gr/cli/
project.rs

1use clap::Parser;
2
3use crate::cmds::project::{ProjectListCliArgs, ProjectMetadataGetCliArgs};
4
5use super::common::{validate_domain_project_repo_path, GetArgs, ListArgs};
6
7#[derive(Parser)]
8pub struct ProjectCommand {
9    #[clap(subcommand)]
10    subcommand: ProjectSubcommand,
11}
12
13#[derive(Parser)]
14enum ProjectSubcommand {
15    #[clap(about = "Gather project information metadata")]
16    Info(ProjectInfo),
17    #[clap(about = "List project members")]
18    Members(ListMembers),
19    #[clap(about = "List project/repository tags")]
20    Tags(ListProject),
21}
22
23#[derive(Parser)]
24struct ProjectInfo {
25    /// ID of the project
26    #[clap(long, group = "id_or_repo")]
27    pub id: Option<i64>,
28    /// Path of the project in the format `OWNER/PROJECT_NAME`
29    #[clap(long, group = "id_or_repo", value_name = "DOMAIN/OWNER/PROJECT_NAME",
30        value_parser=validate_domain_project_repo_path)]
31    pub repo: Option<String>,
32    #[clap(flatten)]
33    pub get_args: GetArgs,
34}
35
36#[derive(Parser)]
37pub struct ListMembers {
38    #[clap(flatten)]
39    pub list_args: ListArgs,
40}
41
42#[derive(Parser)]
43pub struct ListProject {
44    #[clap(flatten)]
45    pub list_args: ListArgs,
46}
47
48impl From<ProjectCommand> for ProjectOptions {
49    fn from(options: ProjectCommand) -> Self {
50        match options.subcommand {
51            ProjectSubcommand::Info(options) => options.into(),
52            ProjectSubcommand::Tags(options) => options.into(),
53            ProjectSubcommand::Members(options) => options.into(),
54        }
55    }
56}
57
58impl From<ProjectInfo> for ProjectOptions {
59    fn from(options: ProjectInfo) -> Self {
60        ProjectOptions::Info(
61            ProjectMetadataGetCliArgs::builder()
62                .id(options.id)
63                .path(options.repo)
64                .get_args(options.get_args.into())
65                .build()
66                .unwrap(),
67        )
68    }
69}
70
71impl From<ListProject> for ProjectOptions {
72    fn from(options: ListProject) -> Self {
73        ProjectOptions::Tags(
74            ProjectListCliArgs::builder()
75                .list_args(options.list_args.into())
76                .tags(true)
77                .build()
78                .unwrap(),
79        )
80    }
81}
82
83impl From<ListMembers> for ProjectOptions {
84    fn from(options: ListMembers) -> Self {
85        ProjectOptions::Members(
86            ProjectListCliArgs::builder()
87                .list_args(options.list_args.into())
88                .members(true)
89                .build()
90                .unwrap(),
91        )
92    }
93}
94
95pub enum ProjectOptions {
96    Info(ProjectMetadataGetCliArgs),
97    Tags(ProjectListCliArgs),
98    Members(ProjectListCliArgs),
99}
100
101#[cfg(test)]
102mod test {
103    use crate::cli::{Args, Command};
104
105    use super::*;
106
107    #[test]
108    fn test_project_cli_info() {
109        let args = Args::parse_from(vec!["gr", "pj", "info", "--id", "1"]);
110        let project_info = match args.command {
111            Command::Project(ProjectCommand {
112                subcommand: ProjectSubcommand::Info(options),
113            }) => {
114                assert_eq!(options.id, Some(1));
115                options
116            }
117            _ => panic!("Expected ProjectCommand::Info"),
118        };
119        let options: ProjectOptions = project_info.into();
120        match options {
121            ProjectOptions::Info(options) => {
122                assert_eq!(options.id, Some(1));
123            }
124            _ => panic!("Expected ProjectOptions::Info"),
125        }
126    }
127
128    #[test]
129    fn test_project_cli_list_tags() {
130        let args = Args::parse_from(vec!["gr", "pj", "tags"]);
131        let list_project = match args.command {
132            Command::Project(ProjectCommand {
133                subcommand: ProjectSubcommand::Tags(options),
134            }) => options,
135            _ => panic!("Expected ProjectCommand::Tags"),
136        };
137        let options: ProjectOptions = list_project.into();
138        match options {
139            ProjectOptions::Tags(cli_args) => {
140                assert!(cli_args.tags);
141                assert!(!cli_args.stars);
142                assert!(!cli_args.members);
143            }
144            _ => panic!("Expected ProjectOptions::Tags"),
145        }
146    }
147
148    #[test]
149    fn test_project_cli_list_members() {
150        let args = Args::parse_from(vec!["gr", "pj", "members"]);
151        let list_members = match args.command {
152            Command::Project(ProjectCommand {
153                subcommand: ProjectSubcommand::Members(options),
154            }) => options,
155            _ => panic!("Expected ProjectCommand::Members"),
156        };
157        let options: ProjectOptions = list_members.into();
158        match options {
159            ProjectOptions::Members(cli_args) => {
160                assert!(cli_args.members);
161                assert!(!cli_args.stars);
162                assert!(!cli_args.tags);
163            }
164            _ => panic!("Expected ProjectOptions::Members"),
165        }
166    }
167}