Files
ahab/src/cmd/compose.rs

137 lines
2.9 KiB
Rust

use super::{Argv, Cmd};
use crate::ctx::Ctx;
// compose prints its own progress, which --quiet has to ask it to stop
fn compose(quiet: bool) -> Argv {
let argv = Argv::new("docker").arg("compose");
match quiet {
true => argv.flag("--progress", "quiet"),
false => argv,
}
}
// the compose commands, each already knowing whether -q asked compose to stop
// narrating. the flag was a field every construction site set by hand, and
// three of them did not, so `ahab -q` still had compose talking over the output
pub struct Compose<'a> {
ctx: &'a Ctx,
}
impl<'a> Compose<'a> {
pub(crate) fn new(ctx: &'a Ctx) -> Self {
Self { ctx }
}
pub fn up(&self) -> Up {
Up {
quiet: self.ctx.quiet,
}
}
pub fn stop(&self) -> Stop {
Stop {
quiet: self.ctx.quiet,
}
}
pub fn start(&self, service: &'a str) -> Start<'a> {
Start {
service,
quiet: self.ctx.quiet,
}
}
// reading the project says nothing, so there is no progress to quieten
pub fn config(&self) -> Config {
Config
}
pub fn ps(&self, service: &str) -> Ps {
Ps {
service: service.to_string(),
}
}
}
// docker compose run --rm, which runs the image's entrypoint and so fixes up the
// container user before handing over
pub struct Run {
service: String,
inner: Argv,
quiet: bool,
}
impl Run {
// only reached through Cmd::in_service, which takes the context, so the
// progress flag cannot be left off by forgetting a builder call
pub(super) fn wrapping(ctx: &Ctx, service: &str, inner: Argv) -> Self {
Self {
service: service.to_string(),
inner,
quiet: ctx.quiet,
}
}
}
impl Cmd for Run {
fn argv(&self) -> Argv {
compose(self.quiet)
.arg("run")
.arg("--rm")
.arg(&self.service)
.args(self.inner.words())
}
}
// the merged project file, with every extends and env_file resolved
pub struct Config;
impl Cmd for Config {
fn argv(&self) -> Argv {
compose(false).arg("config").flag("--format", "json")
}
}
// the container id a service is running as, empty when it is not running
pub struct Ps {
service: String,
}
impl Cmd for Ps {
fn argv(&self) -> Argv {
compose(false).arg("ps").arg("--quiet").arg(&self.service)
}
}
pub struct Up {
quiet: bool,
}
impl Cmd for Up {
fn argv(&self) -> Argv {
compose(self.quiet).arg("up").arg("--detach")
}
}
pub struct Start<'a> {
service: &'a str,
quiet: bool,
}
impl Cmd for Start<'_> {
fn argv(&self) -> Argv {
compose(self.quiet).arg("start").arg(self.service)
}
}
pub struct Stop {
quiet: bool,
}
impl Cmd for Stop {
fn argv(&self) -> Argv {
compose(self.quiet).arg("stop")
}
}