Add function to canonicalize paths (#1859)
This commit is contained in:
parent
22d462bd55
commit
43d88f50e0
@ -1381,7 +1381,10 @@ The process ID is: 420
|
|||||||
##### Fallible
|
##### Fallible
|
||||||
|
|
||||||
- `absolute_path(path)` - Absolute path to relative `path` in the working
|
- `absolute_path(path)` - Absolute path to relative `path` in the working
|
||||||
directory. `absolute_path("./bar.txt")` in directory `/foo` is `/foo/bar.txt`.
|
directory. `absolute_path("./bar.txt")` in directory `/foo` is
|
||||||
|
`/foo/bar.txt`.
|
||||||
|
- `canonicalize(path)` - Canonicalize `path` by resolving symlinks and removing
|
||||||
|
`.`, `..`, and extra `/`s where possible.
|
||||||
- `extension(path)` - Extension of `path`. `extension("/foo/bar.txt")` is
|
- `extension(path)` - Extension of `path`. `extension("/foo/bar.txt")` is
|
||||||
`txt`.
|
`txt`.
|
||||||
- `file_name(path)` - File name of `path` with any leading directory components
|
- `file_name(path)` - File name of `path` with any leading directory components
|
||||||
|
@ -21,6 +21,7 @@ pub(crate) fn get(name: &str) -> Option<Function> {
|
|||||||
let function = match name {
|
let function = match name {
|
||||||
"absolute_path" => Unary(absolute_path),
|
"absolute_path" => Unary(absolute_path),
|
||||||
"arch" => Nullary(arch),
|
"arch" => Nullary(arch),
|
||||||
|
"canonicalize" => Unary(canonicalize),
|
||||||
"cache_directory" => Nullary(|_| dir("cache", dirs::cache_dir)),
|
"cache_directory" => Nullary(|_| dir("cache", dirs::cache_dir)),
|
||||||
"capitalize" => Unary(capitalize),
|
"capitalize" => Unary(capitalize),
|
||||||
"clean" => Unary(clean),
|
"clean" => Unary(clean),
|
||||||
@ -106,6 +107,18 @@ fn arch(_context: &FunctionContext) -> Result<String, String> {
|
|||||||
Ok(target::arch().to_owned())
|
Ok(target::arch().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn canonicalize(_context: &FunctionContext, path: &str) -> Result<String, String> {
|
||||||
|
let canonical =
|
||||||
|
std::fs::canonicalize(path).map_err(|err| format!("I/O error canonicalizing path: {err}"))?;
|
||||||
|
|
||||||
|
canonical.to_str().map(str::to_string).ok_or_else(|| {
|
||||||
|
format!(
|
||||||
|
"Canonical path is not valid unicode: {}",
|
||||||
|
canonical.display(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn capitalize(_context: &FunctionContext, s: &str) -> Result<String, String> {
|
fn capitalize(_context: &FunctionContext, s: &str) -> Result<String, String> {
|
||||||
let mut capitalized = String::new();
|
let mut capitalized = String::new();
|
||||||
for (i, c) in s.chars().enumerate() {
|
for (i, c) in s.chars().enumerate() {
|
||||||
|
@ -662,3 +662,14 @@ fn just_pid() {
|
|||||||
|
|
||||||
assert_eq!(stdout.parse::<u32>().unwrap(), pid);
|
assert_eq!(stdout.parse::<u32>().unwrap(), pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn canonicalize() {
|
||||||
|
Test::new()
|
||||||
|
.args(["--evaluate", "x"])
|
||||||
|
.justfile("x := canonicalize('foo')")
|
||||||
|
.symlink("justfile", "foo")
|
||||||
|
.stdout_regex(".*/justfile")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
@ -113,6 +113,17 @@ impl Test {
|
|||||||
self.tempdir.path().join("justfile")
|
self.tempdir.path().join("justfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[track_caller]
|
||||||
|
pub(crate) fn symlink(self, original: &str, link: &str) -> Self {
|
||||||
|
std::os::unix::fs::symlink(
|
||||||
|
self.tempdir.path().join(original),
|
||||||
|
self.tempdir.path().join(link),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn no_justfile(mut self) -> Self {
|
pub(crate) fn no_justfile(mut self) -> Self {
|
||||||
self.justfile = None;
|
self.justfile = None;
|
||||||
self
|
self
|
||||||
|
Loading…
Reference in New Issue
Block a user