use clap::{Parser, Subcommand};
use lmrc_config_validator::LmrcConfig;
use lmrc_pipeline::steps::*;
use lmrc_pipeline::{Pipeline, PipelineContext, StepRegistry};
use std::path::Path;
#[derive(Parser)]
#[command(name = "pipeline")]
#[command(about = "LMRC Stack deployment pipeline", version)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Check {
#[arg(long)]
format: bool,
#[arg(long)]
clippy: bool,
},
Test,
Build {
#[arg(long)]
release: bool,
},
DockerBuild,
Provision,
Setup,
Deploy,
Full,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
let config = LmrcConfig::from_file(Path::new("lmrc.toml"))?;
match cli.command {
Commands::Check { format, clippy } => {
let ctx = PipelineContext::new(config)?;
let mut pipeline = Pipeline::new(ctx);
if format {
pipeline = pipeline.add_step(FormatCheckStep::new());
}
if clippy {
pipeline = pipeline.add_step(ClippyStep::new());
}
if !format && !clippy {
pipeline = pipeline
.add_step(FormatCheckStep::new())
.add_step(ClippyStep::new());
}
pipeline.run().await?;
}
Commands::Test => {
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx).add_step(TestStep::new()).run().await?;
}
Commands::Build { release } => {
let mut step = BuildStep::new();
if release {
step = step.release();
}
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx).add_step(step).run().await?;
}
Commands::DockerBuild => {
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx)
.add_step(DockerBuildStep::new())
.run()
.await?;
}
Commands::Provision => {
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx)
.add_step(ProvisionStep::new())
.run()
.await?;
}
Commands::Setup => {
let registry = StepRegistry::default();
let setup_steps = registry.build_setup_steps(&config);
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx)
.add_steps_arc(setup_steps)
.run()
.await?;
}
Commands::Deploy => {
let ctx = PipelineContext::new(config)?;
Pipeline::new(ctx)
.add_step(DeployStep::new())
.run()
.await?;
}
Commands::Full => {
let registry = StepRegistry::default();
let ctx = PipelineContext::new(config.clone())?;
let mut pipeline = Pipeline::new(ctx);
pipeline = pipeline.add_steps_arc(registry.build_build_steps(&config));
pipeline = pipeline.add_step(DockerBuildStep::new());
pipeline = pipeline.add_steps_arc(registry.build_provision_steps(&config));
pipeline = pipeline.add_steps_arc(registry.build_setup_steps(&config));
pipeline = pipeline.add_steps_arc(registry.build_deploy_steps(&config));
pipeline.run().await?;
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cli_structure() {
use clap::CommandFactory;
Cli::command();
}
#[test]
fn test_all_commands_exist() {
use clap::CommandFactory;
let cmd = Cli::command();
let subcommands: Vec<_> = cmd.get_subcommands().map(|s| s.get_name()).collect();
assert!(subcommands.contains(&"check"));
assert!(subcommands.contains(&"test"));
assert!(subcommands.contains(&"build"));
assert!(subcommands.contains(&"docker-build"));
assert!(subcommands.contains(&"provision"));
assert!(subcommands.contains(&"setup"));
assert!(subcommands.contains(&"deploy"));
assert!(subcommands.contains(&"full"));
}
}