mirror of
https://github.com/casey/just.git
synced 2024-11-22 02:09:44 +03:00
Use internal implementation of which()
This commit is contained in:
parent
f1980b5150
commit
0c6f5e8376
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -498,6 +498,15 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_executable"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4a1b5bad6f9072935961dfbf1cced2f3d129963d091b6f69f007fe04e758ae2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
@ -535,8 +544,10 @@ dependencies = [
|
|||||||
"dirs",
|
"dirs",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"edit-distance",
|
"edit-distance",
|
||||||
|
"either",
|
||||||
"executable-path",
|
"executable-path",
|
||||||
"heck",
|
"heck",
|
||||||
|
"is_executable",
|
||||||
"lexiclean",
|
"lexiclean",
|
||||||
"libc",
|
"libc",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -30,7 +30,9 @@ derivative = "2.0.0"
|
|||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
dotenvy = "0.15"
|
dotenvy = "0.15"
|
||||||
edit-distance = "2.0.0"
|
edit-distance = "2.0.0"
|
||||||
|
either = "1.13.0"
|
||||||
heck = "0.5.0"
|
heck = "0.5.0"
|
||||||
|
is_executable = "1.0.4"
|
||||||
lexiclean = "0.0.1"
|
lexiclean = "0.0.1"
|
||||||
libc = "0.2.0"
|
libc = "0.2.0"
|
||||||
num_cpus = "1.15.0"
|
num_cpus = "1.15.0"
|
||||||
@ -51,7 +53,6 @@ tempfile = "3.0.0"
|
|||||||
typed-arena = "2.0.1"
|
typed-arena = "2.0.1"
|
||||||
unicode-width = "0.2.0"
|
unicode-width = "0.2.0"
|
||||||
uuid = { version = "1.0.0", features = ["v4"] }
|
uuid = { version = "1.0.0", features = ["v4"] }
|
||||||
which = "6.0.0"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
executable-path = "1.0.0"
|
executable-path = "1.0.0"
|
||||||
|
2
justfile
2
justfile
@ -6,6 +6,8 @@ alias t := test
|
|||||||
|
|
||||||
log := "warn"
|
log := "warn"
|
||||||
|
|
||||||
|
bingus := which("bash")
|
||||||
|
|
||||||
export JUST_LOG := log
|
export JUST_LOG := log
|
||||||
|
|
||||||
[group: 'dev']
|
[group: 'dev']
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
|
either::Either,
|
||||||
heck::{
|
heck::{
|
||||||
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase,
|
ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase,
|
||||||
ToUpperCamelCase,
|
ToUpperCamelCase,
|
||||||
@ -110,7 +111,7 @@ pub(crate) fn get(name: &str) -> Option<Function> {
|
|||||||
"uppercase" => Unary(uppercase),
|
"uppercase" => Unary(uppercase),
|
||||||
"uuid" => Nullary(uuid),
|
"uuid" => Nullary(uuid),
|
||||||
"without_extension" => Unary(without_extension),
|
"without_extension" => Unary(without_extension),
|
||||||
"which" => Unary(which_exec),
|
"which" => Unary(which),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(function)
|
Some(function)
|
||||||
@ -668,14 +669,59 @@ fn uuid(_context: Context) -> FunctionResult {
|
|||||||
Ok(uuid::Uuid::new_v4().to_string())
|
Ok(uuid::Uuid::new_v4().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn which_exec(_context: Context, s: &str) -> FunctionResult {
|
fn which(context: Context, s: &str) -> FunctionResult {
|
||||||
let path = which::which(s).unwrap_or_default();
|
use is_executable::IsExecutable;
|
||||||
path.to_str().map(str::to_string).ok_or_else(|| {
|
|
||||||
format!(
|
let cmd = PathBuf::from(s);
|
||||||
"unable to convert which executable path to string: {}",
|
|
||||||
path.display()
|
let path_var;
|
||||||
)
|
let candidates = match cmd.components().count() {
|
||||||
})
|
0 => Err("empty command string".to_string())?,
|
||||||
|
1 => {
|
||||||
|
// cmd is a regular command
|
||||||
|
path_var = env::var_os("PATH").ok_or("Environment variable `PATH` is not set")?;
|
||||||
|
Either::Left(env::split_paths(&path_var).map(|path| path.join(cmd.clone())))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// cmd contains a path separator, treat it as a path
|
||||||
|
Either::Right(iter::once(cmd))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for mut candidate in candidates.into_iter() {
|
||||||
|
if candidate.is_relative() {
|
||||||
|
// This candidate is a relative path, either because the user invoked `which("./rel/path")`,
|
||||||
|
// or because there was a relative path in `PATH`. Resolve it to an absolute path.
|
||||||
|
let cwd = context
|
||||||
|
.evaluator
|
||||||
|
.context
|
||||||
|
.search
|
||||||
|
.justfile
|
||||||
|
.parent()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Could not resolve absolute path from `{}` relative to the justfile directory. Justfile `{}` had no parent.",
|
||||||
|
candidate.display(),
|
||||||
|
context.evaluator.context.search.justfile.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let mut cwd = PathBuf::from(cwd);
|
||||||
|
cwd.push(candidate);
|
||||||
|
candidate = cwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if candidate.is_executable() {
|
||||||
|
return candidate.to_str().map(str::to_string).ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Executable path is not valid unicode: {}",
|
||||||
|
candidate.display()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No viable candidates; return an empty string
|
||||||
|
Ok(String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn without_extension(_context: Context, path: &str) -> FunctionResult {
|
fn without_extension(_context: Context, path: &str) -> FunctionResult {
|
||||||
|
Loading…
Reference in New Issue
Block a user