Skip to main content

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}