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 /// Print shell completions.
70 Completions {
71 /// Shell to print completions for.
72 #[arg(value_enum)]
73 shell: clap_complete::Shell,
74 },
75 /// Install the man page and wire up shell completions.
76 Setup {
77 /// Skip confirmation prompts.
78 #[arg(long, short = 'y', action = ArgAction::SetTrue)]
79 yes: bool,
80 /// Only re-render generated assets (man page); never touch shell rc files.
81 #[arg(long, action = ArgAction::SetTrue, conflicts_with = "yes")]
82 refresh: bool,
83 },
84 /// Upgrade git-stk to the latest release.
85 Upgrade {
86 /// Build and install the latest unreleased commit instead.
87 #[arg(long, action = ArgAction::SetTrue, conflicts_with = "force")]
88 head: bool,
89 /// Reinstall the latest release even when already up to date.
90 #[arg(long, action = ArgAction::SetTrue)]
91 force: bool,
92 /// Skip the --head confirmation prompt.
93 #[arg(long, short = 'y', action = ArgAction::SetTrue, requires = "head")]
94 yes: bool,
95 },
96 /// Clean up local metadata for merged review requests.
97 Cleanup {
98 branch: Option<String>,
99 /// Print what would change without updating local metadata.
100 #[arg(long, action = ArgAction::SetTrue)]
101 dry_run: bool,
102 /// Delete cleaned merged branches after updating stack metadata.
103 #[arg(long, action = ArgAction::SetTrue)]
104 delete_branch: bool,
105 },
106}
107
108#[derive(Debug, Clone, Copy, Eq, PartialEq)]
109pub enum UpdateRefsMode {
110 Config,
111 Enabled,
112 Disabled,
113}
114
115impl UpdateRefsMode {
116 pub fn from_flags(update_refs: bool, no_update_refs: bool) -> Self {
117 match (update_refs, no_update_refs) {
118 (true, false) => Self::Enabled,
119 (false, true) => Self::Disabled,
120 _ => Self::Config,
121 }
122 }
123}