tracel_xtask/commands/
docker.rs

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