diff --git a/README.md b/README.md index 3d32de8..c8316fa 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,18 @@ There are three modes cargo-sort can be used in: - Checks every crate in the workspace based on flags. Only one root may be given. * **-o or --order** - Specify an ordering of tables. All nested tables will be sorted and appear after the specified table. Any unspecified table will be after specified. + * **--config** + - Specify a custom path to the `tomlfmt.toml` configuration file. ### Config `cargo sort` uses a config file when formatting called `tomlfmt.toml`. This is optional and defaults will -be used if not found in the current working dir. +be used if not found in the current working dir. You can also specify a custom config path using the +`--config` flag: + +```bash +cargo sort --config .config/tomlfmt.toml +``` Here are the defaults when no `tomlfmt.toml` is found ```toml @@ -129,24 +136,24 @@ left off the tool will default to Cargo.toml. ```bash -cargo sort 1.0.0 -Devin R -Ensure Cargo.toml dependency tables are sorted. - -USAGE: - cargo-sort [FLAGS] [CWD] - -FLAGS: - -c, --check exit with non-zero if Cargo.toml is unsorted, overrides default behavior - -f, --format formats the given Cargo.toml according to tomlfmt.toml - -g, --grouped when sorting groups of key value pairs blank lines are kept - -h, --help Prints help information - -p, --print prints Cargo.toml, lexically sorted, to stdout - -V, --version Prints version information - -w, --workspace checks every crate in a workspace - -ARGS: - ... sets cwd, must contain a Cargo.toml file +Ensure Cargo.toml dependency tables are sorted + +Usage: cargo sort [OPTIONS] [CWD]... + +Arguments: + [CWD]... sets cwd, must contain a Cargo.toml file + +Options: + -c, --check Returns non-zero exit code if Cargo.toml is unsorted + -p, --print Prints Cargo.toml, lexically sorted, to stdout + -n, --no-format Skips formatting after sorting + --check-format Also returns non-zero exit code if formatting changes + -w, --workspace Checks every crate in a workspace + -g, --grouped Keep blank lines when sorting groups of key value pairs + -o, --order List the order tables should be written out + --config Path to a custom config file (tomlfmt.toml) + -h, --help Print help + -V, --version Print version ``` # Docker diff --git a/examp/custom_config.toml b/examp/custom_config.toml new file mode 100644 index 0000000..46f504d --- /dev/null +++ b/examp/custom_config.toml @@ -0,0 +1,6 @@ +# Custom config file for testing --config flag +always_trailing_comma = true +multiline_trailing_comma = false +space_around_eq = false +compact_arrays = true +indent_count = 2 diff --git a/src/main.rs b/src/main.rs index 5142e33..4888c36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,10 @@ pub struct Cli { /// (--order package,dependencies,features) #[arg(short, long, value_delimiter = ',')] pub order: Vec, + + /// Path to a custom config file (tomlfmt.toml) + #[arg(long, value_name = "PATH")] + pub config: Option, } fn write_red(highlight: &str, msg: S) -> IoResult<()> { @@ -222,16 +226,22 @@ fn _main() -> IoResult<()> { } } - let mut cwd = cwd.clone(); - cwd.push("tomlfmt.toml"); - let mut config = read_to_string(&cwd) - .or_else(|_err| { - cwd.pop(); - cwd.push(".tomlfmt.toml"); - read_to_string(&cwd) - }) - .unwrap_or_default() - .parse::()?; + let mut config = if let Some(config_path) = &cli.config { + read_to_string(config_path) + .map_err(|_| format!("config file not found: {}", config_path.display()))? + .parse::()? + } else { + let mut config_path = cwd.clone(); + config_path.push("tomlfmt.toml"); + read_to_string(&config_path) + .or_else(|_err| { + config_path.pop(); + config_path.push(".tomlfmt.toml"); + read_to_string(&config_path) + }) + .unwrap_or_default() + .parse::()? + }; if !cli.order.is_empty() { config.table_order = cli.order.clone(); @@ -261,6 +271,51 @@ fn main() { }); } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn cli_config_flag_parsing() { + let args = vec!["cargo-sort", "--config", "custom.toml"]; + let cli = ::try_parse_from(args).unwrap(); + assert_eq!(cli.config, Some(PathBuf::from("custom.toml"))); + } + + #[test] + fn cli_config_flag_with_other_flags() { + let args = vec!["cargo-sort", "--check", "--config", "/path/to/config.toml", "."]; + let cli = ::try_parse_from(args).unwrap(); + assert!(cli.check); + assert_eq!(cli.config, Some(PathBuf::from("/path/to/config.toml"))); + assert_eq!(cli.cwd, vec!["."]); + } + + #[test] + fn cli_without_config_flag() { + let args = vec!["cargo-sort", "--check", "."]; + let cli = ::try_parse_from(args).unwrap(); + assert_eq!(cli.config, None); + } + + #[test] + fn custom_config_loads_correctly() { + let config_content = read_to_string("examp/custom_config.toml").unwrap(); + let config: Config = config_content.parse().unwrap(); + assert!(config.always_trailing_comma); + assert!(!config.multiline_trailing_comma); + assert!(!config.space_around_eq); + assert!(config.compact_arrays); + assert_eq!(config.indent_count, 2); + } + + #[test] + fn config_error_on_missing_file() { + let result = read_to_string("nonexistent_config.toml"); + assert!(result.is_err()); + } +} + // #[test] // fn fuzzy_fail() { // for file in std::fs::read_dir("out/default/crashes").unwrap() {