From efa0120db07914ad9dec959d3da5f8db12e9a5de Mon Sep 17 00:00:00 2001 From: Peter Grayson Date: Sat, 7 Oct 2023 20:17:29 -0400 Subject: [PATCH] feat(delete): --all -A -U -H options --- completion/stgit.zsh | 6 ++++ src/cmd/delete.rs | 80 ++++++++++++++++++++++++++++++++++-------- t/t1601-delete-many.sh | 27 ++++++++++++++ 3 files changed, 99 insertions(+), 14 deletions(-) diff --git a/completion/stgit.zsh b/completion/stgit.zsh index 8bd61c5f..df403418 100644 --- a/completion/stgit.zsh +++ b/completion/stgit.zsh @@ -410,6 +410,12 @@ _stg-delete() { __stg_add_args_push_conflicts subcmd_args+=( '--spill[spill patch contents to worktree and index]' + - group-ahu + '(-A --applied)'{-A,--applied}'[delete applied patches]' + '(-H --hidden)'{-H,--hidden}'[delete hidden patches]' + '(-U --unapplied)'{-U,--unapplied}'[delete unapplied patches]' + - group-all + '--all[delete all patches]' - group-top '(-t --top)'{-t,--top}'[delete top patch]' - group-patchnames diff --git a/src/cmd/delete.rs b/src/cmd/delete.rs index ffb864a7..c78efa1e 100644 --- a/src/cmd/delete.rs +++ b/src/cmd/delete.rs @@ -27,7 +27,12 @@ fn make() -> clap::Command { .about("Delete patches") .override_usage(super::make_usage( "stg delete", - &["[OPTIONS] ...", "[OPTIONS] --top"], + &[ + "[OPTIONS] [...]", + "[OPTIONS] [-A] [-U] [-H]", + "[OPTIONS] --all", + "[OPTIONS] --top", + ], )) .arg( Arg::new("patchranges-all") @@ -36,8 +41,51 @@ fn make() -> clap::Command { .num_args(1..) .allow_hyphen_values(true) .value_parser(clap::value_parser!(PatchRange)) - .conflicts_with("top") - .required_unless_present("top"), + .conflicts_with_all(["top", "all", "A-U-H"]) + .required_unless_present_any(["all", "top", "A-U-H"]), + ) + .arg( + Arg::new("all") + .long("all") + .short('a') + .help("Delete all patches") + .action(clap::ArgAction::SetTrue) + .conflicts_with_all(["top", "A-U-H", "patchranges-all"]), + ) + .arg( + Arg::new("applied") + .long("applied") + .short('A') + .help("Delete the applied patches") + .action(clap::ArgAction::SetTrue), + ) + .arg( + Arg::new("unapplied") + .long("unapplied") + .short('U') + .help("Delete the unapplied patches") + .action(clap::ArgAction::SetTrue), + ) + .arg( + Arg::new("hidden") + .long("hidden") + .short('H') + .help("Delete the hidden patches") + .action(clap::ArgAction::SetTrue), + ) + .group( + clap::ArgGroup::new("A-U-H") + .multiple(true) + .args(["applied", "unapplied", "hidden"]) + .conflicts_with_all(["top", "all", "patchranges-all"]), + ) + .arg( + Arg::new("top") + .long("top") + .short('t') + .help("Delete topmost patch") + .action(clap::ArgAction::SetTrue) + .conflicts_with_all(["all", "A-U-H", "patchranges-all"]), ) .arg( Arg::new("spill") @@ -53,13 +101,6 @@ fn make() -> clap::Command { ) .action(clap::ArgAction::SetTrue), ) - .arg( - Arg::new("top") - .long("top") - .short('t') - .help("Delete topmost patch") - .action(clap::ArgAction::SetTrue), - ) .arg(argset::branch_arg()) .arg(argset::push_conflicts_arg()) } @@ -79,11 +120,22 @@ fn run(matches: &ArgMatches) -> Result<()> { } else { return Err(super::Error::NoAppliedPatches.into()); } - } else { - let range_specs = matches - .get_many::("patchranges-all") - .expect("clap will ensure either patches or --top"); + } else if let Some(range_specs) = matches.get_many::("patchranges-all") { patchrange::resolve_names(&stack, range_specs, RangeConstraint::AllWithAppliedBoundary)? + } else if matches.get_flag("all") { + stack.all_patches().cloned().collect::>() + } else { + let mut patches = Vec::new(); + if matches.get_flag("applied") { + patches.extend(stack.applied().iter().cloned()) + } + if matches.get_flag("unapplied") { + patches.extend(stack.unapplied().iter().cloned()) + } + if matches.get_flag("hidden") { + patches.extend(stack.hidden().iter().cloned()) + } + patches }; if spill_flag diff --git a/t/t1601-delete-many.sh b/t/t1601-delete-many.sh index a995a990..589bb746 100755 --- a/t/t1601-delete-many.sh +++ b/t/t1601-delete-many.sh @@ -43,6 +43,33 @@ test_expect_success 'Delete a range of patches' ' [ "$(echo $(stg series --unapplied --noprefix))" = "p9" ] ' +test_expect_success 'Delete -U' ' + stg undo --hard && + [ "$(echo $(stg series --applied --noprefix))" = "p0 p1 p2" ] && + [ "$(echo $(stg series --unapplied --noprefix))" = "p5 p8 p9" ] && + stg delete -U && + [ "$(echo $(stg series --applied --noprefix))" = "p0 p1 p2" ] && + [ "$(echo $(stg series --unapplied --noprefix))" = "" ] +' + +test_expect_success 'Delete -A' ' + stg undo --hard && + [ "$(echo $(stg series --applied --noprefix))" = "p0 p1 p2" ] && + [ "$(echo $(stg series --unapplied --noprefix))" = "p5 p8 p9" ] && + stg delete -A && + [ "$(echo $(stg series --applied --noprefix))" = "" ] && + [ "$(echo $(stg series --unapplied --noprefix))" = "p5 p8 p9" ] +' + +test_expect_success 'Delete --all' ' + stg undo --hard && + [ "$(echo $(stg series --applied --noprefix))" = "p0 p1 p2" ] && + [ "$(echo $(stg series --unapplied --noprefix))" = "p5 p8 p9" ] && + stg delete --all && + [ "$(echo $(stg series --all --noprefix))" = "" ] && + stg undo --hard +' + test_expect_success 'Delete leading to conflict when re-pushing' ' echo "stuff" >foo.txt && stg new -m p-stuff &&