Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 26 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. Useful for projects that organize config files in a dedicated directory (e.g., `.config/tomlfmt.toml`).

### 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
Expand Down Expand Up @@ -129,24 +136,24 @@ left off the tool will default to Cargo.toml.


```bash
cargo sort 1.0.0
Devin R <[email protected]>
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:
<CWD>... 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 <ORDER> List the order tables should be written out
--config <PATH> Path to a custom config file (tomlfmt.toml)
-h, --help Print help
-V, --version Print version
```

# Docker
Expand Down
6 changes: 6 additions & 0 deletions examp/custom_config.toml
Original file line number Diff line number Diff line change
@@ -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
75 changes: 65 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ pub struct Cli {
/// (--order package,dependencies,features)
#[arg(short, long, value_delimiter = ',')]
pub order: Vec<String>,

/// Path to a custom config file (tomlfmt.toml)
#[arg(long, value_name = "PATH")]
pub config: Option<PathBuf>,
}

fn write_red<S: Display>(highlight: &str, msg: S) -> IoResult<()> {
Expand Down Expand Up @@ -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::<Config>()?;
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::<Config>()?
} 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::<Config>()?
};

if !cli.order.is_empty() {
config.table_order = cli.order.clone();
Expand Down Expand Up @@ -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 = <Cli as clap::Parser>::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 = <Cli as clap::Parser>::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 = <Cli as clap::Parser>::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() {
Expand Down