Unify glob behavior on open, rm, cp-old, mv, umv, cp and du commands (#11621)

# Description
This pr is a follow up to
[#11569](https://github.com/nushell/nushell/pull/11569#issuecomment-1902279587)
> Revert the logic in https://github.com/nushell/nushell/pull/10694 and
apply the logic in this pr to mv, cp, rv will require a larger change, I
need to think how to achieve the bahavior

And sorry @bobhy for reverting some of your changes.

This pr is going to unify glob behavior on the given commands:
* open
* rm
* cp-old
* mv
* umv
* cp
* du

So they have the same behavior to `ls`, which is:
If given parameter is quoted by single quote(`'`) or double quote(`"`),
don't auto-expand the glob pattern. If not quoted, auto-expand the glob
pattern.

Fixes: #9558  Fixes: #10211 Fixes: #9310 Fixes: #10364 

# TODO
But there is one thing remains: if we give a variable to the command, it
will always auto-expand the glob pattern, e.g:
```nushell
let path = "a[123]b"
rm $path
```
I don't think it's expected. But I also think user might want to
auto-expand the glob pattern in variables.

So I'll introduce a new command called `glob escape`, then if user
doesn't want to auto-expand the glob pattern, he can just do this: `rm
($path | glob escape)`

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
Done

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

## NOTE
This pr changes the semantic of `GlobPattern`, before this pr, it will
`expand path` after evaluated, this makes `nu_engine::glob_from` have no
chance to glob things right if a path contains glob pattern.

e.g: [#9310
](https://github.com/nushell/nushell/issues/9310#issuecomment-1886824030)
#10211

I think changing the semantic is fine, because it makes glob works if
path contains something like '*'.

It maybe a breaking change if a custom command's argument are annotated
by `: glob`.
This commit is contained in:
WindSoilder
2024-01-26 21:57:35 +08:00
committed by GitHub
parent e43d893ea3
commit d646903161
28 changed files with 318 additions and 431 deletions

View File

@ -40,7 +40,6 @@ pub enum Expr {
Filepath(String, bool),
Directory(String, bool),
GlobPattern(String, bool),
LsGlobPattern(String, bool),
String(String),
CellPath(CellPath),
FullCellPath(Box<FullCellPath>),

View File

@ -209,7 +209,6 @@ impl Expression {
Expr::Garbage => false,
Expr::Nothing => false,
Expr::GlobPattern(_, _) => false,
Expr::LsGlobPattern(_, _) => false,
Expr::Int(_) => false,
Expr::Keyword(_, _, expr) => expr.has_in_variable(working_set),
Expr::List(list) => {
@ -389,7 +388,6 @@ impl Expression {
Expr::Garbage => {}
Expr::Nothing => {}
Expr::GlobPattern(_, _) => {}
Expr::LsGlobPattern(_, _) => {}
Expr::MatchBlock(_) => {}
Expr::Int(_) => {}
Expr::Keyword(_, _, expr) => expr.replace_span(working_set, replaced, new_span),

View File

@ -286,9 +286,8 @@ pub trait Eval {
}
Expr::Overlay(_) => Self::eval_overlay(state, expr.span),
Expr::GlobPattern(pattern, quoted) => {
Self::eval_glob_pattern(state, mut_state, pattern.clone(), *quoted, expr.span)
}
Expr::LsGlobPattern(pattern, quoted) => {
// GlobPattern is similar to Filepath
// But we don't want to expand path during eval time, it's required for `nu_engine::glob_from` to run correctly
if *quoted {
Ok(Value::quoted_string(pattern, expr.span))
} else {
@ -381,14 +380,6 @@ pub trait Eval {
fn eval_overlay(state: Self::State<'_>, span: Span) -> Result<Value, ShellError>;
fn eval_glob_pattern(
state: Self::State<'_>,
mut_state: &mut Self::MutState,
pattern: String,
quoted: bool,
span: Span,
) -> Result<Value, ShellError>;
/// For expressions that should never actually be evaluated
fn unreachable(expr: &Expression) -> Result<Value, ShellError>;
}

View File

@ -388,16 +388,6 @@ impl Eval for EvalConst {
Err(ShellError::NotAConstant { span })
}
fn eval_glob_pattern(
_: &StateWorkingSet,
_: &mut (),
_: String,
_: bool,
span: Span,
) -> Result<Value, ShellError> {
Err(ShellError::NotAConstant { span })
}
fn unreachable(expr: &Expression) -> Result<Value, ShellError> {
Err(ShellError::NotAConstant { span: expr.span })
}

View File

@ -1264,23 +1264,6 @@ This is an internal Nushell error, please file an issue https://github.com/nushe
span: Span,
},
/// Error expanding glob pattern
///
/// ## Resolution
///
/// Correct glob pattern or file access issue
#[error("Error expanding glob pattern")]
#[diagnostic(
code(nu::shell::error_expanding_glob),
help("Correct glob pattern or file access issue")
)]
//todo: add error detail
ErrorExpandingGlob {
msg: String,
#[label("{msg}")]
span: Span,
},
/// Tried spreading a non-list inside a list or command call.
///
/// ## Resolution

View File

@ -64,9 +64,6 @@ pub enum SyntaxShape {
/// A glob pattern is allowed, eg `foo*`
GlobPattern,
/// A special glob pattern for ls.
LsGlobPattern,
/// Only an integer value is allowed
Int,
@ -154,7 +151,6 @@ impl SyntaxShape {
SyntaxShape::Filesize => Type::Filesize,
SyntaxShape::FullCellPath => Type::Any,
SyntaxShape::GlobPattern => Type::String,
SyntaxShape::LsGlobPattern => Type::String,
SyntaxShape::Error => Type::Error,
SyntaxShape::ImportPattern => Type::Any,
SyntaxShape::Int => Type::Int,
@ -205,7 +201,6 @@ impl Display for SyntaxShape {
SyntaxShape::Filepath => write!(f, "path"),
SyntaxShape::Directory => write!(f, "directory"),
SyntaxShape::GlobPattern => write!(f, "glob"),
SyntaxShape::LsGlobPattern => write!(f, "glob"),
SyntaxShape::ImportPattern => write!(f, "import"),
SyntaxShape::Block => write!(f, "block"),
SyntaxShape::Closure(args) => {

View File

@ -1,8 +1,11 @@
use serde::Deserialize;
use std::fmt::Display;
/// A simple wrapper to String.
///
/// But it tracks if the string is originally quoted.
/// So commands can make decision on path auto-expanding behavior.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Deserialize)]
pub enum NuPath {
/// A quoted path(except backtick), in this case, nushell shouldn't auto-expand path.
Quoted(String),
@ -10,6 +13,15 @@ pub enum NuPath {
UnQuoted(String),
}
impl NuPath {
pub fn strip_ansi_string_unlikely(self) -> Self {
match self {
NuPath::Quoted(s) => NuPath::Quoted(nu_utils::strip_ansi_string_unlikely(s)),
NuPath::UnQuoted(s) => NuPath::UnQuoted(nu_utils::strip_ansi_string_unlikely(s)),
}
}
}
impl AsRef<str> for NuPath {
fn as_ref(&self) -> &str {
match self {
@ -17,3 +29,9 @@ impl AsRef<str> for NuPath {
}
}
}
impl Display for NuPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_ref())
}
}