mirror of https://github.com/sharkdp/fd.git
Merge branch 'master' into no-buffer-single-thread
This commit is contained in:
commit
fcaebd2295
|
@ -0,0 +1,6 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
|
@ -5,6 +5,9 @@
|
|||
## Bugfixes
|
||||
|
||||
- Set default path separator to `/` in MSYS, see #537 and #730 (@aswild)
|
||||
- fd cannot search files under a RAM disk, see #752
|
||||
- fd doesn't show substituted drive on Windows, see #365
|
||||
- Properly handle write errors to devices that are full, see #737
|
||||
|
||||
## Changes
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -29,9 +31,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.35"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
|
||||
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
|
@ -112,9 +114,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.1.7"
|
||||
version = "3.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b57a92e9749e10f25a171adcebfafe72991d45e7ec2dcb853e8f83d9dafaeb08"
|
||||
checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"winapi",
|
||||
|
@ -166,6 +168,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"libc",
|
||||
"lscolors",
|
||||
"normpath",
|
||||
"num_cpus",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
|
@ -176,13 +179,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.13"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe"
|
||||
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.2.10",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -217,9 +220,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.6"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a"
|
||||
checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
|
@ -290,9 +293,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.80"
|
||||
version = "0.2.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
@ -314,22 +317,31 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.18.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
|
||||
checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "normpath"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27e6e8f70e9fbbe3752d330d769e3424f24b9458ce266df93a3b456902fd696a"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
|
@ -383,6 +395,15 @@ version = "0.1.57"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
|
@ -390,26 +411,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.1.57",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.21"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
|
@ -498,9 +518,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
|||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
|
|
|
@ -39,7 +39,7 @@ atty = "0.2"
|
|||
ignore = "0.4.3"
|
||||
lazy_static = "1.1.0"
|
||||
num_cpus = "1.8"
|
||||
regex = "1.0.0"
|
||||
regex = "1.5.4"
|
||||
regex-syntax = "0.6"
|
||||
ctrlc = "3.1"
|
||||
humantime = "2.0"
|
||||
|
@ -47,6 +47,7 @@ lscolors = "0.7"
|
|||
globset = "0.4"
|
||||
anyhow = "1.0"
|
||||
dirs-next = "2.0"
|
||||
normpath = "0.3"
|
||||
|
||||
[dependencies.clap]
|
||||
version = "2.31.2"
|
||||
|
@ -67,7 +68,7 @@ jemallocator = "0.3.0"
|
|||
[dev-dependencies]
|
||||
diff = "0.1"
|
||||
tempdir = "0.3"
|
||||
filetime = "0.2.1"
|
||||
filetime = "0.2.14"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
@ -646,6 +646,7 @@ cargo install --path .
|
|||
|
||||
- [sharkdp](https://github.com/sharkdp)
|
||||
- [tmccombs](https://github.com/tmccombs)
|
||||
- [tavianator](https://github.com/tavianator)
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -259,12 +259,22 @@ Provide paths to search as an alternative to the positional \fIpath\fR argument.
|
|||
\'fd [FLAGS/OPTIONS] \-\-search\-path PATH \-\-search\-path PATH2 [PATTERN]\'
|
||||
.TP
|
||||
.BI "\-x, \-\-exec " command
|
||||
.RS
|
||||
Execute
|
||||
.I command
|
||||
for each search result in parallel (use --threads=1 for sequential command execution). The following placeholders are substituted by a path derived from the current search result:
|
||||
for each search result in parallel (use --threads=1 for sequential command execution).
|
||||
|
||||
Note that all subsequent positional arguments are considered to be arguments to the
|
||||
.I command
|
||||
- not to fd.
|
||||
It is therefore recommended to place the \-x/\-\-exec option last. Alternatively, you can supply
|
||||
a ';' argument to end the argument list and continue with more fd options.
|
||||
Most shells require ';' to be escaped: '\\;'.
|
||||
|
||||
The following placeholders are substituted before the command is executed:
|
||||
.RS
|
||||
.IP {}
|
||||
path
|
||||
path (of the current search result)
|
||||
.IP {/}
|
||||
basename
|
||||
.IP {//}
|
||||
|
@ -274,15 +284,33 @@ path without file extension
|
|||
.IP {/.}
|
||||
basename without file extension
|
||||
.RE
|
||||
|
||||
If no placeholder is present, an implicit "{}" at the end is assumed.
|
||||
|
||||
Examples:
|
||||
|
||||
- find all *.zip files and unzip them:
|
||||
|
||||
fd -e zip -x unzip
|
||||
|
||||
- find *.h and *.cpp files and run "clang-format -i .." for each of them:
|
||||
|
||||
fd -e h -e cpp -x clang-format -i
|
||||
|
||||
- Convert all *.jpg files to *.png files:
|
||||
|
||||
fd -e jpg -x convert {} {.}.png
|
||||
.RE
|
||||
.TP
|
||||
.BI "\-X, \-\-exec-batch " command
|
||||
.RS
|
||||
Execute
|
||||
.I command
|
||||
with all search results at once.
|
||||
A single occurence of the following placeholders is authorized and substituted by the paths derived from the search results before the command is executed:
|
||||
once, with all search results as arguments.
|
||||
One of the following placeholders is substituted before the command is executed:
|
||||
.RS
|
||||
.IP {}
|
||||
path
|
||||
path (of all search results)
|
||||
.IP {/}
|
||||
basename
|
||||
.IP {//}
|
||||
|
@ -292,6 +320,22 @@ path without file extension
|
|||
.IP {/.}
|
||||
basename without file extension
|
||||
.RE
|
||||
|
||||
If no placeholder is present, an implicit "{}" at the end is assumed.
|
||||
|
||||
Examples:
|
||||
|
||||
- Find all test_*.py files and open them in your favorite editor:
|
||||
|
||||
fd -g 'test_*.py' -X vim
|
||||
|
||||
Note that this executes a single "vim" process with all search results as arguments.
|
||||
|
||||
- Find all *.rs files and count the lines with "wc -l ...":
|
||||
|
||||
fd -e rs -X wc -l
|
||||
.RE
|
||||
|
||||
.SH PATTERN SYNTAX
|
||||
The regular expression syntax used by fd is documented here:
|
||||
|
||||
|
|
40
src/app.rs
40
src/app.rs
|
@ -298,16 +298,24 @@ pub fn build_app() -> App<'static, 'static> {
|
|||
.conflicts_with("list-details")
|
||||
.help("Execute a command for each search result")
|
||||
.long_help(
|
||||
"Execute a command for each search result in parallel (use --threads=1 for sequential command execution).\n\
|
||||
All arguments following --exec are taken to be arguments to the command until the \
|
||||
argument ';' is encountered.\n\
|
||||
Each occurrence of the following placeholders is substituted by a path derived from the \
|
||||
current search result before the command is executed:\n \
|
||||
'{}': path\n \
|
||||
"Execute a command for each search result in parallel (use --threads=1 for sequential command execution). \
|
||||
All positional arguments following --exec are considered to be arguments to the command - not to fd. \
|
||||
It is therefore recommended to place the '-x'/'--exec' option last.\n\
|
||||
The following placeholders are substituted before the command is executed:\n \
|
||||
'{}': path (of the current search result)\n \
|
||||
'{/}': basename\n \
|
||||
'{//}': parent directory\n \
|
||||
'{.}': path without file extension\n \
|
||||
'{/.}': basename without file extension",
|
||||
'{/.}': basename without file extension\n\n\
|
||||
If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\
|
||||
Examples:\n\n \
|
||||
- find all *.zip files and unzip them:\n\n \
|
||||
fd -e zip -x unzip\n\n \
|
||||
- find *.h and *.cpp files and run \"clang-format -i ..\" for each of them:\n\n \
|
||||
fd -e h -e cpp -x clang-format -i\n\n \
|
||||
- Convert all *.jpg files to *.png files:\n\n \
|
||||
fd -e jpg -x convert {} {.}.png\
|
||||
",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
|
@ -321,16 +329,20 @@ pub fn build_app() -> App<'static, 'static> {
|
|||
.conflicts_with_all(&["exec", "list-details"])
|
||||
.help("Execute a command with all search results at once")
|
||||
.long_help(
|
||||
"Execute a command with all search results at once.\n\
|
||||
All arguments following --exec-batch are taken to be arguments to the command until the \
|
||||
argument ';' is encountered.\n\
|
||||
A single occurrence of the following placeholders is authorized and substituted by the paths derived from the \
|
||||
search results before the command is executed:\n \
|
||||
'{}': path\n \
|
||||
"Execute the given command once, with all search results as arguments.\n\
|
||||
One of the following placeholders is substituted before the command is executed:\n \
|
||||
'{}': path (of all search results)\n \
|
||||
'{/}': basename\n \
|
||||
'{//}': parent directory\n \
|
||||
'{.}': path without file extension\n \
|
||||
'{/.}': basename without file extension",
|
||||
'{/.}': basename without file extension\n\n\
|
||||
If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\
|
||||
Examples:\n\n \
|
||||
- Find all test_*.py files and open them in your favorite editor:\n\n \
|
||||
fd -g 'test_*.py' -X vim\n\n \
|
||||
- Find all *.rs files and count the lines with \"wc -l ...\":\n\n \
|
||||
fd -e rs -X wc -l\
|
||||
"
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
|
|
|
@ -7,6 +7,8 @@ use std::io;
|
|||
use std::os::unix::fs::{FileTypeExt, PermissionsExt};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use normpath::PathExt;
|
||||
|
||||
use crate::walk;
|
||||
|
||||
pub fn path_absolute_form(path: &Path) -> io::Result<PathBuf> {
|
||||
|
@ -33,10 +35,10 @@ pub fn absolute_path(path: &Path) -> io::Result<PathBuf> {
|
|||
Ok(path_buf)
|
||||
}
|
||||
|
||||
// Path::is_dir() is not guaranteed to be intuitively correct for "." and ".."
|
||||
// See: https://github.com/rust-lang/rust/issues/45302
|
||||
pub fn is_dir(path: &Path) -> bool {
|
||||
path.is_dir() && (path.file_name().is_some() || path.canonicalize().is_ok())
|
||||
pub fn is_existing_directory(path: &Path) -> bool {
|
||||
// Note: we do not use `.exists()` here, as `.` always exists, even if
|
||||
// the CWD has been deleted.
|
||||
path.is_dir() && (path.file_name().is_some() || path.normalize().is_ok())
|
||||
}
|
||||
|
||||
#[cfg(any(unix, target_os = "redox"))]
|
||||
|
|
27
src/main.rs
27
src/main.rs
|
@ -21,6 +21,7 @@ use atty::Stream;
|
|||
use globset::GlobBuilder;
|
||||
use lscolors::LsColors;
|
||||
use regex::bytes::{RegexBuilder, RegexSetBuilder};
|
||||
use normpath::PathExt;
|
||||
|
||||
use crate::error::print_error;
|
||||
use crate::exec::CommandTemplate;
|
||||
|
@ -55,7 +56,7 @@ fn run() -> Result<ExitCode> {
|
|||
// Set the current working directory of the process
|
||||
if let Some(base_directory) = matches.value_of_os("base-directory") {
|
||||
let base_directory = Path::new(base_directory);
|
||||
if !filesystem::is_dir(base_directory) {
|
||||
if !filesystem::is_existing_directory(base_directory) {
|
||||
return Err(anyhow!(
|
||||
"The '--base-directory' path '{}' is not a directory.",
|
||||
base_directory.to_string_lossy()
|
||||
|
@ -70,7 +71,7 @@ fn run() -> Result<ExitCode> {
|
|||
}
|
||||
|
||||
let current_directory = Path::new(".");
|
||||
if !filesystem::is_dir(current_directory) {
|
||||
if !filesystem::is_existing_directory(current_directory) {
|
||||
return Err(anyhow!(
|
||||
"Could not retrieve current directory (has it been deleted?)."
|
||||
));
|
||||
|
@ -95,7 +96,7 @@ fn run() -> Result<ExitCode> {
|
|||
let mut directories = vec![];
|
||||
for path in paths {
|
||||
let path_buffer = PathBuf::from(path);
|
||||
if filesystem::is_dir(&path_buffer) {
|
||||
if filesystem::is_existing_directory(&path_buffer) {
|
||||
directories.push(path_buffer);
|
||||
} else {
|
||||
print_error(format!(
|
||||
|
@ -120,7 +121,7 @@ fn run() -> Result<ExitCode> {
|
|||
.iter()
|
||||
.map(|path_buffer| {
|
||||
path_buffer
|
||||
.canonicalize()
|
||||
.normalize()
|
||||
.and_then(|pb| filesystem::absolute_path(pb.as_path()))
|
||||
.unwrap()
|
||||
})
|
||||
|
@ -130,7 +131,7 @@ fn run() -> Result<ExitCode> {
|
|||
// Detect if the user accidentally supplied a path instead of a search pattern
|
||||
if !matches.is_present("full-path")
|
||||
&& pattern.contains(std::path::MAIN_SEPARATOR)
|
||||
&& filesystem::is_dir(Path::new(pattern))
|
||||
&& Path::new(pattern).is_dir()
|
||||
{
|
||||
return Err(anyhow!(
|
||||
"The search pattern '{pattern}' contains a path-separation character ('{sep}') \
|
||||
|
@ -177,6 +178,22 @@ fn run() -> Result<ExitCode> {
|
|||
.value_of("path-separator")
|
||||
.map_or_else(filesystem::default_path_separator, |s| Some(s.to_owned()));
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let Some(ref sep) = path_separator {
|
||||
if sep.len() > 1 {
|
||||
return Err(anyhow!(
|
||||
"A path separator must be exactly one byte, but \
|
||||
the given separator is {} bytes: '{}'.\n\
|
||||
In some shells on Windows, '/' is automatically \
|
||||
expanded. Try to use '//' instead.",
|
||||
sep.len(),
|
||||
sep
|
||||
));
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
let ls_colors = if colored_output {
|
||||
Some(LsColors::from_env().unwrap_or_else(|| LsColors::from_string(DEFAULT_LS_COLORS)))
|
||||
} else {
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
|||
|
||||
use lscolors::{LsColors, Style};
|
||||
|
||||
use crate::error::print_error;
|
||||
use crate::exit_codes::ExitCode;
|
||||
use crate::filesystem::strip_current_dir;
|
||||
use crate::options::Options;
|
||||
|
@ -33,9 +34,14 @@ pub fn print_entry(
|
|||
print_entry_uncolorized(stdout, path, config)
|
||||
};
|
||||
|
||||
if r.is_err() {
|
||||
// Probably a broken pipe. Exit gracefully.
|
||||
process::exit(ExitCode::GeneralError.into());
|
||||
if let Err(e) = r {
|
||||
if e.kind() == ::std::io::ErrorKind::BrokenPipe {
|
||||
// Exit gracefully in case of a broken pipe (e.g. 'fd ... | head -n 3').
|
||||
process::exit(0);
|
||||
} else {
|
||||
print_error(format!("Could not write to output: {}", e));
|
||||
process::exit(ExitCode::GeneralError.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use normpath::PathExt;
|
||||
use regex::escape;
|
||||
|
||||
use crate::testenv::TestEnv;
|
||||
|
@ -23,11 +24,13 @@ static DEFAULT_FILES: &[&str] = &[
|
|||
"e1 e2",
|
||||
];
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
fn get_absolute_root_path(env: &TestEnv) -> String {
|
||||
let path = env
|
||||
.test_root()
|
||||
.canonicalize()
|
||||
.normalize()
|
||||
.expect("absolute path")
|
||||
.as_path()
|
||||
.to_str()
|
||||
.expect("string")
|
||||
.to_string();
|
||||
|
@ -1090,16 +1093,19 @@ fn test_symlink_as_root() {
|
|||
fn test_symlink_and_absolute_path() {
|
||||
let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES);
|
||||
|
||||
let expected_path = if cfg!(windows) { "symlink" } else { "one/two" };
|
||||
|
||||
te.assert_output_subdirectory(
|
||||
"symlink",
|
||||
&["--absolute-path"],
|
||||
&format!(
|
||||
"{abs_path}/one/two/c.foo
|
||||
{abs_path}/one/two/C.Foo2
|
||||
{abs_path}/one/two/three
|
||||
{abs_path}/one/two/three/d.foo
|
||||
{abs_path}/one/two/three/directory_foo",
|
||||
abs_path = &abs_path
|
||||
"{abs_path}/{expected_path}/c.foo
|
||||
{abs_path}/{expected_path}/C.Foo2
|
||||
{abs_path}/{expected_path}/three
|
||||
{abs_path}/{expected_path}/three/d.foo
|
||||
{abs_path}/{expected_path}/three/directory_foo",
|
||||
abs_path = &abs_path,
|
||||
expected_path = expected_path
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1127,6 +1133,8 @@ fn test_symlink_and_full_path() {
|
|||
let root = te.system_root();
|
||||
let prefix = escape(&root.to_string_lossy());
|
||||
|
||||
let expected_path = if cfg!(windows) { "symlink" } else { "one/two" };
|
||||
|
||||
te.assert_output_subdirectory(
|
||||
"symlink",
|
||||
&[
|
||||
|
@ -1135,10 +1143,11 @@ fn test_symlink_and_full_path() {
|
|||
&format!("^{prefix}.*three", prefix = prefix),
|
||||
],
|
||||
&format!(
|
||||
"{abs_path}/one/two/three
|
||||
{abs_path}/one/two/three/d.foo
|
||||
{abs_path}/one/two/three/directory_foo",
|
||||
abs_path = &abs_path
|
||||
"{abs_path}/{expected_path}/three
|
||||
{abs_path}/{expected_path}/three/d.foo
|
||||
{abs_path}/{expected_path}/three/directory_foo",
|
||||
abs_path = &abs_path,
|
||||
expected_path = expected_path
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1663,7 +1672,7 @@ fn test_base_directory() {
|
|||
let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES);
|
||||
let abs_base_dir = &format!("{abs_path}/one/two", abs_path = &abs_path);
|
||||
te.assert_output(
|
||||
&["--base-directory", &abs_base_dir, "foo", &abs_path],
|
||||
&["--base-directory", abs_base_dir, "foo", &abs_path],
|
||||
&format!(
|
||||
"{abs_path}/a.foo
|
||||
{abs_path}/one/b.foo
|
||||
|
|
Loading…
Reference in New Issue