1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
use clap::{builder::styling, Arg, ArgAction, Command};

pub fn build_cli_commands() -> Command {
    Command::new("")
        .arg(Arg::new("config").required(false))
        .subcommand(
            Command::new("set-branch-prefix")
                .arg(Arg::new("key").required(false))
                .arg(Arg::new("prefix").required(false))
                .about("Set prefix for checkout using clipboard contents")
                .after_help(
                    "Set branch prefix under given key so then you can use it when\n\
                running \n\
                git-helpe-rs bp <key> \n\
                to checkout to a branch name based on contents of your clipboard\n\
                ",
                ),
        )
        .subcommand(
            Command::new("set-branch-template")
                .arg(Arg::new("key").required(true))
                .arg(Arg::new("template").required(true))
                .after_help(
                    "Set branch template under given key so then you can use it when running \n\
                    git-helpe-rs bf ...args_to_interpolate \n\
                    branch template will be interpolated where {} occurs. \n\
                    For example \n\
                    git-helpe-rs set-branch-template fu feature-{}/utils-{} \n\
                    git-helpe-rs bf fu 123 'new cli for stuff automation' \n\
                    will checkout in the following way: \n\
                    git checkout -b feature-123/utils-new-cli-for-stuff-automation \n\
                    you try anything funky with args to interpolate on your own \n\
                    ",
                )
                .about("Set template that can be used when switching branches"),
        )
        .subcommand(
            Command::new("bp")
                .arg(Arg::new("prefix").required(true))
                .about("Check you out to a branch using your clipboard contents")
                .after_help(
                    "Will use contents of your clipboard to checkout you to\n\
                    branch with prefix that's under the given key. \n\
                     Valid clipboard contents when calling this command looks like this: \n\
                    git checkout -b name-of-your-branch \n\
                    If there is a valid content in your clipboard \n\
                    after running following commands: \n\n\
                    git-helpe-rs set-branch-prefix f 'feature/' \n\
                    git-helpe-rs bp \n\n\
                    you will be checked out like this \n\
                    git checkout -b feature/name-of-your-branch
                    ",
                )
                .add_copy_flag()
                .add_dry_run_flag(),
        )
        .subcommand(
            Command::new("bt")
                .arg(Arg::new("interpolate-values").required(true).num_args(0..))
                .arg(Arg::new("key").short('k').required(false).help(
                    "Specify which template you want to use \n\
                    if you omit this param default template will be used",
                ))
                .about("Check out to a branch based on template")
                .add_copy_flag()
                .add_dry_run_flag(),
        )
        // ========== COMMIT-RELATED COMMANDS ========== //
        .subcommand(
            Command::new("set-commit")
                .arg(Arg::new("template").required(true).help(
                    "Template has places to interpolate marked with {}, [], {b} \n\n\
                    When you provide: \n\
                    '[{}] - {}' \n\
                    as your commit template, you will be able to run \n\
                    commit command with following args: \n\
                    git-helpe-rs commit 123 'fix gpu issues' \n\
                    and this commit message will be added: \n\
                    git commit -m \'[123] - fix gpu issues\' \n\n\
                    If you provide [] in your template you will have to \n\
                    set autocomplete value with set-auto-complete \n\
                    with the same number of args as number of [] \n\
                    in provided template \n\n\
                    if you provide {b} in your template you should \n\
                     - have some number in your branch \n\
                     - run git-helpers-c with -b flag \n\
                    ",
                ))
                .arg(Arg::new("key").short('k').required(false).help(
                    "
                You can provide key to have different templates at hand: \n\
                git-helpe-rs commit 123 'fix gpu issues' -k sec \n\
                will use template that was set with \n\
                git-helpe-rs set-commit '{} - {}' -k sec \n\
                Otherwise it will be saved as your default \n\
                ",
                ))
                .about("Set template for commit formatting")
                .after_help(
                    "Sets commit format. \n\
                    You can use {{}} for places to interpolate \n\
                    and {[]} for places to autocomplete. \n\
                    and {b} as places to autocomplete from number in branch. \n\
                    ",
                ),
        )
        .subcommand(
            Command::new("set-auto-complete")
                .about("set value that will be used to autocomplete commit template")
                .arg(Arg::new("auto_complete_value").required(true).num_args(0..)),
        )
        .subcommand(
            Command::new("c")
                .arg(Arg::new("interpolate-values").required(true).num_args(0..))
                .arg(
                    Arg::new("auto-complete")
                        .short('a')
                        .action(ArgAction::SetTrue)
                        .help("Should use autocomplete values for commit message"),
                )
                .arg(Arg::new("key").short('k').required(false).help(
                    "
                    Specify which template you want to use \n\
                    if you omit this param default template will be used \n\
                    ",
                ))
                .arg(
                    Arg::new("infer-number-from-branch")
                        .short('b')
                        .action(ArgAction::SetTrue)
                        .help(
                            "Will try to catch any number from branch name \n\
                    and use it as a value for {b} in your template \n\
                    if your template has no {b} it will panic \n\
                    ",
                        ),
                )
                .about("Commit using one of templates")
                .add_copy_flag()
                .add_dry_run_flag(),
        )
        // ============== OTHERS ============== //
        .subcommand(Command::new("show").about("Show current config in plain JSON"))
        .subcommand(
            Command::new("set-clipboard-command")
                .about("[WIP] Set pair of copy&paste command which will be used")
                .arg(Arg::new("copy-paste-pair").num_args(0..3).help(
                    "On default it's written to use pbcopy and pbpaste as \
                command for setting and taking value from clipboard, but if you want \
                you can use command of your own choice.
                ",
                )),
        )
        .color(clap::ColorChoice::Always)
        .get_styles()
}

trait AddCopyFlag {
    fn add_copy_flag(self) -> Self;
}

impl AddCopyFlag for Command {
    fn add_copy_flag(self) -> Self {
        self.arg(
            Arg::new("copy-flag")
                .short('c')
                .action(ArgAction::SetTrue)
                .help(
                    "instead of executing command pass it to clipboard \n \n
        you can always configure command used for passing to clipboard",
                ),
        )
    }
}

trait AddDryRunFlag {
    fn add_dry_run_flag(self) -> Self;
}

impl AddDryRunFlag for Command {
    fn add_dry_run_flag(self) -> Self {
        self.arg(
            Arg::new("dry-run")
                .long("dr")
                .action(ArgAction::SetTrue)
                .help("instead of executing command see what will be ran \n \n"),
        )
    }
}

trait Styles {
    fn get_styles(self) -> Self;
}
impl Styles for Command {
    fn get_styles(self) -> Self {
        let styles = styling::Styles::styled()
            .header(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
            .usage(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
            .literal(styling::AnsiColor::Blue.on_default() | styling::Effects::BOLD)
            .placeholder(styling::AnsiColor::Cyan.on_default());

        self.styles(styles)
    }
}