-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix run_external::expand_glob()
to return paths that are PWD-relative but reflect the original intent
#13028
Conversation
Oops, this isn't quite finished. |
… like other shells
Ok yeah I realized that this didn't handle "." and "./foo" properly before, and decided to do two things about it:
|
if remainder.components().next().is_none() { | ||
Path::new(".") | ||
// If the first component of the original `arg` string path was '.', that should be preserved | ||
let relative_to_dot = Path::new(arg).starts_with("."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to handle these relative logic by yourself. I think the logic before rewrite is good to use. It uses diff_paths to handle the difference between cwd
and prefix
nushell/crates/nu-command/src/system/run_external.rs
Lines 623 to 640 in c61075e
if let Ok(arg) = m { | |
let arg = if let Some(prefix) = &prefix { | |
if let Ok(remainder) = arg.strip_prefix(prefix) { | |
let new_prefix = if let Some(pfx) = diff_paths(prefix, &cwd) { | |
pfx | |
} else { | |
prefix.to_path_buf() | |
}; | |
new_prefix.join(remainder).to_string_lossy().to_string() | |
} else { | |
arg.to_string_lossy().to_string() | |
} | |
} else { | |
arg.to_string_lossy().to_string() | |
}; | |
process.arg(&arg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I can test whether it passes my tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't be able to check this until tomorrow, but I'm still interested in trying it
Why are we checking for Ctrl-C in the middle of glob expansion? I'm not familar with how Nushell handles Ctrl-C yet, but it feels weird that we're dealing with Ctrl-C within If I recall correctly, the old implementation didn't do anything special with Ctrl-C other than wrap it in the resulting |
@YizhePKU you have to check Ctrl-C during any potentially long loop, as it's impossible to interrupt otherwise. We may not have been doing it before but it's a good idea. |
) # Description This pr is going to use `pathdiff::diff_path`, so we don't need to handle for relative path by ourselves. This is also the behavior before the rewritten of run_external.rs It's a follow up to #13028 # User-Facing Changes NaN # Tests + Formatting No need to add tests
…he parser (#13089) # Description We've had a lot of different issues and PRs related to arg handling with externals since the rewrite of `run-external` in #12921: - #12950 - #12955 - #13000 - #13001 - #13021 - #13027 - #13028 - #13073 Many of these are caused by the argument handling of external calls and `run-external` being very special and involving the parser handing quoted strings over to `run-external` so that it knows whether to expand tildes and globs and so on. This is really unusual and also makes it harder to use `run-external`, and also harder to understand it (and probably is part of the reason why it was rewritten in the first place). This PR moves a lot more of that work over to the parser, so that by the time `run-external` gets it, it's dealing with much more normal Nushell values. In particular: - Unquoted strings are handled as globs with no expand - The unescaped-but-quoted handling of strings was removed, and the parser constructs normal looking strings instead, removing internal quotes so that `run-external` doesn't have to do it - Bare word interpolation is now supported and expansion is done in this case - Expressions typed as `Glob` containing `Expr::StringInterpolation` now produce `Value::Glob` instead, with the quoted status from the expr passed through so we know if it was a bare word - Bare word interpolation for values typed as `glob` now possible, but not implemented - Because expansion is now triggered by `Value::Glob(_, false)` instead of looking at the expr, externals now support glob types # User-Facing Changes - Bare word interpolation works for external command options, and otherwise embedded in other strings: ```nushell ^echo --foo=(2 + 2) # prints --foo=4 ^echo -foo=$"(2 + 2)" # prints -foo=4 ^echo foo="(2 + 2)" # prints (no interpolation!) foo=(2 + 2) ^echo foo,(2 + 2),bar # prints foo,4,bar ``` - Bare word interpolation expands for external command head/args: ```nushell let name = "exa" ~/.cargo/bin/($name) # this works, and expands the tilde ^$"~/.cargo/bin/($name)" # this doesn't expand the tilde ^echo ~/($name)/* # this glob is expanded ^echo $"~/($name)/*" # this isn't expanded ``` - Ndots are now supported for the head of an external command (`^.../foo` works) - Glob values are now supported for head/args of an external command, and expanded appropriately: ```nushell ^("~/.cargo/bin/exa" | into glob) # the tilde is expanded ^echo ("*.txt" | into glob) # this glob is expanded ``` - `run-external` now works more like any other command, without expecting a special call convention for its args: ```nushell run-external echo "'foo'" # before PR: 'foo' # after PR: foo run-external echo "*.txt" # before PR: (glob is expanded) # after PR: *.txt ``` # Tests + Formatting Lots of tests added and cleaned up. Some tests that weren't active on Windows changed to use `nu --testbin cococo` so that they can work. Added a test for Linux only to make sure tilde expansion of commands works, because changing `HOME` there causes `~` to reliably change. - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` # After Submitting - [ ] release notes: make sure to mention the new syntaxes that are supported
Description
Fix #13021
This changes the
expand_glob()
function to usenu_engine::glob_from()
so that absolute paths are actually preserved, rather than being made relative to the provided parent. This preserves the intent of whoever wrote the original path/glob, and also makes it so that tilde always produces absolute paths.I also made
expand_glob()
handle Ctrl-C so that it can be interrupted.cc @YizhePKU
Tests + Formatting
No additional tests here... but that might be a good idea.