use crate::{Project, Service};
use std::env;
use std::process::Command;
use tracing::{debug, instrument};
const CONTEXT_PROJECT_ROOT_VAR: &str = "ORCS_ROOT";
const CONTEXT_SERVICE_VAR: &str = "ORCS_SERVICE";
const CONTEXT_SERVICE_ROOT_VAR: &str = "ORCS_SERVICE_ROOT";
const CONTEXT_STAGE_VAR: &str = "ORCS_STAGE";
#[derive(Clone)]
pub struct StageContext {
pub stage: String,
pub service: String,
}
impl StageContext {
#[instrument]
pub fn new(stage: &str, service: &str) -> StageContext {
debug!("Create new stage context");
StageContext {
stage: stage.to_string(),
service: service.to_string(),
}
}
#[instrument]
pub fn from_env() -> Option<StageContext> {
debug!("Retrieve stage context from environment");
let stage = match env::var(CONTEXT_STAGE_VAR) {
Ok(value) => value,
Err(_) => return None,
};
let service = match env::var(CONTEXT_SERVICE_VAR) {
Ok(value) => value,
Err(_) => return None,
};
Some(Self { stage, service })
}
}
pub trait CommandExt {
fn with_context(&mut self, project: &Project, service: &Service, stage_name: &str)
-> &mut Self;
}
impl CommandExt for Command {
fn with_context(
&mut self,
project: &Project,
service: &Service,
stage_name: &str,
) -> &mut Self {
self.env(CONTEXT_PROJECT_ROOT_VAR, project.canonical_path())
.env(CONTEXT_SERVICE_VAR, &service.name)
.env(CONTEXT_SERVICE_ROOT_VAR, service.path())
.env(CONTEXT_STAGE_VAR, stage_name)
}
}