Skip to content

Commit

Permalink
release: 0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
joshstoik1 committed Oct 23, 2024
2 parents 29054fb + 5700d02 commit d1371f3
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 20 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@



## [0.10.0](https://github.com/Blobfolio/dowser/releases/tag/v0.10.0) - 2024-10-22

### New

* `Dowser::read_paths_from_file`

### Changed

* Bump MSRV to `1.81`
* Miscellaneous code cleanup and lints



## [0.9.3](https://github.com/Blobfolio/dowser/releases/tag/v0.9.3) - 2024-09-05

### Changed
Expand Down
6 changes: 3 additions & 3 deletions CREDITS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Project Dependencies
Package: dowser
Version: 0.9.3
Generated: 2024-09-05 19:25:18 UTC
Version: 0.10.0
Generated: 2024-10-23 04:07:24 UTC

| Package | Version | Author(s) | License |
| ---- | ---- | ---- | ---- |
| [ahash](https://github.com/tkaitchuck/ahash) | 0.8.11 | [Tom Kaitchuck](mailto:[email protected]) | Apache-2.0 or MIT |
| [cfg-if](https://github.com/alexcrichton/cfg-if) | 1.0.0 | [Alex Crichton](mailto:[email protected]) | Apache-2.0 or MIT |
| [dactyl](https://github.com/Blobfolio/dactyl) | 0.7.3 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL |
| [dactyl](https://github.com/Blobfolio/dactyl) | 0.7.4 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL |
| [zerocopy](https://github.com/google/zerocopy) | 0.7.35 | [Joshua Liebow-Feeser](mailto:[email protected]) | Apache-2.0, BSD-2-Clause, or MIT |
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "dowser"
version = "0.9.3"
version = "0.10.0"
authors = ["Blobfolio, LLC. <[email protected]>"]
edition = "2021"
rust-version = "1.72"
rust-version = "1.81"
description = "A recursive, canonicalizing file finding library for Unix."
license = "WTFPL"
repository = "https://github.com/Blobfolio/dowser"
Expand Down
27 changes: 16 additions & 11 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
# Dowser: Obligatory `DirEntry` Replacement.
*/

use ahash::AHasher;
use std::{
fs::DirEntry,
hash::Hasher,
io::Result,
path::{
Path,
Expand All @@ -15,6 +13,18 @@ use std::{



/// # Static Hasher.
///
/// This is used for cheap collision detection. No need to get fancy with it.
const AHASHER: ahash::RandomState = ahash::RandomState::with_seeds(
0x8596_cc44_bef0_1aa0,
0x98d4_0948_da60_19ae,
0x49f1_3013_c503_a6aa,
0xc4d7_82ff_3c9f_7bef,
);



/// # File Entry.
///
/// This holds a pre-computed hash, whether or not the path points to a
Expand Down Expand Up @@ -69,27 +79,22 @@ impl Entry {

#[cfg(unix)]
#[must_use]
#[inline]
/// # Hash Path.
///
/// Since all paths are canonical, we can test for uniqueness by simply
/// hashing them.
pub(super) fn hash_path(path: &Path) -> u64 {
use std::os::unix::ffi::OsStrExt;
let mut hasher = AHasher::default();
hasher.write(path.as_os_str().as_bytes());
hasher.finish()
AHASHER.hash_one(path.as_os_str().as_bytes())
}

#[cfg(not(unix))]
#[must_use]
#[inline]
/// # Hash Path.
///
/// Since all paths are canonical, we can test for uniqueness by simply
/// hashing them.
pub(super) fn hash_path(path: &Path) -> u64 {
use std::hash::Hash;
let mut hasher = AHasher::default();
path.hash(&mut hasher);
hasher.finish()
}
pub(super) fn hash_path(path: &Path) -> u64 { AHASHER.hash_one(path) }
}
2 changes: 1 addition & 1 deletion src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ impl Extension {

/// # Codegen Helpers.
impl Extension {
#[allow(clippy::needless_doctest_main)] // For demonstration.
#[expect(clippy::needless_doctest_main, reason = "For demonstration.")]
#[must_use]
/// # Codegen Helper.
///
Expand Down
101 changes: 101 additions & 0 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,56 @@ impl Dowser {
}
}

impl Dowser {
/// # Load Paths From File.
///
/// Queue up multiple file and/or directory paths from a text file, one
/// entry per line.
///
/// Lines are trimmed and ignored if empty, but otherwise resolved the
/// same as if passed directly to methods like [`Dowser::with_path`], i.e.
/// relative to the current working directory (not the text file itself).
///
/// For that reason, it is recommended that all paths stored in text files
/// be absolute to avoid any ambiguity.
///
/// ## Examples
///
/// ```no_run
/// use dowser::Dowser;
/// use std::path::PathBuf;
///
/// // Read the paths from list.txt.
/// let mut crawler = Dowser::default();
/// crawler.read_paths_from_file("list.txt").unwrap();
///
/// // Crunch into a vec.
/// let files: Vec::<PathBuf> = crawler.collect();
/// ```
///
/// ## Errors
///
/// This method will bubble up any errors encountered while trying to read
/// the text file.
pub fn read_paths_from_file<P: AsRef<Path>>(&mut self, src: P)
-> Result<(), std::io::Error> {
let raw = std::fs::read_to_string(src)?;
for line in raw.lines() {
let line = line.trim();
if ! line.is_empty() {
if let Some(e) = Entry::from_path(line) {
if self.seen.insert(e.hash) {
if e.is_dir { self.dirs.push(e.path); }
else { self.files.push(e.path); }
}
}
}
}

Ok(())
}
}

impl Dowser {
#[must_use]
#[inline]
Expand Down Expand Up @@ -581,4 +631,55 @@ mod tests {
let _res = Dowser::default().without_paths([path]);
let _res = Dowser::default().without_paths(&[path.to_path_buf()]);
}

#[test]
fn t_read_paths_from_file() {
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Write;

// Find the temporary directory.
let tmp = std::env::temp_dir();
if ! tmp.is_dir() { return; }

// Declare a few paths to test crawl.
let asset_dir = std::fs::canonicalize("tests/assets")
.expect("Missing dowser assets dir");
let link01 = std::fs::canonicalize("tests/links/01")
.expect("Missing dowser links/01");

// Mock up a text file containing those entries.
let text_file = tmp.join("dowser.test.txt");
let text = format!(
"{}\n{}\n",
asset_dir.as_os_str().to_str().expect("Asset dir cannot be represented as a string."),
link01.as_os_str().to_str().expect("Link01 cannot be represented as a string."),
);

// Try to save the text file.
let res = File::create(&text_file)
.and_then(|mut file|
file.write_all(text.as_bytes()).and_then(|()| file.flush())
);

// Not all environments will allow that; only proceed with the testing
// if it worked.
if res.is_ok() && text_file.is_file() {
// Feed the text file to dowser, collect the results.
let mut crawl = Dowser::default();
crawl.read_paths_from_file(&text_file)
.expect("Loading text file failed.");
let found: BTreeSet<PathBuf> = crawl.collect();

// We don't need the text file anymore.
let _res = std::fs::remove_file(text_file);

// It should have found the following!
assert!(found.len() == 4);
assert!(found.contains(&link01));
assert!(found.contains(&asset_dir.join("file.txt")));
assert!(found.contains(&asset_dir.join("functioning.JPEG")));
assert!(found.contains(&asset_dir.join("is-executable.sh")));
}
}
}
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ assert_eq!(files1.len(), files2.len());
#![forbid(unsafe_code)]

#![deny(
// TODO: clippy::allow_attributes_without_reason,
clippy::allow_attributes_without_reason,
clippy::correctness,
unreachable_pub,
)]
Expand All @@ -86,7 +86,7 @@ assert_eq!(files1.len(), files2.len());
clippy::perf,
clippy::style,
// TODO: clippy::allow_attributes,
clippy::allow_attributes,
clippy::clone_on_ref_ptr,
clippy::create_dir,
clippy::filetype_is_file,
Expand Down Expand Up @@ -120,7 +120,7 @@ assert_eq!(files1.len(), files2.len());
unused_import_braces,
)]

#![allow(clippy::redundant_pub_crate)] // Unresolvable.
#![expect(clippy::redundant_pub_crate, reason = "Unresolvable.")]

mod entry;
mod ext;
Expand Down

0 comments on commit d1371f3

Please sign in to comment.