diff --git a/Cargo.lock b/Cargo.lock index 8654149..6d68d2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,9 +49,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -70,9 +70,9 @@ checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.57" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -318,9 +318,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.57" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -332,9 +332,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" @@ -560,9 +560,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "env_filter" -version = "0.1.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", @@ -869,9 +869,9 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jiff" -version = "0.2.19" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89a5b5e10d5a9ad6e5d1f4bd58225f655d6fe9767575a5e8ac5a6fe64e04495" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "log", @@ -882,9 +882,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.19" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff7a39c8862fc1369215ccf0a8f12dd4598c7f6484704359f0351bd617034dbf" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", @@ -915,9 +915,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.180" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libloading" @@ -952,9 +952,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litrs" @@ -1004,9 +1004,9 @@ checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miette" @@ -1290,7 +1290,7 @@ dependencies = [ [[package]] name = "nufmt" -version = "0.1.0" +version = "0.1.1" dependencies = [ "clap", "criterion", @@ -1596,9 +1596,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -1611,9 +1611,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -1750,9 +1750,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags", "errno", @@ -1960,9 +1960,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -1994,9 +1994,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", "getrandom 0.3.4", diff --git a/Cargo.toml b/Cargo.toml index c7b9581..f1a4560 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nufmt" -version = "0.1.0" +version = "0.1.1" edition = "2021" authors = ["The NuShell Contributors"] license = "MIT" @@ -14,8 +14,8 @@ categories = ["command-line-utilities"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.5.56", optional = true, features = ["unicode", "derive"] } -env_logger = "0.11.8" +clap = { version = "4.5.61", optional = true, features = ["unicode", "derive"] } +env_logger = "0.11.10" ignore = "0.4.25" log = "0.4.29" nu-ansi-term = "0.50.3" @@ -24,13 +24,13 @@ nu-parser = "0.110.0" nu-protocol = "0.110.0" nu-utils = "0.110.0" nuon = "0.110.0" -rayon = "1.11.0" +rayon = "1.12.0" thiserror = "2.0.18" [dev-dependencies] -criterion = "0.8.1" +criterion = "0.8.2" rstest = "0.26.1" -tempfile = "3.24.0" +tempfile = "3.27.0" [features] default = ["bin"] diff --git a/src/formatting/blocks.rs b/src/formatting/blocks.rs index 6ab023d..8e4bc03 100644 --- a/src/formatting/blocks.rs +++ b/src/formatting/blocks.rs @@ -256,7 +256,25 @@ impl<'a> Formatter<'a> { for (i, element) in pipeline.elements.iter().enumerate() { if i > 0 { - if is_multiline { + // If the previous element already ends with a pipe redirect + // (e.g. `e>|` or `o+e>|`), it acts as the pipeline separator. + // Emit only a space, not an additional `|` (issue #181). + let prev_has_pipe_redir = pipeline.elements[i - 1] + .redirection + .as_ref() + .is_some_and(|redir| { + matches!( + redir, + PipelineRedirection::Single { + target: RedirectionTarget::Pipe { .. }, + .. + } + ) + }); + + if prev_has_pipe_redir { + self.space(); + } else if is_multiline { self.newline(); self.write_indent(); self.write("| "); @@ -300,6 +318,13 @@ impl<'a> Formatter<'a> { fn format_redirection_target(&mut self, target: &RedirectionTarget) { match target { RedirectionTarget::File { expr, span, .. } => { + if span.start < expr.span.end && expr.span.end <= self.source.len() { + // Keep authored redirection text to avoid parser-artifact + // pipe duplication around tokens like `e>|` and `o+e>|`. + self.write_bytes(&self.source[span.start..expr.span.end]); + return; + } + self.write_span(*span); self.space(); self.format_expression(expr); diff --git a/src/formatting/calls.rs b/src/formatting/calls.rs index b8d7206..c4e0ed3 100644 --- a/src/formatting/calls.rs +++ b/src/formatting/calls.rs @@ -222,9 +222,12 @@ impl<'a> Formatter<'a> { /// Format an invocation of an alias (i.e. a call *using* an alias rather /// than declaring one). Preserves the exact source text after the head. fn format_alias_invocation_call(&mut self, call: &nu_protocol::ast::Call) { + // Only consider arguments that belong to the authored source (not + // parser-injected alias expansion arguments – issue #180). let call_end = call .arguments .iter() + .filter(|arg| self.argument_belongs_to_call_source(call, arg)) .map(argument_end_pos) .max() .unwrap_or(call.head.end) @@ -243,14 +246,21 @@ impl<'a> Formatter<'a> { call: &nu_protocol::ast::Call, arg: &Argument, ) -> bool { - let span_start = match arg { + let (span_start, span_end) = match arg { Argument::Positional(expr) | Argument::Unknown(expr) | Argument::Spread(expr) => { - expr.span.start + (expr.span.start, expr.span.end) } - Argument::Named(named) => named.0.span.start, + Argument::Named(named) => ( + named.0.span.start, + named + .2 + .as_ref() + .map_or(named.0.span.end, |value| value.span.end), + ), }; - span_start >= call.head.start + // Exclude parser-injected arguments that don't map to source bytes. + span_end > span_start && span_start >= call.head.start } /// Format `let`/`mut`/`const` calls while preserving explicit type annotations. @@ -637,6 +647,34 @@ impl<'a> Formatter<'a> { } self.format_expression(head); + let has_injected_prefix_args = args.iter().any(|arg| match arg { + ExternalArgument::Regular(expr) | ExternalArgument::Spread(expr) => { + expr.span.end > expr.span.start && expr.span.end <= head.span.start + } + }); + + if has_injected_prefix_args { + let authored_tail_end = args + .iter() + .filter_map(|arg| match arg { + ExternalArgument::Regular(expr) | ExternalArgument::Spread(expr) + if expr.span.end > expr.span.start + && expr.span.start >= head.span.start => + { + Some(expr.span.end) + } + _ => None, + }) + .max() + .unwrap_or(head.span.end) + .min(self.source.len()); + + if head.span.end < authored_tail_end { + self.write_bytes(&self.source[head.span.end..authored_tail_end]); + } + return; + } + let tail_end = args .iter() .map(|arg| match arg { @@ -942,7 +980,13 @@ impl<'a> Formatter<'a> { } if let Some(default) = ¶m.default_value { self.write(" = "); - self.write(&default.to_expanded_string(" ", &nu_protocol::Config::default())); + // Use raw source to preserve original quote style (issue #179). + let span = default.span(); + if span.start < span.end && span.end <= self.source.len() { + self.write_bytes(&self.source[span.start..span.end]); + } else { + self.write(&default.to_parsable_string(" ", &nu_protocol::Config::default())); + } } } @@ -974,7 +1018,13 @@ impl<'a> Formatter<'a> { } if let Some(default) = &flag.default_value { self.write(" = "); - self.write(&default.to_expanded_string(" ", &nu_protocol::Config::default())); + // Use raw source to preserve original quote style (issue #179). + let span = default.span(); + if span.start < span.end && span.end <= self.source.len() { + self.write_bytes(&self.source[span.start..span.end]); + } else { + self.write(&default.to_parsable_string(" ", &nu_protocol::Config::default())); + } } } diff --git a/src/main.rs b/src/main.rs index 7355b28..02104a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ clippy::manual_let_else )] -use clap::Parser; +use clap::{CommandFactory, Parser}; use ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder}; use log::{info, trace}; use nu_ansi_term::{Color, Style}; @@ -49,12 +49,29 @@ impl ExitCode { struct Cli { #[arg( value_name = "FILES", - default_value = ".", conflicts_with("stdin"), help = "One of more Nushell files or directories to format" )] files: Vec, + #[arg( + long, + conflicts_with = "stdin", + conflicts_with = "files", + conflicts_with = "all_recurse", + help = "Format all .nu files in the current directory (non-recursive)" + )] + all: bool, + + #[arg( + long, + conflicts_with = "stdin", + conflicts_with = "files", + conflicts_with = "all", + help = "Format all .nu files recursively from the current directory downward" + )] + all_recurse: bool, + #[arg( long, conflicts_with = "stdin", @@ -89,8 +106,20 @@ fn main() { } let cli = Cli::parse(); + let has_format_target = !cli.files.is_empty() || cli.stdin || cli.all || cli.all_recurse; + + if !has_format_target && cli.config.is_none() { + Cli::command() + .print_help() + .expect("Unexpected error occurred when printing help"); + println!(); + exit_with_code(ExitCode::Success); + } + trace!("received cli.files: {:?}", cli.files); trace!("received cli.stdin: {:?}", cli.stdin); + trace!("received cli.all: {:?}", cli.all); + trace!("received cli.all_recurse: {:?}", cli.all_recurse); trace!("received cli.config: {:?}", cli.config); let config = match load_config(cli.config) { @@ -104,7 +133,15 @@ fn main() { let exit_code = if cli.stdin { format_stdin(&config) } else { - format_files_from_paths(cli.files, &config, cli.dry_run) + let (paths, recurse) = if cli.all { + (vec![PathBuf::from(".")], false) + } else if cli.all_recurse { + (vec![PathBuf::from(".")], true) + } else { + (cli.files, true) + }; + + format_files_from_paths(paths, &config, cli.dry_run, recurse) }; std::io::stdout() @@ -155,8 +192,13 @@ fn format_stdin(config: &Config) -> ExitCode { } /// Format files from the given paths -fn format_files_from_paths(paths: Vec, config: &Config, dry_run: bool) -> ExitCode { - let (target_files, invalid_files) = match discover_nu_files(paths, &config.excludes) { +fn format_files_from_paths( + paths: Vec, + config: &Config, + dry_run: bool, + recurse: bool, +) -> ExitCode { + let (target_files, invalid_files) = match discover_nu_files(paths, &config.excludes, recurse) { Ok(files) => files, Err(err) => { eprintln!("{}: {}", Color::LightRed.paint("error"), err); @@ -319,6 +361,7 @@ fn plural(count: usize) -> &'static str { fn discover_nu_files( paths: Vec, excludes: &[String], + recurse: bool, ) -> Result<(Vec, Vec), ConfigError> { let (valid_paths, invalid_paths): (Vec<_>, Vec<_>) = paths.into_iter().partition(|p| p.exists()); @@ -328,7 +371,12 @@ fn discover_nu_files( let nu_files = valid_paths .iter() .flat_map(|path| { - WalkBuilder::new(path) + let mut builder = WalkBuilder::new(path); + if !recurse { + builder.max_depth(Some(1)); + } + + builder .overrides(overrides.clone()) .build() .filter_map(Result::ok) @@ -493,7 +541,7 @@ mod tests { fs::write(&target, "let x = 1").unwrap(); let (files, invalid) = - discover_nu_files(vec![dir.path().to_path_buf(), nested.clone()], &[]) + discover_nu_files(vec![dir.path().to_path_buf(), nested.clone()], &[], true) .expect("discovery should succeed"); assert!(invalid.is_empty()); diff --git a/tests/fixtures/expected/alias_invocation_in_def_keeps_authored_tokens_issue180.nu b/tests/fixtures/expected/alias_invocation_in_def_keeps_authored_tokens_issue180.nu new file mode 100644 index 0000000..cc69984 --- /dev/null +++ b/tests/fixtures/expected/alias_invocation_in_def_keeps_authored_tokens_issue180.nu @@ -0,0 +1,7 @@ +alias wds = systemd-run waydroid session start +alias wdo = waydroid session stop + +def wdr [] { + wdo + wds +} diff --git a/tests/fixtures/expected/signature_default_string_quotes_preserved_issue179.nu b/tests/fixtures/expected/signature_default_string_quotes_preserved_issue179.nu new file mode 100644 index 0000000..3b84699 --- /dev/null +++ b/tests/fixtures/expected/signature_default_string_quotes_preserved_issue179.nu @@ -0,0 +1,2 @@ +def greet_default [name: string = ""] { } +def greet_default_space [name: string = "a b"] { } diff --git a/tests/fixtures/expected/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu b/tests/fixtures/expected/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu new file mode 100644 index 0000000..f7abcf4 --- /dev/null +++ b/tests/fixtures/expected/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu @@ -0,0 +1,2 @@ +tp $path e>| /dev/null +tp $path o+e>| /dev/null diff --git a/tests/fixtures/expected/try_block_comment_spacing_preserved_issue178.nu b/tests/fixtures/expected/try_block_comment_spacing_preserved_issue178.nu new file mode 100644 index 0000000..4bde568 --- /dev/null +++ b/tests/fixtures/expected/try_block_comment_spacing_preserved_issue178.nu @@ -0,0 +1,4 @@ +try { + # ... + pw-play /usr/share/sounds/freedesktop/stereo/phone-incoming-call.oga +} diff --git a/tests/fixtures/input/alias_invocation_in_def_keeps_authored_tokens_issue180.nu b/tests/fixtures/input/alias_invocation_in_def_keeps_authored_tokens_issue180.nu new file mode 100644 index 0000000..cc69984 --- /dev/null +++ b/tests/fixtures/input/alias_invocation_in_def_keeps_authored_tokens_issue180.nu @@ -0,0 +1,7 @@ +alias wds = systemd-run waydroid session start +alias wdo = waydroid session stop + +def wdr [] { + wdo + wds +} diff --git a/tests/fixtures/input/signature_default_string_quotes_preserved_issue179.nu b/tests/fixtures/input/signature_default_string_quotes_preserved_issue179.nu new file mode 100644 index 0000000..d9acfef --- /dev/null +++ b/tests/fixtures/input/signature_default_string_quotes_preserved_issue179.nu @@ -0,0 +1,2 @@ +def greet_default [name: string = ""] {} +def greet_default_space [name: string = "a b"] {} diff --git a/tests/fixtures/input/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu b/tests/fixtures/input/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu new file mode 100644 index 0000000..f7abcf4 --- /dev/null +++ b/tests/fixtures/input/stderr_pipeline_redirection_pipe_not_duplicated_issue181.nu @@ -0,0 +1,2 @@ +tp $path e>| /dev/null +tp $path o+e>| /dev/null diff --git a/tests/fixtures/input/try_block_comment_spacing_preserved_issue178.nu b/tests/fixtures/input/try_block_comment_spacing_preserved_issue178.nu new file mode 100644 index 0000000..4bde568 --- /dev/null +++ b/tests/fixtures/input/try_block_comment_spacing_preserved_issue178.nu @@ -0,0 +1,4 @@ +try { + # ... + pw-play /usr/share/sounds/freedesktop/stereo/phone-incoming-call.oga +} diff --git a/tests/ground_truth.rs b/tests/ground_truth.rs index e443f1a..94e91a1 100644 --- a/tests/ground_truth.rs +++ b/tests/ground_truth.rs @@ -664,4 +664,24 @@ fixture_tests!( ground_truth_if_call_parentheses_preserved_after_if_issue176, idempotency_if_call_parentheses_preserved_after_if_issue176 ), + ( + "try_block_comment_spacing_preserved_issue178", + ground_truth_try_block_comment_spacing_preserved_issue178, + idempotency_try_block_comment_spacing_preserved_issue178 + ), + ( + "signature_default_string_quotes_preserved_issue179", + ground_truth_signature_default_string_quotes_preserved_issue179, + idempotency_signature_default_string_quotes_preserved_issue179 + ), + ( + "alias_invocation_in_def_keeps_authored_tokens_issue180", + ground_truth_alias_invocation_in_def_keeps_authored_tokens_issue180, + idempotency_alias_invocation_in_def_keeps_authored_tokens_issue180 + ), + ( + "stderr_pipeline_redirection_pipe_not_duplicated_issue181", + ground_truth_stderr_pipeline_redirection_pipe_not_duplicated_issue181, + idempotency_stderr_pipeline_redirection_pipe_not_duplicated_issue181 + ), ); diff --git a/tests/main.rs b/tests/main.rs index 69f9642..6c15d2e 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -494,3 +494,84 @@ if not (has systemctl) {\n\ "parenthesized condition should not be rewritten into invalid syntax: {stdout}" ); } + +#[test] +fn no_args_prints_help_instead_of_formatting_current_directory_issue182() { + let output = Command::new(get_test_binary()).output().unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert_eq!(output.status.code(), Some(0)); + assert!( + stdout.contains("Usage:"), + "expected help/usage output when no args are provided: {stdout}" + ); +} + +#[test] +fn all_formats_only_current_directory_nu_files_issue182() { + let dir = tempdir().unwrap(); + let nested = dir.path().join("nested"); + fs::create_dir_all(&nested).unwrap(); + + let root_nu = dir.path().join("root.nu"); + let nested_nu = nested.join("child.nu"); + + fs::write(&root_nu, INVALID).unwrap(); + fs::write(&nested_nu, INVALID).unwrap(); + + let output = Command::new(get_test_binary()) + .current_dir(dir.path()) + .arg("--all") + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(0)); + assert_eq!(fs::read_to_string(&root_nu).unwrap(), VALID); + assert_eq!(fs::read_to_string(&nested_nu).unwrap(), INVALID); +} + +#[test] +fn all_recurse_formats_current_directory_tree_nu_files_issue182() { + let dir = tempdir().unwrap(); + let nested = dir.path().join("nested"); + fs::create_dir_all(&nested).unwrap(); + + let root_nu = dir.path().join("root.nu"); + let nested_nu = nested.join("child.nu"); + + fs::write(&root_nu, INVALID).unwrap(); + fs::write(&nested_nu, INVALID).unwrap(); + + let output = Command::new(get_test_binary()) + .current_dir(dir.path()) + .arg("--all-recurse") + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(0)); + assert_eq!(fs::read_to_string(&root_nu).unwrap(), VALID); + assert_eq!(fs::read_to_string(&nested_nu).unwrap(), VALID); +} + +#[test] +fn help_includes_all_and_all_recurse_flags_issue182() { + let output = Command::new(get_test_binary()) + .arg("--help") + .output() + .unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert_eq!(output.status.code(), Some(0)); + assert!( + stdout.contains("--all"), + "help missing --all flag: {stdout}" + ); + assert!( + stdout.contains("--all-recurse"), + "help missing --all-recurse flag: {stdout}" + ); + assert!( + stdout.contains("--stdin"), + "help missing --stdin flag: {stdout}" + ); +}