From d049ffbaadc8aacf226b49b3ac049c1c362cc80f Mon Sep 17 00:00:00 2001 From: Juan Ibiapina Date: Fri, 14 Jun 2024 11:26:59 +0200 Subject: [PATCH] feat!: Rework command validation There's no special flow for validation now, it's just a flag like commands, help, etc. This is a BREAKING CHANGE because now the `--validate` flag needs to come after `--`. --- README.md | 5 +++++ integration/help.bats | 1 + integration/validate.bats | 2 +- src/config.rs | 3 ++- src/main.rs | 44 +++++++++++++-------------------------- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 3ad8068..1a30f0a 100644 --- a/README.md +++ b/README.md @@ -332,6 +332,11 @@ Usage comments in sub 1.x for the purpose of documenting, you can run `sub` with the `--validate` flag to check if your scripts are compatible with the new version. +Example: +``` +$ sub --name hat --absolute /path/to/cli/root -- --validate +``` + ### Help, commands and completions If you used the `help`, `commands` or `completions` subcommands, they are now diff --git a/integration/help.bats b/integration/help.bats index f62c7a9..b07c6e7 100644 --- a/integration/help.bats +++ b/integration/help.bats @@ -28,6 +28,7 @@ Options: --usage Print usage -h, --help Print help --completions Print completions + --validate Validate subcommand --commands Print subcommands --extension Filter subcommands by extension diff --git a/integration/validate.bats b/integration/validate.bats index fd0f3f8..e980c5c 100644 --- a/integration/validate.bats +++ b/integration/validate.bats @@ -6,7 +6,7 @@ PROJECT_DIR="$SUB_TEST_DIR/v1" @test "sub: validates all subcommands in the project directory" { fixture "v1" - run $SUB_BIN --name main --absolute "$PROJECT_DIR" --validate + run $SUB_BIN --name main --absolute "$PROJECT_DIR" -- --validate assert_failure assert_output "$PROJECT_DIR/libexec/invalid-usage: invalid usage string diff --git a/src/config.rs b/src/config.rs index 7047767..e186ec5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -78,12 +78,13 @@ impl Config { .arg(Arg::new("usage").long("usage").num_args(0).help("Print usage")) .arg(Arg::new("help").short('h').long("help").num_args(0).help("Print help")) .arg(Arg::new("completions").long("completions").num_args(0).help("Print completions")) + .arg(Arg::new("validate").long("validate").num_args(0).help("Validate subcommand")) .arg(Arg::new("commands").long("commands").num_args(0).help("Print subcommands")) .arg(Arg::new("extension").long("extension").num_args(1).help("Filter subcommands by extension")) .group(ArgGroup::new("extension_group").args(["extension"]).requires("commands")) - .group(ArgGroup::new("exclusion").args(["commands", "completions", "usage", "help"]).multiple(false).required(false)) + .group(ArgGroup::new("exclusion").args(["commands", "completions", "usage", "help", "validate"]).multiple(false).required(false)) .arg(Arg::new("commands_with_args").trailing_var_arg(true).allow_hyphen_values(true).num_args(..)) } diff --git a/src/main.rs b/src/main.rs index a9c5307..77daf77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,28 +16,6 @@ fn main() { let config = Config::new(sub_cli_args.name, sub_cli_args.root, sub_cli_args.color, sub_cli_args.infer_long_arguments); - if sub_cli_args.validate { - let top_level_command = match subcommand(&config, Vec::new()) { - Ok(subcommand) => subcommand, - Err(error) => handle_error( - &config, - error, - false, - ), - }; - - let errors = top_level_command.validate(); - for error in &errors { - println!("{}: {}", error.0.display(), print_error(error.1.clone())); - } - - if errors.is_empty() { - exit(0); - } else { - exit(1); - } - } - let user_cli_command = config.user_cli_command(&config.name); let user_cli_args = parse_user_cli_args(&user_cli_command, sub_cli_args.cliargs); @@ -88,6 +66,18 @@ fn main() { Ok(code) => exit(code), Err(error) => handle_error(&config, error, true), }, + UserCliMode::Validate => { + let errors = subcommand.validate(); + for error in &errors { + println!("{}: {}", error.0.display(), print_error(error.1.clone())); + } + + if errors.is_empty() { + exit(0); + } else { + exit(1); + } + } } } @@ -168,10 +158,6 @@ struct SubCli { #[command(flatten)] exec_and_rel: ExecutableAndRelative, - #[arg(long)] - #[arg(help = "Validate that the CLI is correctly configured")] - validate: bool, - #[arg(help = "Arguments to pass to the CLI", raw = true)] cliargs: Vec, } @@ -199,7 +185,6 @@ struct SubCliArgs { color: Color, root: PathBuf, infer_long_arguments: bool, - validate: bool, cliargs: Vec, } @@ -210,6 +195,7 @@ enum UserCliMode { Help, Commands(Option), Completions, + Validate, } struct UserCliArgs { @@ -233,6 +219,8 @@ fn parse_user_cli_args(cmd: &Command, cliargs: Vec) -> UserCliArgs { UserCliMode::Help } else if args.get_one::("commands").cloned().unwrap_or(false) { UserCliMode::Commands(args.get_one::("extension").cloned()) + } else if args.get_one::("validate").cloned().unwrap_or(false) { + UserCliMode::Validate } else if args .get_one::("completions") .cloned() @@ -279,8 +267,6 @@ fn parse_sub_cli_args() -> SubCliArgs { infer_long_arguments: args.infer_long_arguments, - validate: args.validate, - cliargs: args.cliargs, root,