diff --git a/.github/workflows/beta-unittests.yml b/.github/workflows/beta-unittests.yml new file mode 100644 index 0000000..4c945a5 --- /dev/null +++ b/.github/workflows/beta-unittests.yml @@ -0,0 +1,21 @@ +name: Unit Tests, Beta Toolchain + +on: + push: + branches: main + pull_request: + +jobs: + unit-tests-beta: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + name: Beta Unit Tests + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest beta Rust toolchain + uses: dtolnay/rust-toolchain@beta + - name: Run unit tests + run: cargo test diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml new file mode 100644 index 0000000..9a2d549 --- /dev/null +++ b/.github/workflows/fmt.yml @@ -0,0 +1,20 @@ +name: rustfmt Checks + +on: + push: + branches: main + pull_request: + +jobs: + rustfmt-checks: + runs-on: ubuntu-latest + name: rustfmt checks + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest stable Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Run rustfmt check + run: cargo fmt --all --check diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..37f70ed --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: Clippy Lints + +on: + push: + branches: main + pull_request: + +jobs: + clippy-lints-stable: + runs-on: ubuntu-latest + name: Clippy Lints (Stable) + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest stable Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Run clippy Lints + run: cargo clippy --all-features -- -D warnings + clippy-lints-beta: + runs-on: ubuntu-latest + name: Clippy Lints (Beta) + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest beta Rust toolchain + uses: dtolnay/rust-toolchain@beta + with: + components: clippy + - name: Run clippy Lints + run: cargo clippy --all-features -- -D warnings diff --git a/.github/workflows/nightly-unittests.yml b/.github/workflows/nightly-unittests.yml new file mode 100644 index 0000000..a67b74d --- /dev/null +++ b/.github/workflows/nightly-unittests.yml @@ -0,0 +1,21 @@ +name: Unit Tests, Nightly Toolchain + +on: + push: + branches: main + pull_request: + +jobs: + unit-tests-nightly: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + name: Nightly Unit Tests + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest nightly Rust toolchain + uses: dtolnay/rust-toolchain@nightly + - name: Run unit tests + run: cargo test diff --git a/.github/workflows/stable-unittests.yml b/.github/workflows/stable-unittests.yml new file mode 100644 index 0000000..6a8b5b3 --- /dev/null +++ b/.github/workflows/stable-unittests.yml @@ -0,0 +1,21 @@ +name: Unit Tests, Stable Toolchain + +on: + push: + branches: main + pull_request: + +jobs: + unit-tests-stable: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + name: Stable Unit Tests + steps: + - name: Check out source repository + uses: actions/checkout@v4 + - name: Install the latest stable Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Run unit tests + run: cargo test diff --git a/src/lib/walk.rs b/src/lib/walk.rs index 5e28043..588ac94 100644 --- a/src/lib/walk.rs +++ b/src/lib/walk.rs @@ -130,12 +130,12 @@ impl ParallelWalker { #[cfg(test)] mod tests { use super::*; - use ignore::{DirEntry, WalkParallel, WalkState}; + // use ignore::{DirEntry, WalkParallel, WalkState}; use pretty_assertions::assert_eq; use std::fs::File; use std::io::Write; use std::path::Path; - use std::sync::{Arc, Mutex}; + // use std::sync::{Arc, Mutex}; use tempfile::TempDir; fn mk_args( @@ -190,9 +190,26 @@ mod tests { paths } - fn walk_collect(prefix: &Path, args: &Args) -> Result> { + // fn walk_collect(prefix: &Path, args: &Args) -> Result> { + // let mut paths = vec![]; + // for result in Walker::new(args)? { + // let dirent = match result { + // Err(_) => continue, + // Ok(dirent) => dirent, + // }; + // let path = dirent.path().strip_prefix(prefix).unwrap(); + // if path.as_os_str().is_empty() { + // continue; + // } + // paths.push(normalize_path(path.to_str().unwrap())); + // } + + // Ok(paths) + // } + + fn walk_file_collect(prefix: &Path, args: &Args) -> Result> { let mut paths = vec![]; - for result in Walker::new(args)? { + for result in FileWalker::new(args)? { let dirent = match result { Err(_) => continue, Ok(dirent) => dirent, @@ -207,7 +224,7 @@ mod tests { Ok(paths) } - fn walk_file_collect(prefix: &Path, args: &Args) -> Result> { + fn walk_file_collect_sorted(prefix: &Path, args: &Args) -> Result> { let mut paths = vec![]; for result in FileWalker::new(args)? { let dirent = match result { @@ -220,48 +237,48 @@ mod tests { } paths.push(normalize_path(path.to_str().unwrap())); } - - Ok(paths) - } - - fn walk_collect_parallel(prefix: &Path, args: &Args) -> Result> { - let mut paths = vec![]; - for dirent in walk_collect_entries_parallel(ParallelWalker::new(args)?.walker) { - let path = dirent.path().strip_prefix(prefix).unwrap(); - if path.as_os_str().is_empty() { - continue; - } - paths.push(normalize_path(path.to_str().unwrap())); - } - // sort the paths before returning in order - // in order to be able to test. This represents - // an artificial order in the results, but we will - // still be able to confirm we have complete results paths.sort(); Ok(paths) } - fn walk_collect_entries_parallel(par_walker: WalkParallel) -> Vec { - let dirents = Arc::new(Mutex::new(vec![])); - par_walker.run(|| { - let dirents = dirents.clone(); - Box::new(move |result| { - if let Ok(dirent) = result { - dirents.lock().unwrap().push(dirent); - } - WalkState::Continue - }) - }); + // fn walk_collect_parallel(prefix: &Path, args: &Args) -> Result> { + // let mut paths = vec![]; + // for dirent in walk_collect_entries_parallel(ParallelWalker::new(args)?.walker) { + // let path = dirent.path().strip_prefix(prefix).unwrap(); + // if path.as_os_str().is_empty() { + // continue; + // } + // paths.push(normalize_path(path.to_str().unwrap())); + // } + // // sort the paths before returning in order + // // in order to be able to test. This represents + // // an artificial order in the results, but we will + // // still be able to confirm we have complete results + // paths.sort(); + // Ok(paths) + // } - let dirents = dirents.lock().unwrap(); - dirents.to_vec() - } + // fn walk_collect_entries_parallel(par_walker: WalkParallel) -> Vec { + // let dirents = Arc::new(Mutex::new(vec![])); + // par_walker.run(|| { + // let dirents = dirents.clone(); + // Box::new(move |result| { + // if let Ok(dirent) = result { + // dirents.lock().unwrap().push(dirent); + // } + // WalkState::Continue + // }) + // }); + + // let dirents = dirents.lock().unwrap(); + // dirents.to_vec() + // } - fn assert_paths_sequential(prefix: &Path, args: &Args, expected: &[&str]) -> Result<()> { - let got = walk_collect(prefix, args)?; - assert_eq!(got, mkpaths(expected), "single threaded"); - Ok(()) - } + // fn assert_paths_sequential(prefix: &Path, args: &Args, expected: &[&str]) -> Result<()> { + // let got = walk_collect(prefix, args)?; + // assert_eq!(got, mkpaths(expected), "single threaded"); + // Ok(()) + // } fn assert_file_paths_sequential(prefix: &Path, args: &Args, expected: &[&str]) -> Result<()> { let got = walk_file_collect(prefix, args)?; @@ -269,12 +286,22 @@ mod tests { Ok(()) } - fn assert_paths_parallel(prefix: &Path, args: &Args, expected: &[&str]) -> Result<()> { - let got = walk_collect_parallel(prefix, args)?; - assert_eq!(got, mkpaths(expected), "parallel"); + fn assert_file_paths_sequential_sorted( + prefix: &Path, + args: &Args, + expected: &[&str], + ) -> Result<()> { + let got = walk_file_collect_sorted(prefix, args)?; + assert_eq!(got, mkpaths(expected), "single threaded, files only"); Ok(()) } + // fn assert_paths_parallel(prefix: &Path, args: &Args, expected: &[&str]) -> Result<()> { + // let got = walk_collect_parallel(prefix, args)?; + // assert_eq!(got, mkpaths(expected), "parallel"); + // Ok(()) + // } + // ================== // Default execution // ================== @@ -294,50 +321,15 @@ mod tests { let args = mk_args(td.path(), None, false, false, false, false); - assert_paths_sequential( + assert_file_paths_sequential_sorted( td.path(), &args, &[ - "a", - "a/b", "a/b/ack.js", - "a/b/zoo.py", - "a/b/zip.py", - "a/b/foo.txt", - "a/b/c", - "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - assert_paths_parallel( - td.path(), - &args, - &[ - "a", - "a/b", - "a/b/ack.js", - "a/b/c", "a/b/foo.txt", "a/b/zip.py", "a/b/zoo.py", "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - - assert_file_paths_sequential( - td.path(), - &args, - &[ - "a/b/ack.js", - "a/b/zoo.py", - "a/b/zip.py", - "a/b/foo.txt", - "a/b/zoo.txt", "y/z/foo.md", ], )?; @@ -363,24 +355,7 @@ mod tests { let args = mk_args(td.path(), None, false, false, true, false); - assert_paths_sequential( - td.path(), - &args, - &[ - "a", - "a/b", - "a/b/ack.js", - "a/b/c", - "a/b/foo.txt", - "a/b/zip.py", - "a/b/zoo.py", - "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - + // preserve walker name output sorting here assert_file_paths_sequential( td.path(), &args, @@ -417,53 +392,16 @@ mod tests { let args = mk_args(td.path(), None, true, false, false, false); - assert_paths_sequential( + assert_file_paths_sequential_sorted( td.path(), &args, &[ - "a", - "a/b", "a/b/.hide.txt", // here is the hidden file "a/b/ack.js", - "a/b/zoo.py", - "a/b/zip.py", - "a/b/foo.txt", - "a/b/c", - "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - assert_paths_parallel( - td.path(), - &args, - &[ - "a", - "a/b", - "a/b/.hide.txt", // here is the hidden file - "a/b/ack.js", - "a/b/c", "a/b/foo.txt", "a/b/zip.py", "a/b/zoo.py", "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - - assert_file_paths_sequential( - td.path(), - &args, - &[ - "a/b/.hide.txt", // here is the hidden file - "a/b/ack.js", - "a/b/zoo.py", - "a/b/zip.py", - "a/b/foo.txt", - "a/b/zoo.txt", "y/z/foo.md", ], )?; @@ -489,25 +427,7 @@ mod tests { let args = mk_args(td.path(), None, true, false, true, false); - assert_paths_sequential( - td.path(), - &args, - &[ - "a", - "a/b", - "a/b/.hide.txt", // here is the hidden file - "a/b/ack.js", - "a/b/c", - "a/b/foo.txt", - "a/b/zip.py", - "a/b/zoo.py", - "a/b/zoo.txt", - "y", - "y/z", - "y/z/foo.md", - ], - )?; - + // preserve walker output sorting here assert_file_paths_sequential( td.path(), &args,