mirror of
https://github.com/sharkdp/fd
synced 2024-09-05 08:13:19 +00:00
Fix merge conflicts
This commit is contained in:
commit
2a23905af5
|
@ -142,6 +142,11 @@ cd fd-rs
|
|||
makepkg -si
|
||||
```
|
||||
|
||||
On **NixOS**, or any Linux distro you can use [Nix](https://nixos.org/nix/):
|
||||
```
|
||||
nix-env -i fd
|
||||
```
|
||||
|
||||
On **Windows**, you can download the pre-built binaries from the [Release page](https://github.com/sharkdp/fd/releases).
|
||||
|
||||
## Development
|
||||
|
|
41
appveyor.yml
41
appveyor.yml
|
@ -13,24 +13,24 @@ environment:
|
|||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: stable
|
||||
# Beta channel
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: beta
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
CHANNEL: beta
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
CHANNEL: beta
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: beta
|
||||
# Nightly channel
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
# Beta channel (disabled for speed reasons)
|
||||
#- TARGET: i686-pc-windows-gnu
|
||||
# CHANNEL: beta
|
||||
#- TARGET: i686-pc-windows-msvc
|
||||
# CHANNEL: beta
|
||||
#- TARGET: x86_64-pc-windows-gnu
|
||||
# CHANNEL: beta
|
||||
#- TARGET: x86_64-pc-windows-msvc
|
||||
# CHANNEL: beta
|
||||
# Nightly channel (disabled for speed reasons)
|
||||
#- TARGET: i686-pc-windows-gnu
|
||||
# CHANNEL: nightly
|
||||
#- TARGET: i686-pc-windows-msvc
|
||||
# CHANNEL: nightly
|
||||
#- TARGET: x86_64-pc-windows-gnu
|
||||
# CHANNEL: nightly
|
||||
#- TARGET: x86_64-pc-windows-msvc
|
||||
# CHANNEL: nightly
|
||||
|
||||
# Install Rust and Cargo
|
||||
# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
|
||||
|
@ -87,3 +87,8 @@ branches:
|
|||
# IMPORTANT Regex to match tags. Required, or appveyor may not trigger deploys when a new tag
|
||||
# is pushed. This regex matches semantic versions like v1.2.3-rc4+2016.02.22
|
||||
- /^v\d+\.\d+\.\d+.*$/
|
||||
|
||||
# Disable caching, for now
|
||||
#cache:
|
||||
# - '%USERPROFILE%\.cargo'
|
||||
# - 'target -> Cargo.lock'
|
||||
|
|
|
@ -84,10 +84,13 @@ impl<'a> CommandTicket<'a> {
|
|||
let cmd = Command::new(COMMAND.0.as_str())
|
||||
.arg(COMMAND.1)
|
||||
.arg(&self.command)
|
||||
// Configure the pipes accordingly in the child.
|
||||
.before_exec(move || unsafe {
|
||||
// Configure the pipes accordingly in the child.
|
||||
// Redirect the child's std{out,err} to the write ends of our pipe.
|
||||
dup2(stdout_fds[1], STDOUT_FILENO);
|
||||
dup2(stderr_fds[1], STDERR_FILENO);
|
||||
|
||||
// Close all the fds we created here, so EOF will be sent when the program exits.
|
||||
close(stdout_fds[0]);
|
||||
close(stdout_fds[1]);
|
||||
close(stderr_fds[0]);
|
||||
|
@ -98,9 +101,11 @@ impl<'a> CommandTicket<'a> {
|
|||
|
||||
// Open the read end of the pipes as `File`s.
|
||||
let (mut pout, mut perr) = unsafe {
|
||||
// Close the write ends of the pipes in the parent
|
||||
close(stdout_fds[1]);
|
||||
close(stderr_fds[1]);
|
||||
(
|
||||
// But create files from the read ends.
|
||||
File::from_raw_fd(stdout_fds[0]),
|
||||
File::from_raw_fd(stderr_fds[0]),
|
||||
)
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
|
|||
if path.is_absolute() {
|
||||
Some(PathBuf::from(path))
|
||||
} else {
|
||||
None
|
||||
Some(PathBuf::from(base.join(path)))
|
||||
}
|
||||
} else {
|
||||
let mut ita = path.components();
|
||||
|
|
58
src/main.rs
58
src/main.rs
|
@ -21,7 +21,7 @@ mod walk;
|
|||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time;
|
||||
|
||||
|
@ -41,33 +41,33 @@ fn main() {
|
|||
let pattern = matches.value_of("pattern").unwrap_or(&empty_pattern);
|
||||
|
||||
// Get the current working directory
|
||||
let current_dir_buf = match env::current_dir() {
|
||||
Ok(cd) => cd,
|
||||
Err(_) => error("Error: could not get current directory."),
|
||||
};
|
||||
let current_dir = current_dir_buf.as_path();
|
||||
let current_dir = Path::new(".");
|
||||
// .is_dir() is not guarandteed to be intuitively correct for "." and ".."
|
||||
if let Err(_) = current_dir.canonicalize() {
|
||||
error("Error: could not get current directory.");
|
||||
}
|
||||
|
||||
// Get the root directory for the search
|
||||
let mut root_dir_is_absolute = false;
|
||||
let root_dir_buf = if let Some(rd) = matches.value_of("path") {
|
||||
let path = Path::new(rd);
|
||||
|
||||
root_dir_is_absolute = path.is_absolute();
|
||||
|
||||
fshelper::absolute_path(path).unwrap_or_else(|_| {
|
||||
error(&format!("Error: could not find directory '{}'.", rd))
|
||||
})
|
||||
} else {
|
||||
current_dir_buf.clone()
|
||||
let mut root_dir_buf = match matches.value_of("path") {
|
||||
Some(path) => PathBuf::from(path),
|
||||
None => current_dir.to_path_buf(),
|
||||
};
|
||||
|
||||
if !root_dir_buf.is_dir() {
|
||||
if let Err(_) = root_dir_buf.canonicalize() {
|
||||
error(&format!(
|
||||
"Error: '{}' is not a directory.",
|
||||
root_dir_buf.to_string_lossy()
|
||||
));
|
||||
}
|
||||
|
||||
let path_display = if matches.is_present("absolute-path") || root_dir_buf.is_absolute() {
|
||||
PathDisplay::Absolute
|
||||
} else {
|
||||
PathDisplay::Relative
|
||||
};
|
||||
|
||||
if path_display == PathDisplay::Absolute && root_dir_buf.is_relative() {
|
||||
root_dir_buf = fshelper::absolute_path(root_dir_buf.as_path()).unwrap();
|
||||
}
|
||||
let root_dir = root_dir_buf.as_path();
|
||||
|
||||
// The search will be case-sensitive if the command line flag is set or
|
||||
|
@ -117,11 +117,7 @@ fn main() {
|
|||
.value_of("max-buffer-time")
|
||||
.and_then(|n| u64::from_str_radix(n, 10).ok())
|
||||
.map(time::Duration::from_millis),
|
||||
path_display: if matches.is_present("absolute-path") || root_dir_is_absolute {
|
||||
PathDisplay::Absolute
|
||||
} else {
|
||||
PathDisplay::Relative
|
||||
},
|
||||
path_display,
|
||||
ls_colors,
|
||||
file_type: match matches.value_of("file-type") {
|
||||
Some("f") | Some("file") => FileType::RegularFile,
|
||||
|
@ -136,17 +132,21 @@ fn main() {
|
|||
command,
|
||||
};
|
||||
|
||||
let root = Path::new(ROOT_DIR);
|
||||
let base = match config.path_display {
|
||||
PathDisplay::Relative => current_dir,
|
||||
PathDisplay::Absolute => root,
|
||||
// If base_dir is ROOT_DIR, then root_dir must be absolute.
|
||||
// Otherwise root_dir/entry cannot be turned into an existing relative path from base_dir.
|
||||
//
|
||||
// We utilize ROOT_DIR to avoid resolving the components of root_dir.
|
||||
let base_dir_buf = match config.path_display {
|
||||
PathDisplay::Relative => current_dir.to_path_buf(),
|
||||
PathDisplay::Absolute => PathBuf::from(ROOT_DIR),
|
||||
};
|
||||
let base_dir = base_dir_buf.as_path();
|
||||
|
||||
match RegexBuilder::new(pattern)
|
||||
.case_insensitive(!config.case_sensitive)
|
||||
.dot_matches_new_line(true)
|
||||
.build() {
|
||||
Ok(re) => walk::scan(root_dir, Arc::new(re), base, Arc::new(config)),
|
||||
Ok(re) => walk::scan(root_dir, Arc::new(re), base_dir, Arc::new(config)),
|
||||
Err(err) => error(err.description()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@ use std::os::unix::fs::PermissionsExt;
|
|||
use ansi_term;
|
||||
|
||||
pub fn print_entry(base: &Path, entry: &PathBuf, config: &FdOptions) {
|
||||
let path_full = base.join(entry);
|
||||
let path_full = if !entry.as_os_str().is_empty() {
|
||||
base.join(entry)
|
||||
} else {
|
||||
base.to_path_buf()
|
||||
};
|
||||
|
||||
let path_to_print = if config.path_display == PathDisplay::Absolute {
|
||||
&path_full
|
||||
|
|
|
@ -3,7 +3,7 @@ use fshelper;
|
|||
use internal::{error, FdOptions, PathDisplay};
|
||||
use output;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::channel;
|
||||
use std::thread;
|
||||
|
@ -193,15 +193,11 @@ pub fn scan(root: &Path, pattern: Arc<Regex>, base: &Path, config: Arc<FdOptions
|
|||
|
||||
if let Some(search_str) = search_str_o {
|
||||
pattern.find(&*search_str).map(|_| {
|
||||
let mut path_rel_buf = match fshelper::path_relative_from(entry_path, &*base) {
|
||||
let path_rel_buf = match fshelper::path_relative_from(entry_path, &*base) {
|
||||
Some(p) => p,
|
||||
None => error("Error: could not get relative path for directory entry."),
|
||||
};
|
||||
|
||||
if path_rel_buf == PathBuf::new() {
|
||||
path_rel_buf.push(".");
|
||||
}
|
||||
|
||||
// TODO: take care of the unwrap call
|
||||
tx_thread.send(path_rel_buf.to_owned()).unwrap()
|
||||
});
|
||||
|
|
103
tests/tests.rs
103
tests/tests.rs
|
@ -4,6 +4,20 @@ mod testenv;
|
|||
|
||||
use testenv::TestEnv;
|
||||
|
||||
fn get_absolute_root_path(env: &TestEnv) -> String {
|
||||
let path = env.root()
|
||||
.canonicalize()
|
||||
.expect("absolute path")
|
||||
.to_str()
|
||||
.expect("string")
|
||||
.to_string();
|
||||
|
||||
#[cfg(windows)]
|
||||
let path = path.trim_left_matches(r"\\?\").to_string();
|
||||
|
||||
path
|
||||
}
|
||||
|
||||
/// Simple tests
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
|
@ -62,21 +76,21 @@ fn test_explicit_root_path() {
|
|||
"one/two",
|
||||
&["foo", "../../"],
|
||||
"../../a.foo
|
||||
../b.foo
|
||||
c.foo
|
||||
C.Foo2
|
||||
three/d.foo
|
||||
three/directory_foo",
|
||||
../../one/b.foo
|
||||
../../one/two/c.foo
|
||||
../../one/two/C.Foo2
|
||||
../../one/two/three/d.foo
|
||||
../../one/two/three/directory_foo",
|
||||
);
|
||||
|
||||
te.assert_output_subdirectory(
|
||||
"one/two/three",
|
||||
&["", ".."],
|
||||
".
|
||||
../c.foo
|
||||
"../c.foo
|
||||
../C.Foo2
|
||||
d.foo
|
||||
directory_foo",
|
||||
../three
|
||||
../three/d.foo
|
||||
../three/directory_foo",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -314,15 +328,7 @@ fn test_max_depth() {
|
|||
fn test_absolute_path() {
|
||||
let te = TestEnv::new();
|
||||
|
||||
let abs_path = te.root()
|
||||
.canonicalize()
|
||||
.expect("absolute path")
|
||||
.to_str()
|
||||
.expect("string")
|
||||
.to_string();
|
||||
|
||||
#[cfg(windows)]
|
||||
let abs_path = abs_path.trim_left_matches(r"\\?\");
|
||||
let abs_path = get_absolute_root_path(&te);
|
||||
|
||||
te.assert_output(
|
||||
&["--absolute-path"],
|
||||
|
@ -416,3 +422,64 @@ fn test_extension() {
|
|||
|
||||
te.assert_output(&["--extension", "foo2"], "one/two/C.Foo2");
|
||||
}
|
||||
|
||||
/// Symlinks misc
|
||||
#[test]
|
||||
fn test_symlink() {
|
||||
let te = TestEnv::new();
|
||||
|
||||
let abs_path = get_absolute_root_path(&te);
|
||||
|
||||
// From: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html
|
||||
// The getcwd() function shall place an absolute pathname of the current working directory in
|
||||
// the array pointed to by buf, and return buf. The pathname shall contain no components that
|
||||
// are dot or dot-dot, or are symbolic links.
|
||||
//
|
||||
// Symlinks on Unix are aliases to real paths, only has one redirection.
|
||||
//
|
||||
// Symlinks on Windows can refer to symlinks, and are resolved after logical step "..".
|
||||
|
||||
let parent_parent = if cfg!(windows) { ".." } else { "../.." };
|
||||
te.assert_output_subdirectory(
|
||||
"symlink",
|
||||
&["", &parent_parent],
|
||||
&format!(
|
||||
"{dir}/a.foo
|
||||
{dir}/one
|
||||
{dir}/one/b.foo
|
||||
{dir}/one/two
|
||||
{dir}/one/two/c.foo
|
||||
{dir}/one/two/C.Foo2
|
||||
{dir}/one/two/three
|
||||
{dir}/one/two/three/d.foo
|
||||
{dir}/one/two/three/directory_foo
|
||||
{dir}/symlink",
|
||||
dir = &parent_parent
|
||||
),
|
||||
);
|
||||
|
||||
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
|
||||
),
|
||||
);
|
||||
|
||||
te.assert_output(
|
||||
&["", &format!("{abs_path}/symlink", abs_path = abs_path)],
|
||||
&format!(
|
||||
"{abs_path}/symlink/c.foo
|
||||
{abs_path}/symlink/C.Foo2
|
||||
{abs_path}/symlink/three
|
||||
{abs_path}/symlink/three/d.foo
|
||||
{abs_path}/symlink/three/directory_foo",
|
||||
abs_path = abs_path
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue