use std::collections::HashMap;
use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use lightshuttle_secrets::{EnvFileSource, SecretSource as _};
pub(crate) mod alias;
pub(crate) mod down;
pub(crate) mod export;
pub(crate) mod logs;
pub(crate) mod manifest;
pub(crate) mod ps;
pub(crate) mod restart;
pub(crate) mod secrets;
pub(crate) mod up;
pub(crate) mod validate;
#[derive(Debug, Clone, Copy)]
pub(crate) enum ExitOutcome {
Success,
LifecycleFailed,
RuntimeError,
}
impl ExitOutcome {
#[must_use]
pub(crate) fn code(self) -> i32 {
match self {
Self::Success => 0,
Self::LifecycleFailed => 1,
Self::RuntimeError => 2,
}
}
}
pub(crate) fn load_manifest(path: &Path) -> Result<lightshuttle_manifest::Manifest> {
let yaml = std::fs::read_to_string(path)?;
let mut manifest = lightshuttle_manifest::Manifest::parse(&yaml)?;
manifest.resolve_host_volume_paths(&manifest_base_dir(path));
Ok(manifest)
}
fn manifest_base_dir(path: &Path) -> std::path::PathBuf {
let dir = path
.parent()
.filter(|p| !p.as_os_str().is_empty())
.map_or_else(|| std::path::PathBuf::from("."), Path::to_path_buf);
std::env::current_dir().map_or_else(|_| dir.clone(), |cwd| cwd.join(&dir))
}
pub(crate) fn load_env(path: Option<PathBuf>) -> Result<HashMap<String, String>> {
if let Some(explicit) = path {
let source = EnvFileSource::load(&explicit)
.with_context(|| format!("failed to load --env-file {}", explicit.display()))?;
source
.load()
.with_context(|| format!("failed to read env file {}", explicit.display()))
} else {
match EnvFileSource::load_optional(".env").context("failed to parse .env")? {
Some(source) => source.load().context("failed to read .env"),
None => Ok(HashMap::new()),
}
}
}