1pub mod amps;
2pub mod browse;
3pub mod cache;
4pub mod cicd;
5pub mod common;
6pub mod docker;
7pub mod init;
8pub mod merge_request;
9pub mod my;
10pub mod project;
11pub mod release;
12pub mod star;
13pub mod trending;
14pub mod user;
15
16use self::browse::BrowseCommand;
17use self::browse::BrowseOptions;
18use self::cicd::{PipelineCommand, PipelineOptions};
19use self::common::validate_domain_project_repo_path;
20use self::docker::{DockerCommand, DockerOptions};
21use self::init::{InitCommand, InitCommandOptions};
22use self::my::MyCommand;
23use self::my::MyOptions;
24use self::project::{ProjectCommand, ProjectOptions};
25use self::release::{ReleaseCommand, ReleaseOptions};
26use self::trending::TrendingCommand;
27use self::trending::TrendingOptions;
28use amps::AmpsCommand;
29use amps::AmpsOptions;
30use cache::CacheCommand;
31use cache::CacheOptions;
32use clap::ArgAction;
33use merge_request::{MergeRequestCommand, MergeRequestOptions};
34use user::UserCommand;
35use user::UserOptions;
36
37use std::option::Option;
38
39use clap::builder::{styling::AnsiColor, Styles};
40use clap::Parser;
41
42const CLI_STYLE: Styles = Styles::styled()
43 .header(AnsiColor::Red.on_default().bold())
44 .literal(AnsiColor::Blue.on_default().bold())
45 .placeholder(AnsiColor::Green.on_default())
46 .usage(AnsiColor::Red.on_default().bold());
47
48#[derive(Parser)]
49#[command(about = "A Github/Gitlab CLI tool", styles = CLI_STYLE, version)]
50#[clap(next_help_heading = "Global options")]
51struct Args {
52 #[clap(subcommand)]
53 pub command: Command,
54 #[clap(long, short, global = true, action = ArgAction::Count)]
56 verbose: u8,
57 #[clap(
59 long,
60 global = true,
61 value_name = "DOMAIN/OWNER/PROJECT_NAME",
62 value_parser = validate_domain_project_repo_path
63 )]
64 pub repo: Option<String>,
65 #[clap(long, global = true, value_name = "DOMAIN")]
67 pub domain: Option<String>,
68 #[clap(long, global = true, value_name = "PATH")]
70 pub config: Option<String>,
71}
72
73#[derive(Parser)]
74enum Command {
75 #[clap(name = "mr", about = "Merge request operations")]
76 MergeRequest(MergeRequestCommand),
77 #[clap(name = "br", about = "Open the remote using your browser")]
78 Browse(BrowseCommand),
79 #[clap(name = "pp", about = "CI/CD Pipeline operations")]
80 Pipeline(PipelineCommand),
81 #[clap(name = "pj", about = "Gather project information metadata")]
82 Project(ProjectCommand),
83 #[clap(
84 name = "dk",
85 about = "Handles docker images in Gitlab/Github registries"
86 )]
87 Docker(DockerCommand),
88 #[clap(name = "rl", about = "Release operations")]
89 Release(ReleaseCommand),
90 #[clap(
91 name = "my",
92 about = "Your user information, such as assigned merge requests, etc..."
93 )]
94 My(MyCommand),
95 #[clap(name = "tr", about = "Trending repositories. Github.com only.")]
96 Trending(TrendingCommand),
97 #[clap(name = "us", about = "User operations")]
98 User(UserCommand),
99 #[clap(name = "amps")]
101 Amps(AmpsCommand),
102 #[clap(name = "init", about = "Initialize the config file")]
103 Init(InitCommand),
104 #[clap(name = "cache", about = "Local cache operations")]
105 Cache(CacheCommand),
106 #[clap(
107 name = "manual",
108 about = "Open the user manual in the browser",
109 visible_alias = "man"
110 )]
111 Manual,
112}
113
114pub fn parse_cli() -> OptionArgs {
116 let args = Args::parse();
117 let options = match args.command {
118 Command::MergeRequest(sub_matches) => Some(CliOptions::MergeRequest(sub_matches.into())),
119 Command::Browse(sub_matches) => Some(CliOptions::Browse(sub_matches.into())),
120 Command::Pipeline(sub_matches) => Some(CliOptions::Pipeline(sub_matches.into())),
121 Command::Project(sub_matches) => Some(CliOptions::Project(sub_matches.into())),
122 Command::Init(sub_matches) => Some(CliOptions::Init(sub_matches.into())),
123 Command::Docker(sub_matches) => Some(CliOptions::Docker(sub_matches.into())),
124 Command::Release(sub_matches) => Some(CliOptions::Release(sub_matches.into())),
125 Command::My(sub_matches) => Some(CliOptions::My(sub_matches.into())),
126 Command::Trending(sub_matches) => Some(CliOptions::Trending(sub_matches.into())),
127 Command::Cache(sub_matches) => Some(CliOptions::Cache(sub_matches.into())),
128 Command::Manual => Some(CliOptions::Manual),
129 Command::Amps(sub_matches) => Some(CliOptions::Amps(sub_matches.into())),
130 Command::User(sub_matches) => Some(CliOptions::User(sub_matches.into())),
131 };
132 OptionArgs::new(
133 options,
134 CliArgs::new(args.verbose, args.repo, args.domain, args.config),
135 )
136}
137
138pub enum CliOptions {
139 MergeRequest(MergeRequestOptions),
140 Browse(BrowseOptions),
141 Pipeline(PipelineOptions),
142 Project(ProjectOptions),
143 Init(InitCommandOptions),
144 Docker(DockerOptions),
145 Release(ReleaseOptions),
146 My(MyOptions),
147 Trending(TrendingOptions),
148 Cache(CacheOptions),
149 Manual,
150 Amps(AmpsOptions),
151 User(UserOptions),
152}
153
154#[derive(Clone, Default)]
155pub struct CliArgs {
156 pub verbose: u8,
157 pub repo: Option<String>,
158 pub domain: Option<String>,
159 pub config: Option<String>,
160}
161
162impl CliArgs {
163 pub fn new(
164 verbose: u8,
165 repo: Option<String>,
166 domain: Option<String>,
167 config: Option<String>,
168 ) -> Self {
169 CliArgs {
170 verbose,
171 repo,
172 domain,
173 config,
174 }
175 }
176}
177
178pub struct OptionArgs {
179 pub cli_options: Option<CliOptions>,
180 pub cli_args: CliArgs,
181}
182
183impl OptionArgs {
184 pub fn new(cli_options: Option<CliOptions>, cli_args: CliArgs) -> Self {
185 OptionArgs {
186 cli_options,
187 cli_args,
188 }
189 }
190}