From 70163fae61572378bfdb7d4efdd5607b77423fa2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 13:37:56 -0600 Subject: [PATCH 1/6] docs(args): Clarify command line arguments --- src/args.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/args.rs b/src/args.rs index 4a3398a..047ae2c 100644 --- a/src/args.rs +++ b/src/args.rs @@ -43,7 +43,7 @@ impl Default for Format { )] pub(crate) struct Args { #[structopt(parse(from_os_str), default_value = ".")] - /// Paths to check + /// Paths to check with `-` for stdin pub(crate) path: Vec, #[structopt(short = "c", long = "config")] @@ -59,19 +59,19 @@ pub(crate) struct Args { pub(crate) diff: bool, #[structopt(long, short = "w")] - /// Write corrections out + /// Write fixes out pub(crate) write_changes: bool, #[structopt(long)] - /// Print each file that would be spellchecked. + /// Debug: Print each file that would be spellchecked. pub(crate) files: bool, #[structopt(long)] - /// Print each identifier that would be spellchecked. + /// Debug: Print each identifier that would be spellchecked. pub(crate) identifiers: bool, #[structopt(long)] - /// Print each word that would be spellchecked. + /// Debug: Print each word that would be spellchecked. pub(crate) words: bool, #[structopt(flatten)] From f27282fbc01d1f8415d97c7d48cc7689c5de5888 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 14:54:44 -0600 Subject: [PATCH 2/6] docs(args): Clarify what args are esclusive --- src/args.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/args.rs b/src/args.rs index 047ae2c..7236652 100644 --- a/src/args.rs +++ b/src/args.rs @@ -41,6 +41,7 @@ impl Default for Format { setting = structopt::clap::AppSettings::DeriveDisplayOrder, setting = structopt::clap::AppSettings::DontCollapseArgsInUsage )] +#[structopt(group = structopt::clap::ArgGroup::with_name("mode").multiple(false))] pub(crate) struct Args { #[structopt(parse(from_os_str), default_value = ".")] /// Paths to check with `-` for stdin @@ -54,23 +55,23 @@ pub(crate) struct Args { /// Ignore implicit configuration files. pub(crate) isolated: bool, - #[structopt(long)] + #[structopt(long, group = "mode")] /// Print a diff of what would change pub(crate) diff: bool, - #[structopt(long, short = "w")] + #[structopt(long, short = "w", group = "mode")] /// Write fixes out pub(crate) write_changes: bool, - #[structopt(long)] + #[structopt(long, group = "mode")] /// Debug: Print each file that would be spellchecked. pub(crate) files: bool, - #[structopt(long)] + #[structopt(long, group = "mode")] /// Debug: Print each identifier that would be spellchecked. pub(crate) identifiers: bool, - #[structopt(long)] + #[structopt(long, group = "mode")] /// Debug: Print each word that would be spellchecked. pub(crate) words: bool, From 5db9a8e1c96abfaf6f9cddca1407857948136e00 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 16:15:31 -0600 Subject: [PATCH 3/6] docs(config): Make config more discoverable --- src/args.rs | 4 ++++ src/main.rs | 60 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/args.rs b/src/args.rs index 7236652..bf7af75 100644 --- a/src/args.rs +++ b/src/args.rs @@ -75,6 +75,10 @@ pub(crate) struct Args { /// Debug: Print each word that would be spellchecked. pub(crate) words: bool, + #[structopt(long, group = "mode")] + /// Write the current configuration to file. + pub(crate) dump_config: Option, + #[structopt(flatten)] pub(crate) overrides: FileArgs, diff --git a/src/main.rs b/src/main.rs index a5a5d89..73c142e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,13 +34,40 @@ fn run() -> proc_exit::ExitResult { }; init_logging(args.verbose.log_level()); + + if let Some(output_path) = args.dump_config.as_ref() { + run_dump_config(&args, output_path) + } else { + run_checks(&args) + } +} + +fn run_dump_config(args: &args::Args, output_path: &std::path::Path) -> proc_exit::ExitResult { let global_cwd = std::env::current_dir()?; - let config = if let Some(path) = args.custom_config.as_ref() { - config::Config::from_file(path).with_code(proc_exit::Code::CONFIG_ERR)? + let path = &args.path[0]; + let path = if path == std::path::Path::new("-") { + path.to_owned() } else { - config::Config::default() + path.canonicalize().with_code(proc_exit::Code::USAGE_ERR)? }; + let cwd = if path == std::path::Path::new("-") { + global_cwd.as_path() + } else if path.is_file() { + path.parent().unwrap() + } else { + path.as_path() + }; + + let config = load_config(cwd, &args).with_code(proc_exit::Code::CONFIG_ERR)?; + let output = toml::to_string_pretty(&config).with_code(proc_exit::Code::FAILURE)?; + std::fs::write(output_path, &output)?; + + Ok(()) +} + +fn run_checks(args: &args::Args) -> proc_exit::ExitResult { + let global_cwd = std::env::current_dir()?; let mut typos_found = false; let mut errors_found = false; @@ -57,15 +84,7 @@ fn run() -> proc_exit::ExitResult { } else { path.as_path() }; - - let mut config = config.clone(); - if !args.isolated { - let derived = config::Config::derive(cwd).with_code(proc_exit::Code::CONFIG_ERR)?; - config.update(&derived); - } - config.update(&args.config); - config.default.update(&args.overrides); - let config = config; + let config = load_config(cwd, &args).with_code(proc_exit::Code::CONFIG_ERR)?; let parser = typos::tokens::TokenizerBuilder::new() .ignore_hex(config.default.ignore_hex()) @@ -194,3 +213,20 @@ fn init_logging(level: Option) { builder.init(); } } + +fn load_config(cwd: &std::path::Path, args: &args::Args) -> Result { + let mut config = config::Config::default(); + + if let Some(path) = args.custom_config.as_ref() { + config.update(&config::Config::from_file(path)?); + } + if !args.isolated { + let derived = config::Config::derive(cwd)?; + config.update(&derived); + } + + config.update(&args.config); + config.default.update(&args.overrides); + + Ok(config) +} From ecb32a674a8cdd5eba8d1e0d8de6f16eb2fce815 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 16:16:01 -0600 Subject: [PATCH 4/6] fix(config): Merge custom config over repo config Custom config, like args, is more mutable, so it should be respected more. --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 73c142e..ad506a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -217,13 +217,13 @@ fn init_logging(level: Option) { fn load_config(cwd: &std::path::Path, args: &args::Args) -> Result { let mut config = config::Config::default(); - if let Some(path) = args.custom_config.as_ref() { - config.update(&config::Config::from_file(path)?); - } if !args.isolated { let derived = config::Config::derive(cwd)?; config.update(&derived); } + if let Some(path) = args.custom_config.as_ref() { + config.update(&config::Config::from_file(path)?); + } config.update(&args.config); config.default.update(&args.overrides); From 13a93ee8d1a297dddf666fc1dcf0fa4820d2d3cf Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 16:34:18 -0600 Subject: [PATCH 5/6] fix(config): Provide all field defaults --- src/config.rs | 36 ++++++++++++++++++++++++++++++++++++ src/main.rs | 4 +++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 5f4e613..a9b8cbc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -118,6 +118,13 @@ impl Config { Ok(content) } + pub fn from_defaults() -> Self { + Self { + files: Walk::from_defaults(), + default: FileConfig::from_defaults(), + } + } + pub fn derive(cwd: &std::path::Path) -> Result { if let Some(path) = find_project_file(cwd, &["typos.toml", "_typos.toml", ".typos.toml"]) { Self::from_file(&path) @@ -160,6 +167,19 @@ pub struct Walk { } impl Walk { + pub fn from_defaults() -> Self { + let empty = Self::default(); + Self { + binary: Some(empty.binary()), + ignore_hidden: Some(empty.ignore_hidden()), + ignore_files: Some(true), + ignore_dot: Some(empty.ignore_dot()), + ignore_vcs: Some(empty.ignore_vcs()), + ignore_global: Some(empty.ignore_global()), + ignore_parent: Some(empty.ignore_parent()), + } + } + pub fn update(&mut self, source: &dyn WalkSource) { if let Some(source) = source.binary() { self.binary = Some(source); @@ -264,6 +284,22 @@ pub struct FileConfig { } impl FileConfig { + pub fn from_defaults() -> Self { + let empty = Self::default(); + FileConfig { + check_filename: Some(empty.check_filename()), + check_file: Some(empty.check_file()), + ignore_hex: Some(empty.ignore_hex()), + identifier_leading_digits: Some(empty.identifier_leading_digits()), + identifier_leading_chars: Some(empty.identifier_leading_chars().to_owned()), + identifier_include_digits: Some(empty.identifier_include_digits()), + identifier_include_chars: Some(empty.identifier_include_chars().to_owned()), + locale: Some(empty.locale()), + extend_identifiers: Default::default(), + extend_words: Default::default(), + } + } + pub fn update(&mut self, source: &dyn FileSource) { if let Some(source) = source.check_filename() { self.check_filename = Some(source); diff --git a/src/main.rs b/src/main.rs index ad506a3..1a38514 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,7 +60,9 @@ fn run_dump_config(args: &args::Args, output_path: &std::path::Path) -> proc_exi }; let config = load_config(cwd, &args).with_code(proc_exit::Code::CONFIG_ERR)?; - let output = toml::to_string_pretty(&config).with_code(proc_exit::Code::FAILURE)?; + let mut defaulted_config = config::Config::from_defaults(); + defaulted_config.update(&config); + let output = toml::to_string_pretty(&defaulted_config).with_code(proc_exit::Code::FAILURE)?; std::fs::write(output_path, &output)?; Ok(()) From dbac2eff4a653c86d8c4b519a566999acff40368 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Jan 2021 19:15:05 -0600 Subject: [PATCH 6/6] feat(config): Use '-' to dump config to stdout --- src/args.rs | 2 +- src/main.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/args.rs b/src/args.rs index bf7af75..503e37c 100644 --- a/src/args.rs +++ b/src/args.rs @@ -76,7 +76,7 @@ pub(crate) struct Args { pub(crate) words: bool, #[structopt(long, group = "mode")] - /// Write the current configuration to file. + /// Write the current configuration to file with `-` for stdout pub(crate) dump_config: Option, #[structopt(flatten)] diff --git a/src/main.rs b/src/main.rs index 1a38514..b8095b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,7 +63,11 @@ fn run_dump_config(args: &args::Args, output_path: &std::path::Path) -> proc_exi let mut defaulted_config = config::Config::from_defaults(); defaulted_config.update(&config); let output = toml::to_string_pretty(&defaulted_config).with_code(proc_exit::Code::FAILURE)?; - std::fs::write(output_path, &output)?; + if output_path == std::path::Path::new("-") { + std::io::stdout().write_all(output.as_bytes())?; + } else { + std::fs::write(output_path, &output)?; + } Ok(()) }