docker_wrapper/command/builder/
inspect.rs1use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub struct BuildxInspectResult {
10 pub name: Option<String>,
12 pub driver: Option<String>,
14 pub status: Option<String>,
16 pub platforms: Vec<String>,
18 pub output: String,
20 pub success: bool,
22}
23
24impl BuildxInspectResult {
25 fn parse(output: &CommandOutput) -> Self {
27 let stdout = &output.stdout;
28 let mut name = None;
29 let mut driver = None;
30 let mut status = None;
31 let mut platforms = Vec::new();
32
33 for line in stdout.lines() {
34 let line = line.trim();
35 if line.starts_with("Name:") {
36 name = Some(line.trim_start_matches("Name:").trim().to_string());
37 } else if line.starts_with("Driver:") {
38 driver = Some(line.trim_start_matches("Driver:").trim().to_string());
39 } else if line.starts_with("Status:") {
40 status = Some(line.trim_start_matches("Status:").trim().to_string());
41 } else if line.starts_with("Platforms:") {
42 let platform_str = line.trim_start_matches("Platforms:").trim();
43 platforms = platform_str
44 .split(',')
45 .map(|s| s.trim().to_string())
46 .filter(|s| !s.is_empty())
47 .collect();
48 }
49 }
50
51 Self {
52 name,
53 driver,
54 status,
55 platforms,
56 output: stdout.clone(),
57 success: output.success,
58 }
59 }
60}
61
62#[derive(Debug, Clone, Default)]
86pub struct BuildxInspectCommand {
87 name: Option<String>,
89 bootstrap: bool,
91 pub executor: CommandExecutor,
93}
94
95impl BuildxInspectCommand {
96 #[must_use]
98 pub fn new() -> Self {
99 Self::default()
100 }
101
102 #[must_use]
104 pub fn name(mut self, name: impl Into<String>) -> Self {
105 self.name = Some(name.into());
106 self
107 }
108
109 #[must_use]
111 pub fn bootstrap(mut self) -> Self {
112 self.bootstrap = true;
113 self
114 }
115
116 fn build_args(&self) -> Vec<String> {
118 let mut args = vec!["buildx".to_string(), "inspect".to_string()];
119
120 if self.bootstrap {
121 args.push("--bootstrap".to_string());
122 }
123
124 if let Some(ref name) = self.name {
125 args.push(name.clone());
126 }
127
128 args.extend(self.executor.raw_args.clone());
129
130 args
131 }
132}
133
134#[async_trait]
135impl DockerCommand for BuildxInspectCommand {
136 type Output = BuildxInspectResult;
137
138 fn get_executor(&self) -> &CommandExecutor {
139 &self.executor
140 }
141
142 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
143 &mut self.executor
144 }
145
146 fn build_command_args(&self) -> Vec<String> {
147 self.build_args()
148 }
149
150 async fn execute(&self) -> Result<Self::Output> {
151 let args = self.build_args();
152 let output = self.execute_command(args).await?;
153 Ok(BuildxInspectResult::parse(&output))
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160
161 #[test]
162 fn test_buildx_inspect_basic() {
163 let cmd = BuildxInspectCommand::new();
164 let args = cmd.build_args();
165 assert_eq!(args, vec!["buildx", "inspect"]);
166 }
167
168 #[test]
169 fn test_buildx_inspect_with_name() {
170 let cmd = BuildxInspectCommand::new().name("mybuilder");
171 let args = cmd.build_args();
172 assert!(args.contains(&"mybuilder".to_string()));
173 }
174
175 #[test]
176 fn test_buildx_inspect_with_bootstrap() {
177 let cmd = BuildxInspectCommand::new().bootstrap();
178 let args = cmd.build_args();
179 assert!(args.contains(&"--bootstrap".to_string()));
180 }
181
182 #[test]
183 fn test_buildx_inspect_all_options() {
184 let cmd = BuildxInspectCommand::new().name("mybuilder").bootstrap();
185 let args = cmd.build_args();
186 assert!(args.contains(&"--bootstrap".to_string()));
187 assert!(args.contains(&"mybuilder".to_string()));
188 }
189
190 #[test]
191 fn test_buildx_inspect_result_parse() {
192 let output = CommandOutput {
193 stdout: "Name: mybuilder\nDriver: docker-container\nStatus: running\nPlatforms: linux/amd64, linux/arm64".to_string(),
194 stderr: String::new(),
195 exit_code: 0,
196 success: true,
197 };
198 let result = BuildxInspectResult::parse(&output);
199 assert_eq!(result.name, Some("mybuilder".to_string()));
200 assert_eq!(result.driver, Some("docker-container".to_string()));
201 assert_eq!(result.status, Some("running".to_string()));
202 assert_eq!(result.platforms, vec!["linux/amd64", "linux/arm64"]);
203 }
204}