Make error-message more helpful when user invokes a non-executable file (#13589)

# Description

Fixes Issue #13477 
This adds a check to see if a user is trying to invoke a
(non-executable) file as a command and returns a helpful error if so.
EDIT: this will not work on Windows, and is arguably not relevant there,
because of the different semantics of executables. I think the
equivalent on Windows would be if a user tries to invoke `./foo`, we
should look for `foo.exe` or `foo.bat` in the directory and recommend
that if it exists.

# User-Facing Changes

When a user invokes an unrecognized command that is the path to an
existing file, the error used to say:
`{name} is neither a Nushell built-in or a known external command` 
This PR proposes to change the message to:
`{name} refers to a file that is not executable. Did you forget to to
set execute permissions?`

# Tests + Formatting
Ran cargo fmt, clippy and test on the workspace. 
EDIT: added test asserting the new behavior
This commit is contained in:
playdohface 2024-08-12 14:21:08 +02:00 committed by GitHub
parent 4e205cd9a7
commit 059167ac96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 0 deletions

View file

@ -473,6 +473,15 @@ pub fn command_not_found(
};
}
// If we find a file, it's likely that the user forgot to set permissions
if Path::new(name).is_file() {
return ShellError::ExternalCommand {
label: format!("Command `{name}` not found"),
help: format!("`{name}` refers to a file that is not executable. Did you forget to to set execute permissions?"),
span,
};
}
// We found nothing useful. Give up and return a generic error message.
ShellError::ExternalCommand {
label: format!("Command `{name}` not found"),

View file

@ -127,6 +127,15 @@ fn command_not_found_error_suggests_typo_fix() {
assert!(actual.err.contains("timeit"));
}
#[cfg(not(windows))]
#[test]
fn command_not_found_error_recognizes_non_executable_file() {
let actual = nu!("./Cargo.toml");
assert!(actual.err.contains(
"refers to a file that is not executable. Did you forget to to set execute permissions?"
));
}
#[test]
fn command_not_found_error_shows_not_found_1() {
let actual = nu!(r#"