diff --git a/src/cli/args.rs b/src/cli/args.rs index e112f3e22..444e32a3a 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -26,18 +26,10 @@ pub struct CliArgs { #[arg(short = 'A', long, env = "ACCESSIBLE", global = true)] pub accessible: bool, - /// Ignore hidden files - #[arg(short = 'H', long, global = true)] - pub hidden: bool, - /// Silence output #[arg(short, long, global = true)] pub quiet: bool, - /// Ignore files matched by git's ignore files - #[arg(short, long, global = true)] - pub gitignore: bool, - /// Specify the format of the archive #[arg(short, long, global = true)] pub format: Option, @@ -73,6 +65,14 @@ pub enum Subcommand { #[arg(required = true, value_hint = ValueHint::FilePath)] output: PathBuf, + /// Ignore hidden files + #[arg(short = 'H', long)] + hidden: bool, + + /// Ignore files matched by git's ignore files + #[arg(short, long)] + gitignore: bool, + /// Compression level, applied to all formats #[arg(short, long, group = "compression-level")] level: Option, @@ -153,9 +153,7 @@ mod tests { yes: false, no: false, accessible: false, - hidden: false, quiet: false, - gitignore: false, format: None, // This is usually replaced in assertion tests password: None, @@ -216,6 +214,8 @@ mod tests { cmd: Subcommand::Compress { files: to_paths(["file"]), output: PathBuf::from("file.tar.gz"), + hidden: false, + gitignore: false, level: None, fast: false, slow: false, @@ -230,6 +230,8 @@ mod tests { cmd: Subcommand::Compress { files: to_paths(["a", "b", "c"]), output: PathBuf::from("archive.tar.gz"), + hidden: false, + gitignore: false, level: None, fast: false, slow: false, @@ -239,11 +241,13 @@ mod tests { } ); test!( - "ouch compress a b c archive.tar.gz", + "ouch compress --hidden --gitignore a b c archive.tar.gz", CliArgs { cmd: Subcommand::Compress { files: to_paths(["a", "b", "c"]), output: PathBuf::from("archive.tar.gz"), + hidden: true, + gitignore: true, level: None, fast: false, slow: false, @@ -269,6 +273,8 @@ mod tests { cmd: Subcommand::Compress { files: to_paths(["a", "b", "c"]), output: PathBuf::from("output"), + hidden: false, + gitignore: false, level: None, fast: false, slow: false, @@ -287,5 +293,8 @@ mod tests { assert!(CliArgs::try_parse_from(args_splitter("ouch c input")).is_err()); assert!(CliArgs::try_parse_from(args_splitter("ouch d")).is_err()); assert!(CliArgs::try_parse_from(args_splitter("ouch l")).is_err()); + assert!(CliArgs::try_parse_from(args_splitter("ouch decompress --hidden file.tar.gz")).is_err()); + assert!(CliArgs::try_parse_from(args_splitter("ouch list --gitignore file.tar.gz")).is_err()); + assert!(CliArgs::try_parse_from(args_splitter("ouch --hidden compress file file.tar.gz")).is_err()); } } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index e620dcb07..57d82989b 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -44,19 +44,21 @@ impl CliArgs { (true, true) => unreachable!(), }; - let follow_symlinks = matches!( - &args.cmd, + let (hidden, gitignore, follow_symlinks) = match &args.cmd { Subcommand::Compress { - follow_symlinks: true, + hidden, + gitignore, + follow_symlinks, .. - } - ); + } => (*hidden, *gitignore, *follow_symlinks), + Subcommand::Decompress { .. } | Subcommand::List { .. } => (false, false, false), + }; let file_visibility_policy = FileVisibilityPolicy::new() - .read_git_exclude(args.gitignore) - .read_ignore(args.gitignore) - .read_git_ignore(args.gitignore) - .read_hidden(args.hidden) + .read_git_exclude(gitignore) + .read_ignore(gitignore) + .read_git_ignore(gitignore) + .read_hidden(hidden) .follow_symlinks(follow_symlinks); Ok((args, skip_questions_positively, file_visibility_policy)) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 682c0c9ce..5abf99c2d 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -60,6 +60,8 @@ pub fn run(args: CliArgs, question_policy: QuestionPolicy, file_visibility_polic Subcommand::Compress { files, output: output_path, + hidden: _, + gitignore, level, fast, slow, @@ -72,9 +74,9 @@ pub fn run(args: CliArgs, question_policy: QuestionPolicy, file_visibility_polic // gitignore and follow_symlinks both read paths outside the declared input set so the // sandbox cannot confine them; run unsandboxed and say why - let sandbox_disabled = sandbox::disabled_by_request(args.no_sandbox) || args.gitignore || follow_symlinks; + let sandbox_disabled = sandbox::disabled_by_request(args.no_sandbox) || gitignore || follow_symlinks; if cfg!(target_os = "linux") && !sandbox::disabled_by_request(args.no_sandbox) { - if args.gitignore { + if gitignore { info!("Sandbox: disabled because --gitignore reads git configuration outside the input files"); } if follow_symlinks { diff --git a/tests/snapshots/ui__ui_test_usage_help_flag-2.snap b/tests/snapshots/ui__ui_test_usage_help_flag-2.snap index 5146aa694..693283201 100644 --- a/tests/snapshots/ui__ui_test_usage_help_flag-2.snap +++ b/tests/snapshots/ui__ui_test_usage_help_flag-2.snap @@ -16,9 +16,7 @@ Options: -y, --yes Skip [Y/n] questions, default to yes -n, --no Skip [Y/n] questions, default to no -A, --accessible Activate accessibility mode, reducing visual noise [env: ACCESSIBLE=] - -H, --hidden Ignore hidden files -q, --quiet Silence output - -g, --gitignore Ignore files matched by git's ignore files -f, --format Specify the format of the archive -p, --password Decompress or list with password [env: OUCH_PASSWORD=] -c, --threads Concurrent working threads diff --git a/tests/snapshots/ui__ui_test_usage_help_flag.snap b/tests/snapshots/ui__ui_test_usage_help_flag.snap index d16fcfde0..76bb397fb 100644 --- a/tests/snapshots/ui__ui_test_usage_help_flag.snap +++ b/tests/snapshots/ui__ui_test_usage_help_flag.snap @@ -28,15 +28,9 @@ Options: [env: ACCESSIBLE=] - -H, --hidden - Ignore hidden files - -q, --quiet Silence output - -g, --gitignore - Ignore files matched by git's ignore files - -f, --format Specify the format of the archive