use std::process::Command as StdCommand;
use crate::prelude::{Context, Environment, run_process};
#[tracel_xtask_macros::declare_command_args(None, DockerComposeSubCommand)]
pub struct DockerComposeCmdArgs {}
pub fn handle_command(
args: DockerComposeCmdArgs,
env: Environment,
_ctx: Context,
) -> anyhow::Result<()> {
match args.get_command() {
DockerComposeSubCommand::Up => {
up_docker_compose(&env, &args.project, args.build, args.services)
}
DockerComposeSubCommand::Down => down_docker_compose(&env, &args.project),
}
}
fn get_config_filename(config: &str) -> String {
format!("docker-compose.{config}.yml")
}
pub fn up_docker_compose(
env: &Environment,
project: &str,
build: bool,
services: Vec<String>,
) -> anyhow::Result<()> {
let env_name = env.to_string();
let project = format!("{project}-{env_name}");
let config = get_config_filename(&env_name);
let env_files = env.get_env_files();
let mut args = vec!["compose", "-f", &config, "-p", &project];
env_files.iter().for_each(|f| {
let path = std::path::Path::new(f);
if path.exists() {
args.extend(vec!["--env-file", f]);
}
});
args.extend(vec!["up", "-d"]);
if build {
args.extend(vec!["--build"]);
}
args.extend(services.iter().map(String::as_str));
let result = run_process(
"docker",
&args,
None,
None,
"Failed to execute 'docker compose' to start the container!",
);
if result.is_err() {
run_process(
"docker-compose",
&args[1..],
None,
None,
"Failed to execute 'docker compose' to start the container!",
)
} else {
result
}
}
pub fn down_docker_compose(env: &Environment, project: &str) -> anyhow::Result<()> {
let env_name = env.to_string();
let project = format!("{project}-{env_name}");
let config = get_config_filename(&env_name);
let env_files = env.get_env_files();
let mut args = vec!["compose", "-f", &config, "-p", &project];
env_files.iter().for_each(|f| {
let path = std::path::Path::new(f);
if path.exists() {
args.extend(vec!["--env-file", f]);
}
});
args.extend(vec!["down"]);
let result = run_process(
"docker",
&args,
None,
None,
"Failed to execute 'docker compose' to stop the container!",
);
if result.is_err() {
run_process(
"docker-compose",
&args[1..],
None,
None,
"Failed to execute 'docker compose' to stop the container!",
)
} else {
result
}
}
pub fn tail_container_command(container_name: &str) -> StdCommand {
let mut command = StdCommand::new("docker");
command.args(["logs", "-f", container_name]);
command
}