diff --git a/docs/reference.md b/docs/reference.md index a9fed8f24..13e1625db 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -14,6 +14,8 @@ Configuration is read from the following (in precedence order) | Field | Argument | Format | Description | |------------------------|-------------------|--------|-------------| +| files.binary | --binary | bool | Check binary files as text | +| files.extend-exclude | --exclude | list of strings | Typos-specific ignore globs (gitignore syntax) | | files.ignore-hidden | --hidden | bool | Skip hidden files and directories. | | files.ignore-files | --ignore | bool | Respect ignore files. | | files.ignore-dot | --ignore-dot | bool | Respect .ignore files. | diff --git a/src/bin/typos-cli/args.rs b/src/bin/typos-cli/args.rs index 5f170d9bc..7941c802c 100644 --- a/src/bin/typos-cli/args.rs +++ b/src/bin/typos-cli/args.rs @@ -200,6 +200,10 @@ impl ConfigArgs { #[derive(Debug, StructOpt)] #[structopt(rename_all = "kebab-case")] pub(crate) struct WalkArgs { + #[structopt(long)] + /// Ignore all files & directories matching the pattern. + exclude: Vec, + #[structopt(long, overrides_with("no-hidden"))] /// Search hidden files and directories. hidden: bool, @@ -240,6 +244,7 @@ pub(crate) struct WalkArgs { impl WalkArgs { pub fn to_config(&self) -> config::Walk { config::Walk { + extend_exclude: self.exclude.clone(), ignore_hidden: self.ignore_hidden(), ignore_files: self.ignore_files(), ignore_dot: self.ignore_dot(), diff --git a/src/bin/typos-cli/main.rs b/src/bin/typos-cli/main.rs index 78d816336..d9dc6674e 100644 --- a/src/bin/typos-cli/main.rs +++ b/src/bin/typos-cli/main.rs @@ -196,6 +196,16 @@ fn run_checks( .git_ignore(walk_policy.ignore_vcs()) .git_exclude(walk_policy.ignore_vcs()) .parents(walk_policy.ignore_parent()); + if !walk_policy.extend_exclude.is_empty() { + let mut overrides = ignore::overrides::OverrideBuilder::new("."); + for pattern in walk_policy.extend_exclude.iter() { + overrides + .add(&format!("!{}", pattern)) + .with_code(proc_exit::Code::CONFIG_ERR)?; + } + let overrides = overrides.build().with_code(proc_exit::Code::CONFIG_ERR)?; + walk.overrides(overrides); + } // HACK: Diff doesn't handle mixing content let output_reporter = if args.diff { diff --git a/src/config.rs b/src/config.rs index 8a7453cb4..2290093ac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -61,6 +61,7 @@ impl Config { #[serde(deny_unknown_fields, default)] #[serde(rename_all = "kebab-case")] pub struct Walk { + pub extend_exclude: Vec, /// Skip hidden files and directories. pub ignore_hidden: Option, /// Respect ignore files. @@ -79,6 +80,7 @@ impl Walk { pub fn from_defaults() -> Self { let empty = Self::default(); Self { + extend_exclude: empty.extend_exclude.clone(), ignore_hidden: Some(empty.ignore_hidden()), ignore_files: Some(true), ignore_dot: Some(empty.ignore_dot()), @@ -89,6 +91,8 @@ impl Walk { } pub fn update(&mut self, source: &Walk) { + self.extend_exclude + .extend(source.extend_exclude.iter().cloned()); if let Some(source) = source.ignore_hidden { self.ignore_hidden = Some(source); } @@ -114,6 +118,10 @@ impl Walk { } } + pub fn extend_exclude(&self) -> &[String] { + &self.extend_exclude + } + pub fn ignore_hidden(&self) -> bool { self.ignore_hidden.unwrap_or(true) }