diff --git a/Cargo.lock b/Cargo.lock index b35fa8e..0107fd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "const_format" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.3.1" @@ -2375,20 +2395,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "globset" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", - "serde", -] - [[package]] name = "governor" version = "0.7.0" @@ -2989,6 +2995,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -3662,7 +3677,6 @@ dependencies = [ "futures", "git2", "gix", - "globset", "indicatif", "indicatif-log-bridge", "inquire", @@ -3686,6 +3700,7 @@ dependencies = [ "toml", "toml_edit", "url", + "wax", "winreg", ] @@ -3792,6 +3807,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "pori" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a63d338dec139f56dacc692ca63ad35a6be6a797442479b55acd611d79e906" +dependencies = [ + "nom", +] + [[package]] name = "portable-atomic" version = "1.9.0" @@ -4814,7 +4838,7 @@ dependencies = [ "fnv", "fs4", "htmlescape", - "itertools", + "itertools 0.12.1", "levenshtein_automata", "log", "lru", @@ -4863,7 +4887,7 @@ checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" dependencies = [ "downcast-rs", "fastdivide", - "itertools", + "itertools 0.12.1", "serde", "tantivy-bitpacker", "tantivy-common", @@ -5488,6 +5512,20 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "wax" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d12a78aa0bab22d2f26ed1a96df7ab58e8a93506a3e20adb47c51a93b4e1357" +dependencies = [ + "const_format", + "itertools 0.11.0", + "nom", + "pori", + "regex", + "thiserror 1.0.69", +] + [[package]] name = "web-sys" version = "0.3.72" diff --git a/Cargo.toml b/Cargo.toml index 56bf5c9..5253124 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,7 +65,7 @@ url = { version = "2.5.3", features = ["serde"] } chrono = { version = "0.4.38", features = ["serde"] } sha2 = "0.10.8" tempfile = "3.14.0" -globset = { version = "0.4.15", features = ["serde1"] } +wax = { version = "0.6.0", default-features = false } fs-err = { version = "3.0.0", features = ["tokio"] } # TODO: remove this when gitoxide adds support for: committing, pushing, adding diff --git a/src/cli/commands/publish.rs b/src/cli/commands/publish.rs index 82c14dd..3774611 100644 --- a/src/cli/commands/publish.rs +++ b/src/cli/commands/publish.rs @@ -119,9 +119,13 @@ impl PublishCommand { _ => None, }; - let mut paths = matching_globs(project.package_dir(), manifest.includes.clone(), true) - .await - .context("failed to get included files")?; + let mut paths = matching_globs( + project.package_dir(), + manifest.includes.iter().map(|s| s.as_str()), + true, + ) + .await + .context("failed to get included files")?; if paths.insert(PathBuf::from(MANIFEST_FILE_NAME)) { println!( diff --git a/src/lib.rs b/src/lib.rs index 30c0545..2f2f0e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ use std::{ collections::{HashMap, HashSet}, path::{Path, PathBuf}, }; +use wax::Pattern; /// Downloading packages pub mod download; @@ -192,7 +193,12 @@ impl Project { errors::WorkspaceMembersError::ManifestDeser(dir.to_path_buf(), Box::new(e)) })?; - let members = matching_globs(dir, manifest.workspace_members, false).await?; + let members = matching_globs( + dir, + manifest.workspace_members.iter().map(|s| s.as_str()), + false, + ) + .await?; Ok(stream! { for path in members { @@ -210,40 +216,40 @@ impl Project { } /// Gets all matching paths in a directory -pub async fn matching_globs>( +pub async fn matching_globs<'a, P: AsRef, I: IntoIterator>( dir: P, - members: Vec, + globs: I, relative: bool, ) -> Result, errors::MatchingGlobsError> { - let mut positive_globset = globset::GlobSetBuilder::new(); - let mut negative_globset = globset::GlobSetBuilder::new(); + let (negative_globs, positive_globs): (Vec<&str>, Vec<&str>) = + globs.into_iter().partition(|glob| glob.starts_with('!')); - for pattern in members { - match pattern.glob().strip_prefix('!') { - Some(pattern) => negative_globset.add(globset::Glob::new(pattern)?), - None => positive_globset.add(pattern), - }; - } + let negative_globs = wax::any( + negative_globs + .into_iter() + .map(|glob| wax::Glob::new(&glob[1..])) + .collect::, _>>()?, + )?; + let positive_globs = wax::any( + positive_globs + .into_iter() + .map(wax::Glob::new) + .collect::, _>>()?, + )?; - let positive_globset = positive_globset.build()?; - let negative_globset = negative_globset.build()?; - - let mut read_dirs = vec![fs::read_dir(dir.as_ref().to_path_buf())]; + let mut read_dirs = vec![fs::read_dir(dir.as_ref().to_path_buf()).await?]; let mut paths = HashSet::new(); - while let Some(read_dir) = read_dirs.pop() { - let mut read_dir = read_dir.await?; + while let Some(mut read_dir) = read_dirs.pop() { while let Some(entry) = read_dir.next_entry().await? { let path = entry.path(); if entry.file_type().await?.is_dir() { - read_dirs.push(fs::read_dir(path)); - continue; + read_dirs.push(fs::read_dir(&path).await?); } let relative_path = path.strip_prefix(dir.as_ref()).unwrap(); - if positive_globset.is_match(relative_path) && !negative_globset.is_match(relative_path) - { + if positive_globs.is_match(relative_path) && !negative_globs.is_match(relative_path) { paths.insert(if relative { relative_path.to_path_buf() } else { @@ -349,8 +355,8 @@ pub mod errors { #[error("error interacting with the filesystem")] Io(#[from] std::io::Error), - /// An error occurred while globbing - #[error("error globbing")] - Globbing(#[from] globset::Error), + /// An error occurred while building a glob + #[error("error building glob")] + BuildGlob(#[from] wax::BuildError), } } diff --git a/src/main.rs b/src/main.rs index 1e6fb0c..0a3e592 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,9 +133,13 @@ async fn run() -> anyhow::Result<()> { return Ok(HashSet::new()); } - matching_globs(path, manifest.workspace_members, false) - .await - .context("failed to get workspace members") + matching_globs( + path, + manifest.workspace_members.iter().map(|s| s.as_str()), + false, + ) + .await + .context("failed to get workspace members") } while let Some(path) = current_path { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 5d6b934..6230b11 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -61,7 +61,7 @@ pub struct Manifest { pub overrides: BTreeMap, /// The files to include in the package #[serde(default)] - pub includes: Vec, + pub includes: Vec, /// The patches to apply to packages #[cfg(feature = "patches")] #[serde(default, skip_serializing)] @@ -74,7 +74,7 @@ pub struct Manifest { pub pesde_version: Option, /// A list of globs pointing to workspace members' directories #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub workspace_members: Vec, + pub workspace_members: Vec, /// The Roblox place of this project #[serde(default, skip_serializing)] pub place: BTreeMap,