Add path manipulation functions (#872)

This commit is contained in:
Antonio Gelameris 2021-06-17 09:56:09 +02:00 committed by GitHub
parent 4a82c45dda
commit 162d2df1ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 236 additions and 1 deletions

7
Cargo.lock generated
View file

@ -44,6 +44,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "camino"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4648c6d00a709aa069a236adcaae4f605a6241c72bf5bee79331a4b625921a9"
[[package]]
name = "cc"
version = "1.0.68"
@ -192,6 +198,7 @@ version = "0.9.5"
dependencies = [
"ansi_term 0.12.1",
"atty",
"camino",
"clap",
"ctrlc",
"derivative",

View file

@ -19,6 +19,7 @@ members = [".", "bin/prerelease"]
[dependencies]
ansi_term = "0.12.0"
atty = "0.2.0"
camino = "1.0.4"
clap = "2.33.0"
derivative = "2.0.0"
dotenv = "0.15.0"

View file

@ -19,6 +19,7 @@ pub(crate) use std::{
};
// dependencies
pub(crate) use camino::Utf8Path;
pub(crate) use derivative::Derivative;
pub(crate) use edit_distance::edit_distance;
pub(crate) use libc::EXIT_FAILURE;

View file

@ -1,7 +1,6 @@
use crate::common::*;
use Function::*;
pub(crate) enum Function {
Nullary(fn(&FunctionContext) -> Result<String, String>),
Unary(fn(&FunctionContext, &str) -> Result<String, String>),
@ -19,6 +18,11 @@ lazy_static! {
("env_var", Unary(env_var)),
("env_var_or_default", Binary(env_var_or_default)),
("just_executable", Nullary(just_executable)),
("file_name", Unary(file_name)),
("parent_directory", Unary(parent_directory)),
("file_stem", Unary(file_stem)),
("without_extension", Unary(without_extension)),
("extension", Unary(extension))
]
.into_iter()
.collect();
@ -136,3 +140,43 @@ fn just_executable(_context: &FunctionContext) -> Result<String, String> {
)
})
}
fn file_name(_context: &FunctionContext, path: &str) -> Result<String, String> {
Utf8Path::new(path)
.file_name()
.map(str::to_owned)
.ok_or_else(|| format!("Could not extract file name from `{}`", path))
}
fn parent_directory(_context: &FunctionContext, path: &str) -> Result<String, String> {
Utf8Path::new(path)
.parent()
.map(Utf8Path::to_string)
.ok_or_else(|| format!("Could not extract parent directory from `{}`", path))
}
fn file_stem(_context: &FunctionContext, path: &str) -> Result<String, String> {
Utf8Path::new(path)
.file_stem()
.map(str::to_owned)
.ok_or_else(|| format!("Could not extract file stem from `{}`", path))
}
fn without_extension(_context: &FunctionContext, path: &str) -> Result<String, String> {
let parent = Utf8Path::new(path)
.parent()
.ok_or_else(|| format!("Could not extract parent from `{}`", path))?;
let file_stem = Utf8Path::new(path)
.file_stem()
.ok_or_else(|| format!("Could not extract file stem from `{}`", path))?;
Ok(parent.join(file_stem).to_string())
}
fn extension(_context: &FunctionContext, path: &str) -> Result<String, String> {
Utf8Path::new(path)
.extension()
.map(str::to_owned)
.ok_or_else(|| format!("Could not extract extension from `{}`", path))
}

View file

