diff --git a/CHANGELOG.md b/CHANGELOG.md index 072167e..ff9298e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Print that no updates are available in `outdated` command by @daimond113 +- Support negated globs in `workspace_members` field by @daimond113 ## [0.5.0-rc.12] - 2024-11-22 ### Added diff --git a/src/lib.rs b/src/lib.rs index 7c17047..941b72c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ use std::{ collections::{HashMap, HashSet}, path::{Path, PathBuf}, }; +use tokio::task::spawn_blocking; /// Downloading packages pub mod download; @@ -192,15 +193,29 @@ impl Project { errors::WorkspaceMembersError::ManifestDeser(dir.to_path_buf(), Box::new(e)) })?; - let members = manifest - .workspace_members - .into_iter() - .map(|glob| dir.join(glob)) - .map(|path| glob::glob(&path.as_os_str().to_string_lossy())) - .collect::, _>>()? - .into_iter() - .flat_map(|paths| paths.into_iter()) - .collect::, _>>()?; + let mut members = HashSet::new(); + + for glob in &manifest.workspace_members { + let is_removal = glob.starts_with('!'); + let glob = if is_removal { &glob[1..] } else { glob }; + + let path = dir.join(glob); + let paths = spawn_blocking(move || { + glob::glob(&path.as_os_str().to_string_lossy())? + .collect::, _>>() + .map_err(errors::WorkspaceMembersError::Globbing) + }) + .await + .unwrap()?; + + if is_removal { + for path in paths { + members.remove(&path); + } + } else { + members.extend(paths); + } + } Ok(stream! { for path in members {