mirror of
https://github.com/BurntSushi/walkdir.git
synced 2025-09-26 21:20:23 +00:00
style: switch to rustfmt
This commit is contained in:
parent
dc7499a6c6
commit
c584a1d56c
38
.github/workflows/ci.yml
vendored
38
.github/workflows/ci.yml
vendored
@ -67,22 +67,22 @@ jobs:
|
||||
cargo build --verbose
|
||||
cargo test --verbose
|
||||
|
||||
# TODO: Switch to rustfmt for walkdir 3. walkdir 3 is in a
|
||||
# half-finished state, and applying rustfmt now would wreak havoc.
|
||||
# rustfmt:
|
||||
# name: rustfmt
|
||||
# runs-on: ubuntu-18.04
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v1
|
||||
# with:
|
||||
# fetch-depth: 1
|
||||
# - name: Install Rust
|
||||
# uses: hecrj/setup-rust-action@v1
|
||||
# with:
|
||||
# rust-version: stable
|
||||
# - name: Install rustfmt
|
||||
# run: rustup component add rustfmt
|
||||
# - name: Check formatting
|
||||
# run: |
|
||||
# cargo fmt --all -- --check
|
||||
rustfmt:
|
||||
name: rustfmt
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
components: rustfmt
|
||||
- name: Install rustfmt
|
||||
run: rustup component add rustfmt
|
||||
- name: Check formatting
|
||||
run: |
|
||||
cargo fmt --all -- --check
|
||||
|
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
@ -0,0 +1,2 @@
|
||||
max_width = 79
|
||||
use_small_heuristics = "max"
|
82
src/dent.rs
82
src/dent.rs
@ -58,7 +58,6 @@ pub struct DirEntry {
|
||||
metadata: fs::Metadata,
|
||||
}
|
||||
|
||||
|
||||
impl DirEntry {
|
||||
/// The full path that this entry represents.
|
||||
///
|
||||
@ -134,7 +133,8 @@ impl DirEntry {
|
||||
fs::metadata(&self.path)
|
||||
} else {
|
||||
Ok(self.metadata.clone())
|
||||
}.map_err(|err| Error::from_entry(self, err))
|
||||
}
|
||||
.map_err(|err| Error::from_entry(self, err))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
@ -143,7 +143,8 @@ impl DirEntry {
|
||||
fs::metadata(&self.path)
|
||||
} else {
|
||||
fs::symlink_metadata(&self.path)
|
||||
}.map_err(|err| Error::from_entry(self, err))
|
||||
}
|
||||
.map_err(|err| Error::from_entry(self, err))
|
||||
}
|
||||
|
||||
/// Return the file type for the file that this entry points to.
|
||||
@ -198,12 +199,12 @@ impl DirEntry {
|
||||
ent: &fs::DirEntry,
|
||||
) -> Result<DirEntry> {
|
||||
let path = ent.path();
|
||||
let ty = ent.file_type().map_err(|err| {
|
||||
Error::from_path(depth, path.clone(), err)
|
||||
})?;
|
||||
let md = ent.metadata().map_err(|err| {
|
||||
Error::from_path(depth, path.clone(), err)
|
||||
})?;
|
||||
let ty = ent
|
||||
.file_type()
|
||||
.map_err(|err| Error::from_path(depth, path.clone(), err))?;
|
||||
let md = ent
|
||||
.metadata()
|
||||
.map_err(|err| Error::from_path(depth, path.clone(), err))?;
|
||||
Ok(DirEntry {
|
||||
path: path,
|
||||
ty: ty,
|
||||
@ -220,9 +221,9 @@ impl DirEntry {
|
||||
) -> Result<DirEntry> {
|
||||
use std::os::unix::fs::DirEntryExt;
|
||||
|
||||
let ty = ent.file_type().map_err(|err| {
|
||||
Error::from_path(depth, ent.path(), err)
|
||||
})?;
|
||||
let ty = ent
|
||||
.file_type()
|
||||
.map_err(|err| Error::from_path(depth, ent.path(), err))?;
|
||||
Ok(DirEntry {
|
||||
path: ent.path(),
|
||||
ty: ty,
|
||||
@ -237,9 +238,9 @@ impl DirEntry {
|
||||
depth: usize,
|
||||
ent: &fs::DirEntry,
|
||||
) -> Result<DirEntry> {
|
||||
let ty = ent.file_type().map_err(|err| {
|
||||
Error::from_path(depth, ent.path(), err)
|
||||
})?;
|
||||
let ty = ent
|
||||
.file_type()
|
||||
.map_err(|err| Error::from_path(depth, ent.path(), err))?;
|
||||
Ok(DirEntry {
|
||||
path: ent.path(),
|
||||
ty: ty,
|
||||
@ -254,16 +255,13 @@ impl DirEntry {
|
||||
pb: PathBuf,
|
||||
follow: bool,
|
||||
) -> Result<DirEntry> {
|
||||
let md =
|
||||
if follow {
|
||||
fs::metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
};
|
||||
let md = if follow {
|
||||
fs::metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
};
|
||||
Ok(DirEntry {
|
||||
path: pb,
|
||||
ty: md.file_type(),
|
||||
@ -281,16 +279,13 @@ impl DirEntry {
|
||||
) -> Result<DirEntry> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
let md =
|
||||
if follow {
|
||||
fs::metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
};
|
||||
let md = if follow {
|
||||
fs::metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
};
|
||||
Ok(DirEntry {
|
||||
path: pb,
|
||||
ty: md.file_type(),
|
||||
@ -306,16 +301,13 @@ impl DirEntry {
|
||||
pb: PathBuf,
|
||||
follow: bool,
|
||||
) -> Result<DirEntry> {
|
||||
let md =
|
||||
if follow {
|
||||
fs::metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb).map_err(|err| {
|
||||
Error::from_path(depth, pb.clone(), err)
|
||||
})?
|
||||
};
|
||||
let md = if follow {
|
||||
fs::metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
} else {
|
||||
fs::symlink_metadata(&pb)
|
||||
.map_err(|err| Error::from_path(depth, pb.clone(), err))?
|
||||
};
|
||||
Ok(DirEntry {
|
||||
path: pb,
|
||||
ty: md.file_type(),
|
||||
|
45
src/error.rs
45
src/error.rs
@ -141,10 +141,10 @@ impl Error {
|
||||
/// [`into_io_error`]: struct.Error.html#method.into_io_error
|
||||
/// [impl]: struct.Error.html#impl-From%3CError%3E
|
||||
pub fn io_error(&self) -> Option<&io::Error> {
|
||||
match self.inner {
|
||||
match self.inner {
|
||||
ErrorInner::Io { ref err, .. } => Some(err),
|
||||
ErrorInner::Loop { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to [`io_error`] except consumes self to convert to the original
|
||||
@ -153,10 +153,10 @@ impl Error {
|
||||
/// [`io_error`]: struct.Error.html#method.io_error
|
||||
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
|
||||
pub fn into_io_error(self) -> Option<io::Error> {
|
||||
match self.inner {
|
||||
match self.inner {
|
||||
ErrorInner::Io { err, .. } => Some(err),
|
||||
ErrorInner::Loop { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_path(
|
||||
@ -181,10 +181,7 @@ impl Error {
|
||||
}
|
||||
|
||||
pub(crate) fn from_io(depth: usize, err: io::Error) -> Self {
|
||||
Error {
|
||||
depth: depth,
|
||||
inner: ErrorInner::Io { path: None, err: err },
|
||||
}
|
||||
Error { depth: depth, inner: ErrorInner::Io { path: None, err: err } }
|
||||
}
|
||||
|
||||
pub(crate) fn from_loop(
|
||||
@ -197,7 +194,7 @@ impl Error {
|
||||
inner: ErrorInner::Loop {
|
||||
ancestor: ancestor.to_path_buf(),
|
||||
child: child.to_path_buf(),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,18 +223,20 @@ impl error::Error for Error {
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.inner {
|
||||
ErrorInner::Io { path: None, ref err } => {
|
||||
err.fmt(f)
|
||||
}
|
||||
ErrorInner::Io { path: Some(ref path), ref err } => {
|
||||
write!(f, "IO error for operation on {}: {}",
|
||||
path.display(), err)
|
||||
}
|
||||
ErrorInner::Loop { ref ancestor, ref child } => {
|
||||
write!(f, "File system loop found: \
|
||||
{} points to an ancestor {}",
|
||||
child.display(), ancestor.display())
|
||||
}
|
||||
ErrorInner::Io { path: None, ref err } => err.fmt(f),
|
||||
ErrorInner::Io { path: Some(ref path), ref err } => write!(
|
||||
f,
|
||||
"IO error for operation on {}: {}",
|
||||
path.display(),
|
||||
err
|
||||
),
|
||||
ErrorInner::Loop { ref ancestor, ref child } => write!(
|
||||
f,
|
||||
"File system loop found: \
|
||||
{} points to an ancestor {}",
|
||||
child.display(),
|
||||
ancestor.display()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,9 +255,7 @@ impl From<Error> for io::Error {
|
||||
/// [`into_io_error`]: struct.WalkDir.html#method.into_io_error
|
||||
fn from(walk_err: Error) -> io::Error {
|
||||
let kind = match walk_err {
|
||||
Error { inner: ErrorInner::Io { ref err, .. }, .. } => {
|
||||
err.kind()
|
||||
}
|
||||
Error { inner: ErrorInner::Io { ref err, .. }, .. } => err.kind(),
|
||||
Error { inner: ErrorInner::Loop { .. }, .. } => {
|
||||
io::ErrorKind::Other
|
||||
}
|
||||
|
92
src/lib.rs
92
src/lib.rs
@ -118,7 +118,7 @@ extern crate winapi_util;
|
||||
#[cfg(test)]
|
||||
doctest!("../README.md");
|
||||
|
||||
use std::cmp::{Ordering, min};
|
||||
use std::cmp::{min, Ordering};
|
||||
use std::fmt;
|
||||
use std::fs::{self, ReadDir};
|
||||
use std::io;
|
||||
@ -148,7 +148,7 @@ macro_rules! itry {
|
||||
Ok(v) => v,
|
||||
Err(err) => return Some(Err(From::from(err))),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A result type for walkdir operations.
|
||||
@ -249,9 +249,14 @@ struct WalkDirOptions {
|
||||
max_open: usize,
|
||||
min_depth: usize,
|
||||
max_depth: usize,
|
||||
sorter: Option<Box<
|
||||
dyn FnMut(&DirEntry,&DirEntry) -> Ordering + Send + Sync + 'static
|
||||
>>,
|
||||
sorter: Option<
|
||||
Box<
|
||||
dyn FnMut(&DirEntry, &DirEntry) -> Ordering
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>,
|
||||
>,
|
||||
contents_first: bool,
|
||||
same_file_system: bool,
|
||||
}
|
||||
@ -392,7 +397,8 @@ impl WalkDir {
|
||||
/// WalkDir::new("foo").sort_by(|a,b| a.file_name().cmp(b.file_name()));
|
||||
/// ```
|
||||
pub fn sort_by<F>(mut self, cmp: F) -> Self
|
||||
where F: FnMut(&DirEntry, &DirEntry) -> Ordering + Send + Sync + 'static
|
||||
where
|
||||
F: FnMut(&DirEntry, &DirEntry) -> Ordering + Send + Sync + 'static,
|
||||
{
|
||||
self.opts.sorter = Some(Box::new(cmp));
|
||||
self
|
||||
@ -565,10 +571,7 @@ impl Ancestor {
|
||||
#[cfg(windows)]
|
||||
fn new(dent: &DirEntry) -> io::Result<Ancestor> {
|
||||
let handle = Handle::from_path(dent.path())?;
|
||||
Ok(Ancestor {
|
||||
path: dent.path().to_path_buf(),
|
||||
handle: handle,
|
||||
})
|
||||
Ok(Ancestor { path: dent.path().to_path_buf(), handle: handle })
|
||||
}
|
||||
|
||||
/// Create a new ancestor from the given directory path.
|
||||
@ -653,7 +656,8 @@ impl Iterator for IntoIter {
|
||||
}
|
||||
// Unwrap is safe here because we've verified above that
|
||||
// `self.stack_list` is not empty
|
||||
let next = self.stack_list
|
||||
let next = self
|
||||
.stack_list
|
||||
.last_mut()
|
||||
.expect("BUG: stack should be non-empty")
|
||||
.next();
|
||||
@ -774,7 +778,8 @@ impl IntoIter {
|
||||
/// [`min_depth`]: struct.WalkDir.html#method.min_depth
|
||||
/// [`max_depth`]: struct.WalkDir.html#method.max_depth
|
||||
pub fn filter_entry<P>(self, predicate: P) -> FilterEntry<Self, P>
|
||||
where P: FnMut(&DirEntry) -> bool
|
||||
where
|
||||
P: FnMut(&DirEntry) -> bool,
|
||||
{
|
||||
FilterEntry { it: self, predicate: predicate }
|
||||
}
|
||||
@ -825,7 +830,9 @@ impl IntoIter {
|
||||
if self.depth < self.deferred_dirs.len() {
|
||||
// Unwrap is safe here because we've guaranteed that
|
||||
// `self.deferred_dirs.len()` can never be less than 1
|
||||
let deferred: DirEntry = self.deferred_dirs.pop()
|
||||
let deferred: DirEntry = self
|
||||
.deferred_dirs
|
||||
.pop()
|
||||
.expect("BUG: deferred_dirs should be non-empty");
|
||||
if !self.skippable() {
|
||||
return Some(deferred);
|
||||
@ -837,9 +844,8 @@ impl IntoIter {
|
||||
|
||||
fn push(&mut self, dent: &DirEntry) -> Result<()> {
|
||||
// Make room for another open file descriptor if we've hit the max.
|
||||
let free = self.stack_list
|
||||
.len()
|
||||
.checked_sub(self.oldest_opened).unwrap();
|
||||
let free =
|
||||
self.stack_list.len().checked_sub(self.oldest_opened).unwrap();
|
||||
if free == self.opts.max_open {
|
||||
self.stack_list[self.oldest_opened].close();
|
||||
}
|
||||
@ -850,20 +856,17 @@ impl IntoIter {
|
||||
let mut list = DirList::Opened { depth: self.depth, it: rd };
|
||||
if let Some(ref mut cmp) = self.opts.sorter {
|
||||
let mut entries: Vec<_> = list.collect();
|
||||
entries.sort_by(|a, b| {
|
||||
match (a, b) {
|
||||
(&Ok(ref a), &Ok(ref b)) => cmp(a, b),
|
||||
(&Err(_), &Err(_)) => Ordering::Equal,
|
||||
(&Ok(_), &Err(_)) => Ordering::Greater,
|
||||
(&Err(_), &Ok(_)) => Ordering::Less,
|
||||
}
|
||||
entries.sort_by(|a, b| match (a, b) {
|
||||
(&Ok(ref a), &Ok(ref b)) => cmp(a, b),
|
||||
(&Err(_), &Err(_)) => Ordering::Equal,
|
||||
(&Ok(_), &Err(_)) => Ordering::Greater,
|
||||
(&Err(_), &Ok(_)) => Ordering::Less,
|
||||
});
|
||||
list = DirList::Closed(entries.into_iter());
|
||||
}
|
||||
if self.opts.follow_links {
|
||||
let ancestor = Ancestor::new(&dent).map_err(|err| {
|
||||
Error::from_io(self.depth, err)
|
||||
})?;
|
||||
let ancestor = Ancestor::new(&dent)
|
||||
.map_err(|err| Error::from_io(self.depth, err))?;
|
||||
self.stack_path.push(ancestor);
|
||||
}
|
||||
// We push this after stack_path since creating the Ancestor can fail.
|
||||
@ -900,11 +903,8 @@ impl IntoIter {
|
||||
}
|
||||
|
||||
fn follow(&self, mut dent: DirEntry) -> Result<DirEntry> {
|
||||
dent = DirEntry::from_path(
|
||||
self.depth,
|
||||
dent.path().to_path_buf(),
|
||||
true,
|
||||
)?;
|
||||
dent =
|
||||
DirEntry::from_path(self.depth, dent.path().to_path_buf(), true)?;
|
||||
// The only way a symlink can cause a loop is if it points
|
||||
// to a directory. Otherwise, it always points to a leaf
|
||||
// and we can omit any loop checks.
|
||||
@ -915,16 +915,17 @@ impl IntoIter {
|
||||
}
|
||||
|
||||
fn check_loop<P: AsRef<Path>>(&self, child: P) -> Result<()> {
|
||||
let hchild = Handle::from_path(&child).map_err(|err| {
|
||||
Error::from_io(self.depth, err)
|
||||
})?;
|
||||
let hchild = Handle::from_path(&child)
|
||||
.map_err(|err| Error::from_io(self.depth, err))?;
|
||||
for ancestor in self.stack_path.iter().rev() {
|
||||
let is_same = ancestor.is_same(&hchild).map_err(|err| {
|
||||
Error::from_io(self.depth, err)
|
||||
})?;
|
||||
let is_same = ancestor
|
||||
.is_same(&hchild)
|
||||
.map_err(|err| Error::from_io(self.depth, err))?;
|
||||
if is_same {
|
||||
return Err(Error::from_loop(
|
||||
self.depth, &ancestor.path, child.as_ref(),
|
||||
self.depth,
|
||||
&ancestor.path,
|
||||
child.as_ref(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -934,7 +935,8 @@ impl IntoIter {
|
||||
fn is_same_file_system(&mut self, dent: &DirEntry) -> Result<bool> {
|
||||
let dent_device = util::device_num(dent.path())
|
||||
.map_err(|err| Error::from_entry(dent, err))?;
|
||||
Ok(self.root_device
|
||||
Ok(self
|
||||
.root_device
|
||||
.map(|d| d == dent_device)
|
||||
.expect("BUG: called is_same_file_system without root device"))
|
||||
}
|
||||
@ -963,9 +965,9 @@ impl Iterator for DirList {
|
||||
Err(ref mut err) => err.take().map(Err),
|
||||
Ok(ref mut rd) => rd.next().map(|r| match r {
|
||||
Ok(r) => DirEntry::from_entry(depth + 1, &r),
|
||||
Err(err) => Err(Error::from_io(depth + 1, err))
|
||||
Err(err) => Err(Error::from_io(depth + 1, err)),
|
||||
}),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -998,7 +1000,8 @@ pub struct FilterEntry<I, P> {
|
||||
}
|
||||
|
||||
impl<P> Iterator for FilterEntry<IntoIter, P>
|
||||
where P: FnMut(&DirEntry) -> bool
|
||||
where
|
||||
P: FnMut(&DirEntry) -> bool,
|
||||
{
|
||||
type Item = Result<DirEntry>;
|
||||
|
||||
@ -1025,7 +1028,10 @@ where P: FnMut(&DirEntry) -> bool
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> FilterEntry<IntoIter, P> where P: FnMut(&DirEntry) -> bool {
|
||||
impl<P> FilterEntry<IntoIter, P>
|
||||
where
|
||||
P: FnMut(&DirEntry) -> bool,
|
||||
{
|
||||
/// Yields only entries which satisfy the given predicate and skips
|
||||
/// descending into directories that do not satisfy the given predicate.
|
||||
///
|
||||
|
@ -6,7 +6,7 @@ use WalkDir;
|
||||
|
||||
#[test]
|
||||
fn send_sync_traits() {
|
||||
use {IntoIter, FilterEntry};
|
||||
use {FilterEntry, IntoIter};
|
||||
|
||||
fn assert_send<T: Send>() {}
|
||||
fn assert_sync<T: Sync>() {}
|
||||
@ -209,9 +209,8 @@ fn many_mixed() {
|
||||
|
||||
#[test]
|
||||
fn nested() {
|
||||
let nested = PathBuf::from(
|
||||
"a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z",
|
||||
);
|
||||
let nested =
|
||||
PathBuf::from("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
|
||||
let dir = Dir::tmp();
|
||||
dir.mkdirp(&nested);
|
||||
dir.touch(nested.join("A"));
|
||||
@ -255,9 +254,8 @@ fn nested() {
|
||||
|
||||
#[test]
|
||||
fn nested_small_max_open() {
|
||||
let nested = PathBuf::from(
|
||||
"a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z",
|
||||
);
|
||||
let nested =
|
||||
PathBuf::from("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
|
||||
let dir = Dir::tmp();
|
||||
dir.mkdirp(&nested);
|
||||
dir.touch(nested.join("A"));
|
||||
@ -723,10 +721,7 @@ fn min_depth_1() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a"),
|
||||
dir.join("a").join("b"),
|
||||
];
|
||||
let expected = vec![dir.join("a"), dir.join("a").join("b")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -739,9 +734,7 @@ fn min_depth_2() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a").join("b"),
|
||||
];
|
||||
let expected = vec![dir.join("a").join("b")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -754,9 +747,7 @@ fn max_depth_0() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.path().to_path_buf(),
|
||||
];
|
||||
let expected = vec![dir.path().to_path_buf()];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -769,10 +760,7 @@ fn max_depth_1() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.path().to_path_buf(),
|
||||
dir.join("a"),
|
||||
];
|
||||
let expected = vec![dir.path().to_path_buf(), dir.join("a")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -785,11 +773,8 @@ fn max_depth_2() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.path().to_path_buf(),
|
||||
dir.join("a"),
|
||||
dir.join("a").join("b"),
|
||||
];
|
||||
let expected =
|
||||
vec![dir.path().to_path_buf(), dir.join("a"), dir.join("a").join("b")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -803,9 +788,7 @@ fn min_max_depth_diff_nada() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a").join("b").join("c"),
|
||||
];
|
||||
let expected = vec![dir.join("a").join("b").join("c")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -818,9 +801,7 @@ fn min_max_depth_diff_0() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a").join("b"),
|
||||
];
|
||||
let expected = vec![dir.join("a").join("b")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -833,10 +814,7 @@ fn min_max_depth_diff_1() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a"),
|
||||
dir.join("a").join("b"),
|
||||
];
|
||||
let expected = vec![dir.join("a"), dir.join("a").join("b")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
@ -849,10 +827,7 @@ fn contents_first() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.join("a"),
|
||||
dir.path().to_path_buf(),
|
||||
];
|
||||
let expected = vec![dir.join("a"), dir.path().to_path_buf()];
|
||||
assert_eq!(expected, r.paths());
|
||||
}
|
||||
|
||||
@ -910,7 +885,7 @@ fn sort() {
|
||||
dir.mkdirp("quux");
|
||||
|
||||
let wd = WalkDir::new(dir.path())
|
||||
.sort_by(|a,b| a.file_name().cmp(b.file_name()).reverse());
|
||||
.sort_by(|a, b| a.file_name().cmp(b.file_name()).reverse());
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
@ -933,7 +908,7 @@ fn sort_max_open() {
|
||||
|
||||
let wd = WalkDir::new(dir.path())
|
||||
.max_open(1)
|
||||
.sort_by(|a,b| a.file_name().cmp(b.file_name()).reverse());
|
||||
.sort_by(|a, b| a.file_name().cmp(b.file_name()).reverse());
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
@ -969,25 +944,18 @@ fn same_file_system() {
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.path().to_path_buf(),
|
||||
dir.join("a"),
|
||||
dir.join("sys-link"),
|
||||
];
|
||||
let expected =
|
||||
vec![dir.path().to_path_buf(), dir.join("a"), dir.join("sys-link")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
|
||||
// ... now follow symlinks and ensure we don't descend into /sys.
|
||||
let wd = WalkDir::new(dir.path())
|
||||
.same_file_system(true)
|
||||
.follow_links(true);
|
||||
let wd =
|
||||
WalkDir::new(dir.path()).same_file_system(true).follow_links(true);
|
||||
let r = dir.run_recursive(wd);
|
||||
r.assert_no_errors();
|
||||
|
||||
let expected = vec![
|
||||
dir.path().to_path_buf(),
|
||||
dir.join("a"),
|
||||
dir.join("sys-link"),
|
||||
];
|
||||
let expected =
|
||||
vec![dir.path().to_path_buf(), dir.join("a"), dir.join("sys-link")];
|
||||
assert_eq!(expected, r.sorted_paths());
|
||||
}
|
||||
|
||||
|
@ -98,16 +98,11 @@ impl Dir {
|
||||
|
||||
/// Run the given iterator and return the result as a distinct collection
|
||||
/// of directory entries and errors.
|
||||
pub fn run_recursive<I>(
|
||||
&self,
|
||||
it: I,
|
||||
) -> RecursiveResults
|
||||
where I: IntoIterator<Item=result::Result<DirEntry, Error>>
|
||||
pub fn run_recursive<I>(&self, it: I) -> RecursiveResults
|
||||
where
|
||||
I: IntoIterator<Item = result::Result<DirEntry, Error>>,
|
||||
{
|
||||
let mut results = RecursiveResults {
|
||||
ents: vec![],
|
||||
errs: vec![],
|
||||
};
|
||||
let mut results = RecursiveResults { ents: vec![], errs: vec![] };
|
||||
for result in it {
|
||||
match result {
|
||||
Ok(ent) => results.ents.push(ent),
|
||||
@ -170,7 +165,9 @@ impl Dir {
|
||||
.map_err(|e| {
|
||||
err!(
|
||||
"failed to symlink file {} with target {}: {}",
|
||||
src.display(), link_name.display(), e
|
||||
src.display(),
|
||||
link_name.display(),
|
||||
e
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
@ -199,7 +196,9 @@ impl Dir {
|
||||
.map_err(|e| {
|
||||
err!(
|
||||
"failed to symlink directory {} with target {}: {}",
|
||||
src.display(), link_name.display(), e
|
||||
src.display(),
|
||||
link_name.display(),
|
||||
e
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
@ -225,7 +224,7 @@ impl TempDir {
|
||||
/// temporary directory.
|
||||
pub fn new() -> Result<TempDir> {
|
||||
#[allow(deprecated)]
|
||||
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
static TRIES: usize = 100;
|
||||
#[allow(deprecated)]
|
||||
|
@ -2,22 +2,22 @@ use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn device_num<P: AsRef<Path>>(path: P)-> io::Result<u64> {
|
||||
pub fn device_num<P: AsRef<Path>>(path: P) -> io::Result<u64> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
path.as_ref().metadata().map(|md| md.dev())
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg(windows)]
|
||||
pub fn device_num<P: AsRef<Path>>(path: P) -> io::Result<u64> {
|
||||
use winapi_util::{Handle, file};
|
||||
use winapi_util::{file, Handle};
|
||||
|
||||
let h = Handle::from_path_any(path)?;
|
||||
file::information(h).map(|info| info.volume_serial_number())
|
||||
}
|
||||
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
pub fn device_num<P: AsRef<Path>>(_: P)-> io::Result<u64> {
|
||||
pub fn device_num<P: AsRef<Path>>(_: P) -> io::Result<u64> {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"walkdir: same_file_system option not supported on this platform",
|
||||
|
@ -59,8 +59,9 @@ fn print_count<W1, W2>(
|
||||
mut stdout: W1,
|
||||
mut stderr: W2,
|
||||
) -> Result<()>
|
||||
where W1: io::Write,
|
||||
W2: io::Write
|
||||
where
|
||||
W1: io::Write,
|
||||
W2: io::Write,
|
||||
{
|
||||
let mut count: u64 = 0;
|
||||
for dir in &args.dirs {
|
||||
@ -84,8 +85,9 @@ fn print_paths<W1, W2>(
|
||||
mut stdout: W1,
|
||||
mut stderr: W2,
|
||||
) -> Result<()>
|
||||
where W1: io::Write,
|
||||
W2: io::Write
|
||||
where
|
||||
W1: io::Write,
|
||||
W2: io::Write,
|
||||
{
|
||||
for dir in &args.dirs {
|
||||
if args.tree {
|
||||
@ -103,8 +105,9 @@ fn print_paths_flat<W1, W2>(
|
||||
mut stderr: W2,
|
||||
dir: &Path,
|
||||
) -> Result<()>
|
||||
where W1: io::Write,
|
||||
W2: io::Write
|
||||
where
|
||||
W1: io::Write,
|
||||
W2: io::Write,
|
||||
{
|
||||
for result in args.walkdir(dir) {
|
||||
let dent = match result {
|
||||
@ -128,8 +131,9 @@ fn print_paths_tree<W1, W2>(
|
||||
mut stderr: W2,
|
||||
dir: &Path,
|
||||
) -> Result<()>
|
||||
where W1: io::Write,
|
||||
W2: io::Write
|
||||
where
|
||||
W1: io::Write,
|
||||
W2: io::Write,
|
||||
{
|
||||
for result in args.walkdir(dir) {
|
||||
let dent = match result {
|
||||
@ -166,62 +170,78 @@ struct Args {
|
||||
|
||||
impl Args {
|
||||
fn parse() -> Result<Args> {
|
||||
use clap::{App, Arg, crate_authors, crate_version};
|
||||
use clap::{crate_authors, crate_version, App, Arg};
|
||||
|
||||
let parsed = App::new("List files using walkdir")
|
||||
.author(crate_authors!())
|
||||
.version(crate_version!())
|
||||
.max_term_width(100)
|
||||
.arg(Arg::with_name("dirs")
|
||||
.multiple(true)
|
||||
.arg(Arg::with_name("dirs").multiple(true))
|
||||
.arg(
|
||||
Arg::with_name("follow-links")
|
||||
.long("follow-links")
|
||||
.short("L")
|
||||
.help("Follow symbolic links."),
|
||||
)
|
||||
.arg(Arg::with_name("follow-links")
|
||||
.long("follow-links").short("L")
|
||||
.help("Follow symbolic links.")
|
||||
.arg(
|
||||
Arg::with_name("min-depth")
|
||||
.long("min-depth")
|
||||
.takes_value(true)
|
||||
.help("Only show entries at or above this depth."),
|
||||
)
|
||||
.arg(Arg::with_name("min-depth")
|
||||
.long("min-depth")
|
||||
.takes_value(true)
|
||||
.help("Only show entries at or above this depth.")
|
||||
.arg(
|
||||
Arg::with_name("max-depth")
|
||||
.long("max-depth")
|
||||
.takes_value(true)
|
||||
.help("Only show entries at or below this depth."),
|
||||
)
|
||||
.arg(Arg::with_name("max-depth")
|
||||
.long("max-depth")
|
||||
.takes_value(true)
|
||||
.help("Only show entries at or below this depth.")
|
||||
.arg(
|
||||
Arg::with_name("max-open")
|
||||
.long("max-open")
|
||||
.takes_value(true)
|
||||
.default_value("10")
|
||||
.help("Use at most this many open file descriptors."),
|
||||
)
|
||||
.arg(Arg::with_name("max-open")
|
||||
.long("max-open")
|
||||
.takes_value(true)
|
||||
.default_value("10")
|
||||
.help("Use at most this many open file descriptors.")
|
||||
.arg(
|
||||
Arg::with_name("tree")
|
||||
.long("tree")
|
||||
.help("Show file paths in a tree."),
|
||||
)
|
||||
.arg(Arg::with_name("tree")
|
||||
.long("tree")
|
||||
.help("Show file paths in a tree.")
|
||||
.arg(
|
||||
Arg::with_name("ignore-errors")
|
||||
.long("ignore-errors")
|
||||
.short("q")
|
||||
.help("Don't print error messages."),
|
||||
)
|
||||
.arg(Arg::with_name("ignore-errors")
|
||||
.long("ignore-errors").short("q")
|
||||
.help("Don't print error messages.")
|
||||
.arg(
|
||||
Arg::with_name("sort")
|
||||
.long("sort")
|
||||
.help("Sort file paths lexicographically."),
|
||||
)
|
||||
.arg(Arg::with_name("sort")
|
||||
.long("sort")
|
||||
.help("Sort file paths lexicographically.")
|
||||
.arg(
|
||||
Arg::with_name("depth-first").long("depth-first").help(
|
||||
"Show directory contents before the directory path.",
|
||||
),
|
||||
)
|
||||
.arg(Arg::with_name("depth-first")
|
||||
.long("depth-first")
|
||||
.help("Show directory contents before the directory path.")
|
||||
.arg(
|
||||
Arg::with_name("same-file-system")
|
||||
.long("same-file-system")
|
||||
.short("x")
|
||||
.help(
|
||||
"Only show paths on the same file system as the root.",
|
||||
),
|
||||
)
|
||||
.arg(Arg::with_name("same-file-system")
|
||||
.long("same-file-system").short("x")
|
||||
.help("Only show paths on the same file system as the root.")
|
||||
.arg(
|
||||
Arg::with_name("timeit")
|
||||
.long("timeit")
|
||||
.short("t")
|
||||
.help("Print timing info."),
|
||||
)
|
||||
.arg(Arg::with_name("timeit")
|
||||
.long("timeit").short("t")
|
||||
.help("Print timing info.")
|
||||
)
|
||||
.arg(Arg::with_name("count")
|
||||
.long("count").short("c")
|
||||
.help("Print only a total count of all file paths.")
|
||||
.arg(
|
||||
Arg::with_name("count")
|
||||
.long("count")
|
||||
.short("c")
|
||||
.help("Print only a total count of all file paths."),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
@ -260,22 +280,21 @@ impl Args {
|
||||
walkdir = walkdir.max_open(x);
|
||||
}
|
||||
if self.sort {
|
||||
walkdir = walkdir.sort_by(|a, b| {
|
||||
a.file_name().cmp(b.file_name())
|
||||
});
|
||||
walkdir = walkdir.sort_by(|a, b| a.file_name().cmp(b.file_name()));
|
||||
}
|
||||
walkdir
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_usize(parsed: &clap::ArgMatches, flag: &str) -> Result<Option<usize>> {
|
||||
fn parse_usize(
|
||||
parsed: &clap::ArgMatches,
|
||||
flag: &str,
|
||||
) -> Result<Option<usize>> {
|
||||
match parsed.value_of_lossy(flag) {
|
||||
None => Ok(None),
|
||||
Some(x) => {
|
||||
x.parse().map(Some).or_else(|e| {
|
||||
err!("failed to parse --{} as a number: {}", flag, e)
|
||||
})
|
||||
}
|
||||
Some(x) => x.parse().map(Some).or_else(|e| {
|
||||
err!("failed to parse --{} as a number: {}", flag, e)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user