forked from extern/nushell
Simplify is_executable
in nu-completion
. (#3742)
On Windows, we used the `is-exeuctable` crate but on Unix, we duplicated the check that it did, with one difference: We also looked at whether or not it was a symlink. The `is-executable` crate uses `std::fs::metadata` which follows symlinks, so this scenario should never occur here, as it will return the metadata for the target file. Using the `is-executable` crate on both Unix and Windows lets us make it non-optional. This lets us remove the `executable-support` feature. (It is worth noting that this code didn't compile on Windows when the `executable-support` feature was not specified.) Right now, there is an alternate code path for `target_arch` being `wasm32`. This isn't exactly correct as it should probably handle something different for when the `target_os` is `wasi`.
This commit is contained in:
parent
08c624576c
commit
1943071d12
@ -71,7 +71,6 @@ rustyline-support = ["nu-cli/rustyline-support", "nu-command/rustyline-support"]
|
||||
term-support = ["nu-command/term"]
|
||||
uuid-support = ["nu-command/uuid_crate"]
|
||||
which-support = ["nu-command/which", "nu-engine/which"]
|
||||
executable-support = ["nu-completion/is_executable"]
|
||||
|
||||
default = [
|
||||
"nu-cli/shadow-rs",
|
||||
@ -85,7 +84,6 @@ default = [
|
||||
"post",
|
||||
"fetch",
|
||||
"zip-support",
|
||||
"executable-support",
|
||||
"dataframe",
|
||||
]
|
||||
|
||||
|
@ -21,7 +21,9 @@ nu-test-support = { version="0.33.1", path="../nu-test-support" }
|
||||
|
||||
dirs-next = "2.0.0"
|
||||
indexmap = { version="1.6.1", features=["serde-1"] }
|
||||
is_executable = { version="1.0.1", optional=true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
is_executable = "1.0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
parking_lot = "0.11.1"
|
||||
|
@ -1,8 +1,7 @@
|
||||
use super::matchers::Matcher;
|
||||
use crate::{Completer, CompletionContext, Suggestion};
|
||||
use indexmap::set::IndexSet;
|
||||
#[cfg(feature = "is_executable")]
|
||||
#[allow(unused)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use is_executable::IsExecutable;
|
||||
use nu_test_support::NATIVE_PATH_ENV_VAR;
|
||||
use std::iter::FromIterator;
|
||||
@ -56,11 +55,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn is_executable(path: &Path) -> bool {
|
||||
// This call to a crate essentially checks the PATHEXT on Windows and does some
|
||||
// low level WinAPI calls to determine if the file is executable. It seems quite
|
||||
// a bit faster than calling path.metadata().
|
||||
// On Unix, this checks the file metadata. The underlying code traverses symlinks.
|
||||
path.is_executable()
|
||||
}
|
||||
|
||||
@ -69,22 +69,6 @@ fn is_executable(_path: &Path) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn is_executable(path: &Path) -> bool {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
if let Ok(metadata) = path.metadata() {
|
||||
let filetype = metadata.file_type();
|
||||
let permissions = metadata.permissions();
|
||||
|
||||
// The file is executable if it is a directory or a symlink and the permissions are set for
|
||||
// owner, group, or other
|
||||
(filetype.is_file() || filetype.is_symlink()) && (permissions.mode() & 0o111 != 0)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO cache these, but watch for changes to PATH
|
||||
fn find_path_executables() -> Option<IndexSet<String>> {
|
||||
let path_var = std::env::var_os(NATIVE_PATH_ENV_VAR)?;
|
||||
|
Loading…
Reference in New Issue
Block a user