tracel_xtask/commands/
docker_compose.rs1use std::process::Command as StdCommand;
2
3use crate::prelude::{Context, Environment, run_process};
4
5#[tracel_xtask_macros::declare_command_args(None, DockerComposeSubCommand)]
6pub struct DockerComposeCmdArgs {}
7
8pub fn handle_command(
9 args: DockerComposeCmdArgs,
10 env: Environment,
11 _ctx: Context,
12) -> anyhow::Result<()> {
13 match args.get_command() {
14 DockerComposeSubCommand::Up => {
15 up_docker_compose(&env, &args.project, args.build, args.services)
16 }
17 DockerComposeSubCommand::Down => down_docker_compose(&env, &args.project),
18 }
19}
20
21fn get_config_filename(config: &str) -> String {
22 format!("docker-compose.{config}.yml")
23}
24
25pub fn up_docker_compose(
26 env: &Environment,
27 project: &str,
28 build: bool,
29 services: Vec<String>,
30) -> anyhow::Result<()> {
31 let env_name = env.to_string();
32 let project = format!("{project}-{env_name}");
33 let config = get_config_filename(&env_name);
34 let env_files = env.get_env_files();
35 let mut args = vec!["compose", "-f", &config, "-p", &project];
36 env_files.iter().for_each(|f| {
37 let path = std::path::Path::new(f);
38 if path.exists() {
39 args.extend(vec!["--env-file", f]);
40 }
41 });
42 args.extend(vec!["up", "-d"]);
43 if build {
44 args.extend(vec!["--build"]);
45 }
46 args.extend(services.iter().map(String::as_str));
47 let result = run_process(
48 "docker",
49 &args,
50 None,
51 None,
52 "Failed to execute 'docker compose' to start the container!",
53 );
54 if result.is_err() {
55 run_process(
56 "docker-compose",
57 &args[1..],
58 None,
59 None,
60 "Failed to execute 'docker compose' to start the container!",
61 )
62 } else {
63 result
64 }
65}
66
67pub fn down_docker_compose(env: &Environment, project: &str) -> anyhow::Result<()> {
68 let env_name = env.to_string();
69 let project = format!("{project}-{env_name}");
70 let config = get_config_filename(&env_name);
71 let env_files = env.get_env_files();
72 let mut args = vec!["compose", "-f", &config, "-p", &project];
73 env_files.iter().for_each(|f| {
74 let path = std::path::Path::new(f);
75 if path.exists() {
76 args.extend(vec!["--env-file", f]);
77 }
78 });
79 args.extend(vec!["down"]);
80 let result = run_process(
81 "docker",
82 &args,
83 None,
84 None,
85 "Failed to execute 'docker compose' to stop the container!",
86 );
87 if result.is_err() {
88 run_process(
89 "docker-compose",
90 &args[1..],
91 None,
92 None,
93 "Failed to execute 'docker compose' to stop the container!",
94 )
95 } else {
96 result
97 }
98}
99
100pub fn tail_container_command(container_name: &str) -> StdCommand {
101 let mut command = StdCommand::new("docker");
102 command.args(["logs", "-f", container_name]);
103 command
104}