#![allow(dead_code)]
mod compose;
mod containers;
mod installation;
mod types;
pub use types::{ContainerInfo, DockerInfo};
use anyhow::Result;
use std::path::Path;
use std::time::Duration;
pub struct DockerService {
compose_file: Option<String>,
}
impl DockerService {
pub fn new() -> Self {
Self { compose_file: None }
}
pub fn with_compose_file(compose_file: impl Into<String>) -> Self {
Self {
compose_file: Some(compose_file.into()),
}
}
pub fn check_installation(&self) -> Result<DockerInfo> {
installation::check_installation()
}
pub fn check_daemon(&self) -> Result<()> {
installation::check_daemon()
}
pub fn compose_build(&self, service: Option<&str>) -> Result<()> {
compose::compose_build(self.compose_file.as_deref(), service)
}
pub async fn compose_up(&self, detach: bool) -> Result<()> {
compose::compose_up(self.compose_file.as_deref(), detach).await
}
pub async fn compose_up_service(&self, service: &str, detach: bool) -> Result<()> {
compose::compose_up_service(self.compose_file.as_deref(), service, detach).await
}
pub async fn compose_run_service(
&self,
service: &str,
detach: bool,
service_ports: bool,
command_args: &[String],
) -> Result<()> {
compose::compose_run_service(
self.compose_file.as_deref(),
service,
detach,
service_ports,
command_args,
)
.await
}
pub async fn compose_stop(&self, service: Option<&str>) -> Result<()> {
compose::compose_stop(self.compose_file.as_deref(), service).await
}
pub async fn compose_down(&self) -> Result<()> {
compose::compose_down(self.compose_file.as_deref()).await
}
pub async fn compose_restart(&self, service: Option<&str>) -> Result<()> {
compose::compose_restart(self.compose_file.as_deref(), service).await
}
pub fn compose_logs(&self, service: Option<&str>, follow: bool, tail: Option<usize>) -> Result<()> {
compose::compose_logs(self.compose_file.as_deref(), service, follow, tail)
}
pub async fn is_container_running(&self, container_name: &str) -> Result<bool> {
containers::is_container_running(container_name).await
}
pub async fn list_containers(&self) -> Result<Vec<ContainerInfo>> {
containers::list_containers().await
}
pub fn compose_file_exists(&self, path: Option<&Path>) -> bool {
containers::compose_file_exists(self.compose_file.as_deref(), path)
}
pub async fn wait_for_healthy(&self, container_name: &str, timeout: Duration) -> Result<()> {
containers::wait_for_healthy(container_name, timeout).await
}
pub async fn start_project_services(&self, services: &[String], project_name: &str) -> Result<bool> {
if services.is_empty() {
return Ok(false);
}
let mut all_running = true;
for service in services {
let container_name = format!("{}-{}", project_name, service);
if !self.is_container_running(&container_name).await.unwrap_or(false) {
all_running = false;
break;
}
}
if all_running {
return Ok(false); }
for service in services {
self.compose_up_service(service, true).await?;
}
tokio::time::sleep(Duration::from_secs(2)).await;
Ok(true) }
}
impl Default for DockerService {
fn default() -> Self {
Self::new()
}
}