1use clap::Parser;
2
3use crate::cmds::docker::{DockerImageCliArgs, DockerListCliArgs};
4
5use super::common::{GetArgs, ListArgs};
6
7#[derive(Parser)]
8pub struct DockerCommand {
9 #[clap(subcommand)]
10 subcommand: DockerSubCommand,
11}
12
13#[derive(Parser)]
14enum DockerSubCommand {
15 #[clap(about = "List Docker images")]
16 List(ListDockerImages),
17 #[clap(about = "Get docker image metadata")]
18 Image(DockerImageMetadata),
19}
20
21#[derive(Parser)]
22struct DockerImageMetadata {
23 #[clap()]
25 tag: String,
26 #[clap(long, help_heading = "Docker options")]
28 repo_id: i64,
29 #[clap(flatten)]
30 get_args: GetArgs,
31}
32
33#[derive(Parser)]
34#[clap(next_help_heading = "Docker options")]
35struct ListDockerImages {
36 #[clap(long, default_value = "false", group = "list")]
38 repos: bool,
39 #[clap(long, default_value = "false", group = "list", requires = "repo_id")]
41 tags: bool,
42 #[clap(long)]
44 repo_id: Option<i64>,
45 #[command(flatten)]
46 list_args: ListArgs,
47}
48
49impl From<DockerCommand> for DockerOptions {
50 fn from(options: DockerCommand) -> Self {
51 match options.subcommand {
52 DockerSubCommand::List(options) => options.into(),
53 DockerSubCommand::Image(options) => options.into(),
54 }
55 }
56}
57
58impl From<DockerImageMetadata> for DockerOptions {
59 fn from(options: DockerImageMetadata) -> Self {
60 DockerOptions::Get(
61 DockerImageCliArgs::builder()
62 .repo_id(options.repo_id)
63 .tag(options.tag)
64 .get_args(options.get_args.into())
65 .build()
66 .unwrap(),
67 )
68 }
69}
70
71impl From<ListDockerImages> for DockerOptions {
72 fn from(options: ListDockerImages) -> Self {
73 DockerOptions::List(
74 DockerListCliArgs::builder()
75 .repos(options.repos)
76 .tags(options.tags)
77 .repo_id(options.repo_id)
78 .list_args(options.list_args.into())
79 .build()
80 .unwrap(),
81 )
82 }
83}
84
85pub enum DockerOptions {
86 List(DockerListCliArgs),
87 Get(DockerImageCliArgs),
88}
89
90#[cfg(test)]
91mod test {
92 use crate::cli::{Args, Command};
93
94 use super::*;
95
96 #[test]
97 fn test_docker_cli_repos() {
98 let args = Args::parse_from(vec!["gr", "dk", "list", "--repos"]);
99 let list_images = match args.command {
100 Command::Docker(DockerCommand {
101 subcommand: DockerSubCommand::List(options),
102 }) => {
103 assert!(options.repos);
104 assert!(!options.tags);
105 options
106 }
107 _ => panic!("Expected DockerCommand"),
108 };
109 let options: DockerOptions = list_images.into();
110 match options {
111 DockerOptions::List(args) => {
112 assert!(args.repos);
113 assert!(!args.tags);
114 }
115 _ => panic!("Expected DockerOptions::List"),
116 }
117 }
118
119 #[test]
120 fn test_docker_cli_tags() {
121 let args = Args::parse_from(vec!["gr", "dk", "list", "--tags", "--repo-id", "12"]);
122 match args.command {
123 Command::Docker(DockerCommand {
124 subcommand: DockerSubCommand::List(options),
125 }) => {
126 assert!(!options.repos);
127 assert!(options.tags);
128 assert_eq!(options.repo_id, Some(12));
129 }
130 _ => panic!("Expected DockerCommand"),
131 }
132 }
133
134 #[test]
135 fn test_docker_get_image_metadata_cli_args() {
136 let args = Args::parse_from(vec![
137 "gr",
138 "dk",
139 "image",
140 "--refresh",
141 "--no-headers",
142 "--repo-id",
143 "123",
144 "v0.0.1",
145 ]);
146 let image_metadata = match args.command {
147 Command::Docker(DockerCommand {
148 subcommand: DockerSubCommand::Image(options),
149 }) => {
150 assert_eq!(options.repo_id, 123);
151 assert_eq!(options.tag, "v0.0.1");
152 assert!(options.get_args.cache_args.refresh);
153 assert!(options.get_args.format_args.no_headers);
154 options
155 }
156 _ => panic!("Expected DockerCommand"),
157 };
158 let options: DockerOptions = image_metadata.into();
160 match options {
161 DockerOptions::Get(args) => {
162 assert_eq!(args.repo_id, 123);
163 assert_eq!(args.tag, "v0.0.1");
164 assert!(args.get_args.cache_args.refresh);
165 assert!(args.get_args.no_headers);
166 }
167 _ => panic!("Expected DockerOptions::Get"),
168 }
169 }
170}