docker_wrapper/compose/
exec.rs1use super::{execute_compose_command, ComposeCommand, ComposeConfig, ComposeOutput};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone, Default)]
9#[allow(dead_code)] pub struct ComposeExecCommand {
11 config: ComposeConfig,
12 service: String,
13 command: Vec<String>,
14 detach: bool,
15 user: Option<String>,
16 workdir: Option<String>,
17}
18
19impl ComposeExecCommand {
20 #[must_use]
22 pub fn new(service: impl Into<String>) -> Self {
23 Self {
24 service: service.into(),
25 ..Self::default()
26 }
27 }
28
29 pub async fn run(&self) -> Result<ComposeOutput> {
35 self.execute().await
36 }
37}
38
39#[async_trait]
40impl ComposeCommand for ComposeExecCommand {
41 type Output = ComposeOutput;
42
43 fn subcommand(&self) -> &'static str {
44 "exec"
45 }
46
47 fn build_args(&self) -> Vec<String> {
48 let mut args = vec![self.service.clone()];
49 args.extend(self.command.clone());
50 args
51 }
52
53 async fn execute(&self) -> Result<Self::Output> {
54 execute_compose_command(&self.config, self.subcommand(), self.build_args()).await
55 }
56
57 fn config(&self) -> &ComposeConfig {
58 &self.config
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_compose_exec_basic() {
68 let cmd = ComposeExecCommand::new("web");
69 assert_eq!(cmd.service, "web");
70 assert_eq!(cmd.subcommand(), "exec");
71 let args = cmd.build_args();
72 assert_eq!(args, vec!["web"]);
73 }
74
75 #[test]
76 fn test_compose_exec_with_command() {
77 let mut cmd = ComposeExecCommand::new("db");
78 cmd.command = vec!["psql".to_string(), "-U".to_string(), "postgres".to_string()];
79
80 let args = cmd.build_args();
81 assert_eq!(args, vec!["db", "psql", "-U", "postgres"]);
82 }
83
84 #[test]
85 fn test_compose_exec_with_config() {
86 let config = ComposeConfig::new()
87 .file("docker-compose.yml")
88 .project_name("myapp");
89
90 let mut cmd = ComposeExecCommand::new("web");
91 cmd.config = config;
92 cmd.command = vec!["bash".to_string()];
93
94 assert_eq!(cmd.config().project_name, Some("myapp".to_string()));
95 assert_eq!(cmd.build_args(), vec!["web", "bash"]);
96 }
97
98 #[test]
99 fn test_compose_exec_future_options() {
100 let cmd = ComposeExecCommand {
102 config: ComposeConfig::new(),
103 service: "app".to_string(),
104 command: vec!["sh".to_string()],
105 detach: true,
106 user: Some("root".to_string()),
107 workdir: Some("/app".to_string()),
108 };
109
110 let args = cmd.build_args();
112 assert_eq!(args, vec!["app", "sh"]);
113
114 }
121}