Small fixes and refactors to paths & source command (#3998)

* Expand path when converting value -> PathBuf

Also includes Tagged<PathBuf>.

Fixes #3605

* Expand path for PATH env. variable

Fixes #1834

* Remove leftover Cows after nu-path refactor

There were some unnecessary Cow conversions leftover from the old
nu-path implementation.

* Use canonicalize in source command; Improve errors

Previously, `source` used `expand_path()` which does not follow
symlinks.

As a follow up, I improved the source error messages so they now tell
why the source file could not be canonicalized or read into string.
This commit is contained in:
Jakub Žádník
2021-09-12 02:36:14 +03:00
committed by GitHub
parent 0fa0c25fb3
commit cc5c4d38bb
6 changed files with 55 additions and 36 deletions

View File

@ -2,11 +2,11 @@ use crate::prelude::*;
use nu_engine::{script, WholeStreamCommand};
use nu_errors::ShellError;
use nu_path::expand_path;
use nu_path::{canonicalize, canonicalize_with};
use nu_protocol::{Signature, SyntaxShape};
use nu_source::Tagged;
use std::{borrow::Cow, path::Path, path::PathBuf};
use std::path::Path;
pub struct Source;
@ -69,11 +69,15 @@ pub fn source(args: CommandArgs) -> Result<OutputStream, ShellError> {
for lib_path in dir {
match lib_path {
Ok(name) => {
let path = PathBuf::from(name).join(source_file);
let path = canonicalize_with(&source_file, name).map_err(|e| {
ShellError::labeled_error(
format!("Can't load source file. Reason: {}", e.to_string()),
"Can't load this file",
filename.span(),
)
})?;
if let Ok(contents) =
std::fs::read_to_string(&expand_path(Cow::Borrowed(path.as_path())))
{
if let Ok(contents) = std::fs::read_to_string(path) {
let result = script::run_script_standalone(contents, true, ctx, false);
if let Err(err) = result {
@ -89,9 +93,15 @@ pub fn source(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
}
let path = Path::new(source_file);
let path = canonicalize(source_file).map_err(|e| {
ShellError::labeled_error(
format!("Can't load source file. Reason: {}", e.to_string()),
"Can't load this file",
filename.span(),
)
})?;
let contents = std::fs::read_to_string(&expand_path(Cow::Borrowed(path)));
let contents = std::fs::read_to_string(path);
match contents {
Ok(contents) => {
@ -102,10 +112,10 @@ pub fn source(args: CommandArgs) -> Result<OutputStream, ShellError> {
}
Ok(OutputStream::empty())
}
Err(_) => {
Err(e) => {
ctx.error(ShellError::labeled_error(
"Can't load file to source",
"can't load file",
format!("Can't load source file. Reason: {}", e.to_string()),
"Can't load this file",
filename.span(),
));

View File

@ -5,7 +5,7 @@ use nu_errors::ShellError;
use nu_path::{canonicalize, expand_path};
use nu_protocol::{ColumnPath, Signature, SyntaxShape, UntaggedValue, Value};
use nu_source::Span;
use std::{borrow::Cow, path::Path};
use std::path::Path;
pub struct PathExpand;
@ -105,7 +105,7 @@ fn action(path: &Path, tag: Tag, args: &PathExpandArguments) -> Value {
tag.span,
))
} else {
UntaggedValue::filepath(expand_path(Cow::Borrowed(path))).into_value(tag)
UntaggedValue::filepath(expand_path(path)).into_value(tag)
}
}