add -n for path expand, so it doesn't follow symlink (#6255)

* add -p for path expand, so it doesn't follow symlink

* fix arg name

* rename from no-dereferenct to no-follow-link

* rename from no-follow-link to no-symlink, and change short -p to -n

* follow strict first

* fix

* simplify test

* fix clippy

* fix test on windows
This commit is contained in:
WindSoilder
2022-08-10 21:43:56 +08:00
committed by GitHub
parent 2e5d981a09
commit 0f10d984c3
4 changed files with 90 additions and 20 deletions

View File

@ -57,9 +57,9 @@ impl Command for Cp {
// .switch("force", "suppress error when no file", Some('f'))
.switch("interactive", "ask user to confirm action", Some('i'))
.switch(
"no-dereference",
"If the -r option is specified, no symbolic links are followed.",
Some('p'),
"no-symlink",
"no symbolic links are followed, only works if -r is active",
Some('n'),
)
.category(Category::FileSystem)
}
@ -218,7 +218,7 @@ impl Command for Cp {
)
})?;
let not_follow_symlink = call.has_flag("no-dereference");
let not_follow_symlink = call.has_flag("no-symlink");
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
let mut dest = destination.clone();

View File

@ -11,6 +11,7 @@ struct Arguments {
strict: bool,
columns: Option<Vec<String>>,
cwd: String,
not_follow_symlink: bool,
}
impl PathSubcommandArguments for Arguments {
@ -34,6 +35,7 @@ impl Command for SubCommand {
"Throw an error if the path could not be expanded",
Some('s'),
)
.switch("no-symlink", "Do not resolve symbolic links", Some('n'))
.named(
"columns",
SyntaxShape::Table,
@ -58,6 +60,7 @@ impl Command for SubCommand {
strict: call.has_flag("strict"),
columns: call.get_flag(engine_state, stack, "columns")?,
cwd: current_dir_str(engine_state, stack)?,
not_follow_symlink: call.has_flag("no-symlink"),
};
input.map(
@ -84,6 +87,11 @@ impl Command for SubCommand {
example: r"'foo\..\bar' | path expand",
result: None,
},
Example {
description: "Expand an absolute path without following symlink",
example: r"'foo\..\bar' | path expand -n",
result: None,
},
]
}
@ -110,22 +118,35 @@ impl Command for SubCommand {
}
fn expand(path: &Path, span: Span, args: &Arguments) -> Value {
if let Ok(p) = canonicalize_with(path, &args.cwd) {
Value::string(p.to_string_lossy(), span)
} else if args.strict {
Value::Error {
error: ShellError::GenericError(
"Could not expand path".into(),
"could not be expanded (path might not exist, non-final \
component is not a directory, or other cause)"
.into(),
Some(span),
None,
Vec::new(),
),
if args.strict {
match canonicalize_with(path, &args.cwd) {
Ok(p) => {
if args.not_follow_symlink {
Value::string(expand_path_with(path, &args.cwd).to_string_lossy(), span)
} else {
Value::string(p.to_string_lossy(), span)
}
}
Err(_) => Value::Error {
error: ShellError::GenericError(
"Could not expand path".into(),
"could not be expanded (path might not exist, non-final \
component is not a directory, or other cause)"
.into(),
Some(span),
None,
Vec::new(),
),
},
}
} else {
} else if args.not_follow_symlink {
Value::string(expand_path_with(path, &args.cwd).to_string_lossy(), span)
} else {
canonicalize_with(path, &args.cwd)
.map(|p| Value::string(p.to_string_lossy(), span))
.unwrap_or_else(|_| {
Value::string(expand_path_with(path, &args.cwd).to_string_lossy(), span)
})
}
}