From 0eebb54432e36d79238f027284831aa038458dc8 Mon Sep 17 00:00:00 2001 From: niekdomi Date: Wed, 25 Feb 2026 15:36:34 +0100 Subject: [PATCH 1/2] Added include path option to white list files & paths --- crates/codebook-config/src/helpers.rs | 20 +++++++++++++++----- crates/codebook-config/src/lib.rs | 12 ++++++++++++ crates/codebook-config/src/settings.rs | 17 +++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/crates/codebook-config/src/helpers.rs b/crates/codebook-config/src/helpers.rs index 53d2b2c..a1621d0 100644 --- a/crates/codebook-config/src/helpers.rs +++ b/crates/codebook-config/src/helpers.rs @@ -90,16 +90,26 @@ pub(crate) fn dictionary_ids(settings: &ConfigSettings) -> Vec { } } -/// Determine whether a path should be ignored based on the configured glob patterns. -pub(crate) fn should_ignore_path(settings: &ConfigSettings, path: &Path) -> bool { - let path_str = path.to_string_lossy(); - settings.ignore_paths.iter().any(|pattern| { +fn match_pattern(pattern: &[String], path_str: &str) -> bool { + pattern.iter().any(|pattern| { Pattern::new(pattern) - .map(|p| p.matches(&path_str)) + .map(|p| p.matches(path_str)) .unwrap_or(false) }) } +/// Determine wheter a path should be included based on the configured glob patterns. +pub(crate) fn should_include_path(settings: &ConfigSettings, path: &Path) -> bool { + let path_str = path.to_string_lossy(); + match_pattern(&settings.include_paths, &path_str) +} + +/// Determine whether a path should be ignored based on the configured glob patterns. +pub(crate) fn should_ignore_path(settings: &ConfigSettings, path: &Path) -> bool { + let path_str = path.to_string_lossy(); + match_pattern(&settings.ignore_paths, &path_str) +} + /// Check if a word is explicitly allowed. pub(crate) fn is_allowed_word(settings: &ConfigSettings, word: &str) -> bool { let word = word.to_ascii_lowercase(); diff --git a/crates/codebook-config/src/lib.rs b/crates/codebook-config/src/lib.rs index 084b07e..80cadb6 100644 --- a/crates/codebook-config/src/lib.rs +++ b/crates/codebook-config/src/lib.rs @@ -26,6 +26,7 @@ pub trait CodebookConfig: Sync + Send + Debug { fn add_ignore(&self, file: &str) -> Result; fn get_dictionary_ids(&self) -> Vec; fn should_ignore_path(&self, path: &Path) -> bool; + fn should_include_path(&self, path: &Path) -> bool; fn is_allowed_word(&self, word: &str) -> bool; fn should_flag_word(&self, word: &str) -> bool; fn get_ignore_patterns(&self) -> Option>; @@ -496,6 +497,12 @@ impl CodebookConfig for CodebookConfigFile { helpers::should_ignore_path(&snapshot, path) } + /// Check if a path is included based on the effective configuration + fn should_include_path(&self, path: &Path) -> bool { + let snapshot = self.snapshot(); + helpers::should_include_path(&snapshot, path) + } + /// Check if a word is in the effective allowlist fn is_allowed_word(&self, word: &str) -> bool { let snapshot = self.snapshot(); @@ -580,6 +587,11 @@ impl CodebookConfig for CodebookConfigMemory { helpers::dictionary_ids(&snapshot) } + fn should_include_path(&self, path: &Path) -> bool { + let snapshot = self.snapshot(); + helpers::should_include_path(&snapshot, path) + } + fn should_ignore_path(&self, path: &Path) -> bool { let snapshot = self.snapshot(); helpers::should_ignore_path(&snapshot, path) diff --git a/crates/codebook-config/src/settings.rs b/crates/codebook-config/src/settings.rs index 9173b98..8a0b5e0 100644 --- a/crates/codebook-config/src/settings.rs +++ b/crates/codebook-config/src/settings.rs @@ -13,6 +13,10 @@ pub struct ConfigSettings { #[serde(default, skip_serializing_if = "Vec::is_empty")] pub flag_words: Vec, + /// Glob patterns for paths to include + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub include_paths: Vec, + /// Glob patterns for paths to ignore #[serde(default, skip_serializing_if = "Vec::is_empty")] pub ignore_paths: Vec, @@ -58,6 +62,7 @@ impl Default for ConfigSettings { dictionaries: vec![], words: Vec::new(), flag_words: Vec::new(), + include_paths: Vec::new(), ignore_paths: Vec::new(), ignore_patterns: Vec::new(), use_global: true, @@ -83,6 +88,8 @@ impl<'de> Deserialize<'de> for ConfigSettings { #[serde(default)] flag_words: Vec, #[serde(default)] + include_paths: Vec, + #[serde(default)] ignore_paths: Vec, #[serde(default)] ignore_patterns: Vec, @@ -97,6 +104,7 @@ impl<'de> Deserialize<'de> for ConfigSettings { dictionaries: to_lowercase_vec(helper.dictionaries), words: to_lowercase_vec(helper.words), flag_words: to_lowercase_vec(helper.flag_words), + include_paths: helper.include_paths, ignore_paths: helper.ignore_paths, ignore_patterns: helper.ignore_patterns, use_global: helper.use_global, @@ -112,6 +120,7 @@ impl ConfigSettings { self.dictionaries.extend(other.dictionaries); self.words.extend(other.words); self.flag_words.extend(other.flag_words); + self.include_paths.extend(other.include_paths); self.ignore_paths.extend(other.ignore_paths); self.ignore_patterns.extend(other.ignore_patterns); @@ -133,6 +142,7 @@ impl ConfigSettings { sort_and_dedup(&mut self.dictionaries); sort_and_dedup(&mut self.words); sort_and_dedup(&mut self.flag_words); + sort_and_dedup(&mut self.include_paths); sort_and_dedup(&mut self.ignore_paths); sort_and_dedup(&mut self.ignore_patterns); } @@ -154,6 +164,7 @@ mod tests { assert_eq!(config.dictionaries, Vec::::new()); assert_eq!(config.words, Vec::::new()); assert_eq!(config.flag_words, Vec::::new()); + assert_eq!(config.include_paths, Vec::::new()); assert_eq!(config.ignore_paths, Vec::::new()); assert_eq!(config.ignore_patterns, Vec::::new()); assert!(config.use_global); @@ -166,6 +177,7 @@ mod tests { dictionaries = ["EN_US", "en_GB"] words = ["CodeBook", "Rust"] flag_words = ["TODO", "FIXME"] + include_paths = ["src/**/*.rs", "lib/"] ignore_paths = ["**/*.md", "target/"] ignore_patterns = ["^```.*$", "^//.*$"] use_global = false @@ -176,6 +188,7 @@ mod tests { assert_eq!(config.dictionaries, vec!["en_us", "en_gb"]); assert_eq!(config.words, vec!["codebook", "rust"]); assert_eq!(config.flag_words, vec!["todo", "fixme"]); + assert_eq!(config.include_paths, vec!["src/**/*.rs", "lib/"]); assert_eq!(config.ignore_paths, vec!["**/*.md", "target/"]); // Don't test the exact order, just check that both elements are present @@ -225,6 +238,7 @@ mod tests { dictionaries: vec!["en_us".to_string()], words: vec!["codebook".to_string()], flag_words: vec!["todo".to_string()], + include_paths: vec!["src/".to_string()], ignore_paths: vec!["**/*.md".to_string()], ignore_patterns: vec!["^```.*$".to_string()], use_global: true, @@ -235,6 +249,7 @@ mod tests { dictionaries: vec!["en_gb".to_string(), "en_us".to_string()], words: vec!["rust".to_string()], flag_words: vec!["fixme".to_string()], + include_paths: vec!["lib/".to_string(), "src/".to_string()], ignore_paths: vec!["target/".to_string()], ignore_patterns: vec!["^//.*$".to_string()], use_global: false, @@ -247,6 +262,7 @@ mod tests { assert_eq!(base.dictionaries, vec!["en_gb", "en_us"]); assert_eq!(base.words, vec!["codebook", "rust"]); assert_eq!(base.flag_words, vec!["fixme", "todo"]); + assert_eq!(base.include_paths, vec!["lib/", "src/"]); assert_eq!(base.ignore_paths, vec!["**/*.md", "target/"]); // Don't test the exact order, just check that both elements are present @@ -294,6 +310,7 @@ mod tests { "rust".to_string(), ], flag_words: vec!["fixme".to_string(), "todo".to_string(), "fixme".to_string()], + include_paths: vec![], ignore_paths: vec![ "target/".to_string(), "**/*.md".to_string(), From 4c98e0e5673a5c72c99c70e932104bc41a5dab8e Mon Sep 17 00:00:00 2001 From: niekdomi Date: Wed, 25 Feb 2026 15:42:28 +0100 Subject: [PATCH 2/2] consistent order --- crates/codebook-config/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/codebook-config/src/lib.rs b/crates/codebook-config/src/lib.rs index 80cadb6..10ae3c0 100644 --- a/crates/codebook-config/src/lib.rs +++ b/crates/codebook-config/src/lib.rs @@ -491,18 +491,18 @@ impl CodebookConfig for CodebookConfigFile { helpers::dictionary_ids(&snapshot) } - /// Check if a path should be ignored based on the effective configuration - fn should_ignore_path(&self, path: &Path) -> bool { - let snapshot = self.snapshot(); - helpers::should_ignore_path(&snapshot, path) - } - /// Check if a path is included based on the effective configuration fn should_include_path(&self, path: &Path) -> bool { let snapshot = self.snapshot(); helpers::should_include_path(&snapshot, path) } + /// Check if a path should be ignored based on the effective configuration + fn should_ignore_path(&self, path: &Path) -> bool { + let snapshot = self.snapshot(); + helpers::should_ignore_path(&snapshot, path) + } + /// Check if a word is in the effective allowlist fn is_allowed_word(&self, word: &str) -> bool { let snapshot = self.snapshot();