Move path handling to nu-path (#3653)

* fixes #3616
This commit is contained in:
Niklas Jonsson
2021-06-20 01:07:26 +02:00
committed by GitHub
parent b9f1371994
commit a8f6a13239
24 changed files with 645 additions and 465 deletions

View File

@ -15,6 +15,7 @@ nu-data = { version = "0.32.1", path = "../nu-data" }
nu-engine = { version = "0.32.1", path = "../nu-engine" }
nu-errors = { version = "0.32.1", path = "../nu-errors" }
nu-json = { version = "0.32.1", path = "../nu-json" }
nu-path = { version = "0.32.1", path = "../nu-path" }
nu-parser = { version = "0.32.1", path = "../nu-parser" }
nu-plugin = { version = "0.32.1", path = "../nu-plugin" }
nu-protocol = { version = "0.32.1", path = "../nu-protocol" }
@ -81,7 +82,6 @@ serde_json = "1.0.61"
serde_urlencoded = "0.7.0"
serde_yaml = "0.8.16"
sha2 = "0.9.3"
shellexpand = "2.1.0"
strip-ansi-escapes = "0.1.0"
sxd-document = "0.3.2"
sxd-xpath = "0.4.2"

View File

@ -5,7 +5,6 @@ use nu_test_support::NATIVE_PATH_ENV_VAR;
use parking_lot::Mutex;
use std::io::Write;
use std::ops::Deref;
use std::process::{Command, Stdio};
use std::sync::mpsc;
use std::{borrow::Cow, io::BufReader};
@ -105,7 +104,7 @@ fn run_with_stdin(
let process_args = command_args
.iter()
.map(|(arg, _is_literal)| {
let arg = expand_tilde(arg.deref(), dirs_next::home_dir);
let arg = nu_path::expand_tilde_string(Cow::Borrowed(arg));
#[cfg(not(windows))]
{
@ -126,7 +125,7 @@ fn run_with_stdin(
if let Some(unquoted) = remove_quotes(&arg) {
unquoted.to_string()
} else {
arg.as_ref().to_string()
arg.to_string()
}
}
})
@ -486,15 +485,6 @@ impl Iterator for ChannelReceiver {
}
}
fn expand_tilde<SI: ?Sized, P, HD>(input: &SI, home_dir: HD) -> std::borrow::Cow<str>
where
SI: AsRef<str>,
P: AsRef<std::path::Path>,
HD: FnOnce() -> Option<P>,
{
shellexpand::tilde_with_context(input, home_dir)
}
fn argument_is_quoted(argument: &str) -> bool {
if argument.len() < 2 {
return false;
@ -543,9 +533,7 @@ fn shell_os_paths() -> Vec<std::path::PathBuf> {
#[cfg(test)]
mod tests {
use super::{
add_double_quotes, argument_is_quoted, escape_double_quotes, expand_tilde, remove_quotes,
};
use super::{add_double_quotes, argument_is_quoted, escape_double_quotes, remove_quotes};
#[cfg(feature = "which")]
use super::{run_external_command, InputStream};
@ -667,20 +655,4 @@ mod tests {
assert_eq!(remove_quotes("'andrés'"), Some("andrés"));
assert_eq!(remove_quotes(r#""andrés""#), Some("andrés"));
}
#[test]
fn expands_tilde_if_starts_with_tilde_character() {
assert_eq!(
expand_tilde("~", || Some(std::path::Path::new("the_path_to_nu_light"))),
"the_path_to_nu_light"
);
}
#[test]
fn does_not_expand_tilde_if_tilde_is_not_first_character() {
assert_eq!(
expand_tilde("1~1", || Some(std::path::Path::new("the_path_to_nu_light"))),
"1~1"
);
}
}

View File

@ -1,10 +1,10 @@
use std::path::PathBuf;
use crate::prelude::*;
use nu_engine::filesystem::path::canonicalize;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_path::canonicalize;
use nu_protocol::{CommandAction, ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
use nu_source::Tagged;

View File

@ -2,10 +2,12 @@ use crate::prelude::*;
use nu_engine::{script, WholeStreamCommand};
use nu_errors::ShellError;
use nu_parser::expand_path;
use nu_path::expand_path;
use nu_protocol::{Signature, SyntaxShape};
use nu_source::Tagged;
use std::{borrow::Cow, path::Path};
pub struct Source;
#[derive(Deserialize)]
@ -46,7 +48,7 @@ pub fn source(args: CommandArgs) -> Result<ActionStream, ShellError> {
// Note: this is a special case for setting the context from a command
// In this case, if we don't set it now, we'll lose the scope that this
// variable should be set into.
let contents = std::fs::read_to_string(expand_path(&filename.item).into_owned());
let contents = std::fs::read_to_string(&expand_path(Cow::Borrowed(Path::new(&filename.item))));
match contents {
Ok(contents) => {
let result = script::run_script_standalone(contents, true, &ctx, false);

View File

@ -1,12 +1,11 @@
use super::{operate, PathSubcommandArguments};
use crate::prelude::*;
use nu_engine::filesystem::path::expand_tilde;
use nu_engine::filesystem::path::resolve_dots;
use nu_engine::WholeStreamCommand;
use nu_errors::ShellError;
use nu_path::expand_path;
use nu_protocol::{ColumnPath, Signature, SyntaxShape, UntaggedValue, Value};
use nu_source::Span;
use std::path::Path;
use std::{borrow::Cow, path::Path};
pub struct PathExpand;
@ -102,13 +101,7 @@ fn action(path: &Path, tag: Tag, args: &PathExpandArguments) -> Value {
tag.span,
))
} else {
// "best effort" mode, just expand tilde and resolve single/double dots
let path = match expand_tilde(path) {
Some(expanded) => expanded,
None => path.into(),
};
UntaggedValue::filepath(resolve_dots(&path)).into_value(tag)
UntaggedValue::filepath(expand_path(Cow::Borrowed(path))).into_value(tag)
}
}

View File

@ -43,3 +43,36 @@ fn expands_path_with_double_dot() {
assert_eq!(PathBuf::from(actual.out), expected);
})
}
#[cfg(windows)]
mod windows {
use super::*;
#[test]
fn expands_path_with_tilde_backward_slash() {
Playground::setup("path_expand_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "~\tmp.txt" | path expand
"#
));
assert!(!PathBuf::from(actual.out).starts_with("~"));
})
}
#[test]
fn win_expands_path_with_tilde_forward_slash() {
Playground::setup("path_expand_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "~/tmp.txt" | path expand
"#
));
assert!(!PathBuf::from(actual.out).starts_with("~"));
})
}
}