orcs 0.0.8

Microservices monorepo orchestration tool
Documentation
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)
    }
}