Add join
function for joining paths (#882)
This commit is contained in:
parent
9dc2385c64
commit
87e395254b
16
README.adoc
16
README.adoc
@ -794,14 +794,22 @@ Starting server with database localhost:6379 on port 1337...
|
|||||||
|
|
||||||
==== Path Manipulation
|
==== Path Manipulation
|
||||||
|
|
||||||
- `file_name(path)` - File name of `path` with any leading directory components removed. `file_name("/foo/bar.txt")` is `bar.txt`.
|
===== Fallible
|
||||||
- `parent_directory(path)` - Parent directory of `path`. `parent_directory("/foo/bar.txt")` is `/foo`.
|
|
||||||
- `file_stem(path)` - File name of `path` without extension. `file_stem("/foo/bar.txt")` is `bar`.
|
|
||||||
- `without_extension(path)` - `path` without extension. `without_extension("/foo/bar.txt")` is `/foo/bar`.
|
|
||||||
- `extension(path)` - Extension of `path`. `extension("/foo/bar.txt")` is `txt`.
|
- `extension(path)` - Extension of `path`. `extension("/foo/bar.txt")` is `txt`.
|
||||||
|
- `file_name(path)` - File name of `path` with any leading directory components removed. `file_name("/foo/bar.txt")` is `bar.txt`.
|
||||||
|
- `file_stem(path)` - File name of `path` without extension. `file_stem("/foo/bar.txt")` is `bar`.
|
||||||
|
- `parent_directory(path)` - Parent directory of `path`. `parent_directory("/foo/bar.txt")` is `/foo`.
|
||||||
|
- `without_extension(path)` - `path` without extension. `without_extension("/foo/bar.txt")` is `/foo/bar`.
|
||||||
|
|
||||||
These functions can fail, for example if a path does not have an extension, which will halt execution.
|
These functions can fail, for example if a path does not have an extension, which will halt execution.
|
||||||
|
|
||||||
|
===== Infallible
|
||||||
|
|
||||||
|
- `join(a, b)` - Join path `a` with path `b`. `join("foo/bar", "baz")` is `foo/bar/baz`.
|
||||||
|
|
||||||
|
These functions always succeed.
|
||||||
|
|
||||||
=== Command Evaluation Using Backticks
|
=== Command Evaluation Using Backticks
|
||||||
|
|
||||||
Backticks can be used to store the result of commands:
|
Backticks can be used to store the result of commands:
|
||||||
|
155
src/function.rs
155
src/function.rs
@ -10,19 +10,20 @@ pub(crate) enum Function {
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub(crate) static ref TABLE: BTreeMap<&'static str, Function> = vec![
|
pub(crate) static ref TABLE: BTreeMap<&'static str, Function> = vec![
|
||||||
("arch", Nullary(arch)),
|
("arch", Nullary(arch)),
|
||||||
("os", Nullary(os)),
|
|
||||||
("os_family", Nullary(os_family)),
|
|
||||||
("justfile_directory", Nullary(justfile_directory)),
|
|
||||||
("justfile", Nullary(justfile)),
|
|
||||||
("invocation_directory", Nullary(invocation_directory)),
|
|
||||||
("env_var", Unary(env_var)),
|
("env_var", Unary(env_var)),
|
||||||
("env_var_or_default", Binary(env_var_or_default)),
|
("env_var_or_default", Binary(env_var_or_default)),
|
||||||
("just_executable", Nullary(just_executable)),
|
("extension", Unary(extension)),
|
||||||
("file_name", Unary(file_name)),
|
("file_name", Unary(file_name)),
|
||||||
("parent_directory", Unary(parent_directory)),
|
|
||||||
("file_stem", Unary(file_stem)),
|
("file_stem", Unary(file_stem)),
|
||||||
|
("invocation_directory", Nullary(invocation_directory)),
|
||||||
|
("join", Binary(join)),
|
||||||
|
("just_executable", Nullary(just_executable)),
|
||||||
|
("justfile", Nullary(justfile)),
|
||||||
|
("justfile_directory", Nullary(justfile_directory)),
|
||||||
|
("os", Nullary(os)),
|
||||||
|
("os_family", Nullary(os_family)),
|
||||||
|
("parent_directory", Unary(parent_directory)),
|
||||||
("without_extension", Unary(without_extension)),
|
("without_extension", Unary(without_extension)),
|
||||||
("extension", Unary(extension))
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
@ -42,55 +43,6 @@ fn arch(_context: &FunctionContext) -> Result<String, String> {
|
|||||||
Ok(target::arch().to_owned())
|
Ok(target::arch().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os(_context: &FunctionContext) -> Result<String, String> {
|
|
||||||
Ok(target::os().to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn os_family(_context: &FunctionContext) -> Result<String, String> {
|
|
||||||
Ok(target::os_family().to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn invocation_directory(context: &FunctionContext) -> Result<String, String> {
|
|
||||||
Platform::convert_native_path(
|
|
||||||
&context.search.working_directory,
|
|
||||||
context.invocation_directory,
|
|
||||||
)
|
|
||||||
.map_err(|e| format!("Error getting shell path: {}", e))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn justfile(context: &FunctionContext) -> Result<String, String> {
|
|
||||||
context
|
|
||||||
.search
|
|
||||||
.justfile
|
|
||||||
.to_str()
|
|
||||||
.map(str::to_owned)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
format!(
|
|
||||||
"Justfile path is not valid unicode: {}",
|
|
||||||
context.search.justfile.to_string_lossy()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn justfile_directory(context: &FunctionContext) -> Result<String, String> {
|
|
||||||
let justfile_directory = context.search.justfile.parent().ok_or_else(|| {
|
|
||||||
format!(
|
|
||||||
"Could not resolve justfile directory. Justfile `{}` had no parent.",
|
|
||||||
context.search.justfile.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
justfile_directory
|
|
||||||
.to_str()
|
|
||||||
.map(str::to_owned)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
format!(
|
|
||||||
"Justfile directory is not valid unicode: {}",
|
|
||||||
justfile_directory.to_string_lossy()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn env_var(context: &FunctionContext, key: &str) -> Result<String, String> {
|
fn env_var(context: &FunctionContext, key: &str) -> Result<String, String> {
|
||||||
use std::env::VarError::*;
|
use std::env::VarError::*;
|
||||||
|
|
||||||
@ -129,6 +81,39 @@ fn env_var_or_default(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 invocation_directory(context: &FunctionContext) -> Result<String, String> {
|
||||||
|
Platform::convert_native_path(
|
||||||
|
&context.search.working_directory,
|
||||||
|
context.invocation_directory,
|
||||||
|
)
|
||||||
|
.map_err(|e| format!("Error getting shell path: {}", e))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join(_context: &FunctionContext, base: &str, with: &str) -> Result<String, String> {
|
||||||
|
Ok(Utf8Path::new(base).join(with).to_string())
|
||||||
|
}
|
||||||
|
|
||||||
fn just_executable(_context: &FunctionContext) -> Result<String, String> {
|
fn just_executable(_context: &FunctionContext) -> Result<String, String> {
|
||||||
let exe_path =
|
let exe_path =
|
||||||
std::env::current_exe().map_err(|e| format!("Error getting current executable: {}", e))?;
|
std::env::current_exe().map_err(|e| format!("Error getting current executable: {}", e))?;
|
||||||
@ -141,11 +126,45 @@ fn just_executable(_context: &FunctionContext) -> Result<String, String> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(_context: &FunctionContext, path: &str) -> Result<String, String> {
|
fn justfile(context: &FunctionContext) -> Result<String, String> {
|
||||||
Utf8Path::new(path)
|
context
|
||||||
.file_name()
|
.search
|
||||||
|
.justfile
|
||||||
|
.to_str()
|
||||||
.map(str::to_owned)
|
.map(str::to_owned)
|
||||||
.ok_or_else(|| format!("Could not extract file name from `{}`", path))
|
.ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Justfile path is not valid unicode: {}",
|
||||||
|
context.search.justfile.to_string_lossy()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn justfile_directory(context: &FunctionContext) -> Result<String, String> {
|
||||||
|
let justfile_directory = context.search.justfile.parent().ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Could not resolve justfile directory. Justfile `{}` had no parent.",
|
||||||
|
context.search.justfile.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
justfile_directory
|
||||||
|
.to_str()
|
||||||
|
.map(str::to_owned)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Justfile directory is not valid unicode: {}",
|
||||||
|
justfile_directory.to_string_lossy()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn os(_context: &FunctionContext) -> Result<String, String> {
|
||||||
|
Ok(target::os().to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn os_family(_context: &FunctionContext) -> Result<String, String> {
|
||||||
|
Ok(target::os_family().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_directory(_context: &FunctionContext, path: &str) -> Result<String, String> {
|
fn parent_directory(_context: &FunctionContext, path: &str) -> Result<String, String> {
|
||||||
@ -155,13 +174,6 @@ fn parent_directory(_context: &FunctionContext, path: &str) -> Result<String, St
|
|||||||
.ok_or_else(|| format!("Could not extract parent directory from `{}`", path))
|
.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> {
|
fn without_extension(_context: &FunctionContext, path: &str) -> Result<String, String> {
|
||||||
let parent = Utf8Path::new(path)
|
let parent = Utf8Path::new(path)
|
||||||
.parent()
|
.parent()
|
||||||
@ -173,10 +185,3 @@ fn without_extension(_context: &FunctionContext, path: &str) -> Result<String, S
|
|||||||
|
|
||||||
Ok(parent.join(file_stem).to_string())
|
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))
|
|
||||||
}
|
|
||||||
|
@ -1179,12 +1179,13 @@ fs := file_stem('/foo/bar/baz.hello')
|
|||||||
fn := file_name('/foo/bar/baz.hello')
|
fn := file_name('/foo/bar/baz.hello')
|
||||||
dir := parent_directory('/foo/bar/baz.hello')
|
dir := parent_directory('/foo/bar/baz.hello')
|
||||||
ext := extension('/foo/bar/baz.hello')
|
ext := extension('/foo/bar/baz.hello')
|
||||||
|
jn := join('a', 'b')
|
||||||
|
|
||||||
foo:
|
foo:
|
||||||
/bin/echo '{{we}}' '{{fs}}' '{{fn}}' '{{dir}}' '{{ext}}'
|
/bin/echo '{{we}}' '{{fs}}' '{{fn}}' '{{dir}}' '{{ext}}' '{{jn}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "/foo/bar/baz baz baz.hello /foo/bar hello\n",
|
stdout: "/foo/bar/baz baz baz.hello /foo/bar hello a/b\n",
|
||||||
stderr: "/bin/echo '/foo/bar/baz' 'baz' 'baz.hello' '/foo/bar' 'hello'\n",
|
stderr: "/bin/echo '/foo/bar/baz' 'baz' 'baz.hello' '/foo/bar' 'hello' 'a/b'\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
|
Loading…
Reference in New Issue
Block a user