git_stk/cli.rs
1use clap::{ArgAction, Parser, Subcommand};
2
3#[derive(Debug, Parser)]
4#[command(name = "git-stk")]
5#[command(about = "Git-native stacked branch workflow helper, with GitHub and GitLab integration")]
6pub struct Cli {
7 #[command(subcommand)]
8 pub command: Command,
9}
10
11#[derive(Debug, Subcommand)]
12pub enum Command {
13 /// Create a new child branch from the current branch.
14 New { branch: String },
15 /// Print a branch's stack parent.
16 Parent { branch: Option<String> },
17 /// Print a branch's stack children.
18 Children { branch: Option<String> },
19 /// Check out the current branch's stack parent.
20 Up,
21 /// Check out a stack child of the current branch.
22 Down { branch: Option<String> },
23 /// Print the current stack.
24 List,
25 /// Print local and remote stack status for a branch.
26 Status { branch: Option<String> },
27 /// Attach an existing branch to a parent.
28 Adopt {
29 branch: String,
30 #[arg(long)]
31 parent: String,
32 },
33 /// Remove stack parent metadata from a branch.
34 Detach { branch: Option<String> },
35 /// Rebase the current branch and descendants onto their stack parents.
36 Restack {
37 /// Pass --update-refs to git rebase.
38 #[arg(long, action = ArgAction::SetTrue, conflicts_with = "no_update_refs")]
39 update_refs: bool,
40 /// Do not pass --update-refs to git rebase.
41 #[arg(long, action = ArgAction::SetTrue)]
42 no_update_refs: bool,
43 },
44 /// Continue an interrupted restack after resolving conflicts.
45 Continue,
46 /// Abort an interrupted restack.
47 Abort,
48 /// Print detected review provider.
49 Provider,
50 /// Print the review request for a branch.
51 Review { branch: Option<String> },
52 /// Sync local stack metadata from remote review requests.
53 Sync {
54 branch: Option<String>,
55 /// Print what would change without updating local metadata.
56 #[arg(long, action = ArgAction::SetTrue)]
57 dry_run: bool,
58 },
59 /// Create or update a remote review request for a branch.
60 Submit {
61 branch: Option<String>,
62 /// Print what would change without creating or updating reviews.
63 #[arg(long, action = ArgAction::SetTrue)]
64 dry_run: bool,
65 /// Submit the branch and its descendants parent-first.
66 #[arg(long, conflicts_with = "branch")]
67 stack: bool,
68 },
69 /// Upgrade git-stk to the latest release.
70 Upgrade {
71 /// Build and install the latest unreleased commit instead.
72 #[arg(long, action = ArgAction::SetTrue, conflicts_with = "force")]
73 head: bool,
74 /// Reinstall the latest release even when already up to date.
75 #[arg(long, action = ArgAction::SetTrue)]
76 force: bool,
77 /// Skip the --head confirmation prompt.
78 #[arg(long, short = 'y', action = ArgAction::SetTrue, requires = "head")]
79 yes: bool,
80 },
81 /// Clean up local metadata for merged review requests.
82 Cleanup {
83 branch: Option<String>,
84 /// Print what would change without updating local metadata.
85 #[arg(long, action = ArgAction::SetTrue)]
86 dry_run: bool,
87 /// Delete cleaned merged branches after updating stack metadata.
88 #[arg(long, action = ArgAction::SetTrue)]
89 delete_branch: bool,
90 },
91}
92
93#[derive(Debug, Clone, Copy, Eq, PartialEq)]
94pub enum UpdateRefsMode {
95 Config,
96 Enabled,
97 Disabled,
98}
99
100impl UpdateRefsMode {
101 pub fn from_flags(update_refs: bool, no_update_refs: bool) -> Self {
102 match (update_refs, no_update_refs) {
103 (true, false) => Self::Enabled,
104 (false, true) => Self::Disabled,
105 _ => Self::Config,
106 }
107 }
108}