@ -251,6 +251,25 @@ test! {
",
}
test! {
name: assignment_path_functions,
justfile: "
foo := without_extension('foo/bar.baz')
foo2 := file_stem('foo/bar.baz')
foo3 := parent_directory('foo/bar.baz')
foo4 := file_name('foo/bar.baz')
foo5 := extension('foo/bar.baz')
",
args: ("--dump"),
stdout: "
foo := without_extension('foo/bar.baz')
foo2 := file_stem('foo/bar.baz')
foo3 := parent_directory('foo/bar.baz')
foo4 := file_name('foo/bar.baz')
foo5 := extension('foo/bar.baz')
",
}
test! {
name: recipe_ordinary,
justfile: "

View file

@ -1170,6 +1170,169 @@ foo:
stderr: format!("/bin/echo '{}' 'HTAP' 'ABC'\n", env::var("USER").unwrap()).as_str(),
}
#[cfg(not(windows))]
test! {
name: path_functions,
justfile: r#"
we := without_extension('/foo/bar/baz.hello')
fs := file_stem('/foo/bar/baz.hello')
fn := file_name('/foo/bar/baz.hello')
dir := parent_directory('/foo/bar/baz.hello')
ext := extension('/foo/bar/baz.hello')
foo:
/bin/echo '{{we}}' '{{fs}}' '{{fn}}' '{{dir}}' '{{ext}}'
"#,
stdout: "/foo/bar/baz baz baz.hello /foo/bar hello\n",
stderr: "/bin/echo '/foo/bar/baz' 'baz' 'baz.hello' '/foo/bar' 'hello'\n",
}
#[cfg(not(windows))]
test! {
name: path_functions2,
justfile: r#"
we := without_extension('/foo/bar/baz')
fs := file_stem('/foo/bar/baz.hello.ciao')
fn := file_name('/bar/baz.hello.ciao')
dir := parent_directory('/foo/')
ext := extension('/foo/bar/baz.hello.ciao')
foo:
/bin/echo '{{we}}' '{{fs}}' '{{fn}}' '{{dir}}' '{{ext}}'
"#,
stdout: "/foo/bar/baz baz.hello baz.hello.ciao / ciao\n",
stderr: "/bin/echo '/foo/bar/baz' 'baz.hello' 'baz.hello.ciao' '/' 'ciao'\n",
}
#[cfg(not(windows))]
test! {
name: broken_without_extension_function,
justfile: r#"
we := without_extension('')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{} {}\n{}\n{}\n{}\n",
"error: Call to function `without_extension` failed:",
"Could not extract parent from ``",
" |",
"1 | we := without_extension(\'\')",
" | ^^^^^^^^^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_extension_function,
justfile: r#"
we := extension('')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{}\n{}\n{}\n{}\n",
"error: Call to function `extension` failed: Could not extract extension from ``",
" |",
"1 | we := extension(\'\')",
" | ^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_extension_function2,
justfile: r#"
we := extension('foo')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{}\n{}\n{}\n{}\n",
"error: Call to function `extension` failed: Could not extract extension from `foo`",
" |",
"1 | we := extension(\'foo\')",
" | ^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_file_stem_function,
justfile: r#"
we := file_stem('')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{}\n{}\n{}\n{}\n",
"error: Call to function `file_stem` failed: Could not extract file stem from ``",
" |",
"1 | we := file_stem(\'\')",
" | ^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_file_name_function,
justfile: r#"
we := file_name('')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{}\n{}\n{}\n{}\n",
"error: Call to function `file_name` failed: Could not extract file name from ``",
" |",
"1 | we := file_name(\'\')",
" | ^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_directory_function,
justfile: r#"
we := parent_directory('')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{} {}\n{}\n{}\n{}\n",
"error: Call to function `parent_directory` failed:",
"Could not extract parent directory from ``",
" |",
"1 | we := parent_directory(\'\')",
" | ^^^^^^^^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(not(windows))]
test! {
name: broken_directory_function2,
justfile: r#"
we := parent_directory('/')
foo:
/bin/echo '{{we}}'
"#,
stdout: "",
stderr: format!("{} {}\n{}\n{}\n{}\n",
"error: Call to function `parent_directory` failed:",
"Could not extract parent directory from `/`",
" |",
"1 | we := parent_directory(\'/\')",
" | ^^^^^^^^^^^^^^^^").as_str(),
status: EXIT_FAILURE,
}
#[cfg(windows)]
test! {
name: env_var_functions,