diff --git a/Cargo.lock b/Cargo.lock index 6eaaa86..ac05bd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -364,6 +364,12 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "either" version = "1.13.0" @@ -1072,6 +1078,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro2" version = "1.0.89" @@ -1483,6 +1499,7 @@ dependencies = [ "indicatif", "nonempty", "pest", + "pretty_assertions", "tokio", "tracing", "tracing-log", @@ -2344,6 +2361,12 @@ version = "0.52.6" source = "registry+/~https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 2cc7129..bcfc3bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ tokio = { version = "1.41.0", features = ["full"] } tracing-log = "0.2.0" indicatif = "0.17.8" clap-verbosity-flag = "2.2.2" +pretty_assertions = "1.4.1" diff --git a/src/commands/format.rs b/src/commands/format.rs index d79f11e..68c59ac 100644 --- a/src/commands/format.rs +++ b/src/commands/format.rs @@ -15,6 +15,7 @@ use clap::Parser; use codespan_reporting::files::SimpleFile; use codespan_reporting::term::emit; use colored::Colorize; +use pretty_assertions::StrComparison; use walkdir::WalkDir; use wdl::ast::Document; use wdl::ast::Node; @@ -70,8 +71,12 @@ pub struct FormatArgs { pub indentation_size: Option, /// Overwrite the WDL documents with the formatted versions - #[arg(long)] + #[arg(long, conflicts_with = "check")] pub overwrite: bool, + + /// Check if files are formatted correctly and print diff if not + #[arg(long, conflicts_with = "overwrite")] + pub check: bool, } /// Reads source from the given path. @@ -103,14 +108,16 @@ fn format_document( overwrite: bool, report_mode: Mode, no_color: bool, + check: bool, ) -> Result { if path.to_str() != Some("-") { + let action = if check { "checking" } else { "formatting" }; println!( - "{formatting} `{path}`", - formatting = if no_color { - "formatting".normal() + "{action_colored} `{path}`", + action_colored = if no_color { + action.normal() } else { - "formatting".green() + action.green() }, path = path.display() ); @@ -140,6 +147,15 @@ fn format_document( let formatter = Formatter::new(config); let formatted = formatter.format(&document)?; + if check { + if formatted != source { + print!("{}", StrComparison::new(&source, &formatted)); + return Ok(1); + } + println!("`{path}` is formatted correctly", path = path.display()); + return Ok(0); + } + if overwrite { fs::write(path, formatted) .with_context(|| format!("failed to write `{path}`", path = path.display()))?; @@ -172,8 +188,8 @@ pub fn format(args: FormatArgs) -> Result<()> { let mut diagnostics = 0; if args.path.to_str() != Some("-") && args.path.is_dir() { - if !args.overwrite { - bail!("formatting a directory requires the `--overwrite` option"); + if !args.overwrite && !args.check { + bail!("formatting a directory requires the `--overwrite` or `--check` option"); } for entry in WalkDir::new(&args.path) { @@ -194,6 +210,7 @@ pub fn format(args: FormatArgs) -> Result<()> { args.overwrite, args.report_mode, args.no_color, + args.check, )?; } } else { @@ -203,6 +220,7 @@ pub fn format(args: FormatArgs) -> Result<()> { args.overwrite, args.report_mode, args.no_color, + args.check, )?; }