run.rs
1 use std::path::{Path, PathBuf}; 2 3 use clap::Parser; 4 5 use super::{AmbientError, Config, Leaf}; 6 use ambient_ci::{project::Projects, run::cmd_run, runlog::RunLog}; 7 8 /// Run CI on projects. 9 #[derive(Debug, Parser)] 10 pub struct Run { 11 /// Project specification file. May contain any number of projects. 12 #[clap(long)] 13 projects: Option<PathBuf>, 14 15 /// Which projects to run CI for, from the ones in the PROJECTS 16 /// file. Default is all of them. 17 chosen: Option<Vec<String>>, 18 19 /// Run log. 20 #[clap(long)] 21 log: Option<PathBuf>, 22 23 /// rsync target for publishing artifacts with rsync program. 24 #[clap(long, aliases = ["rsync", "target"])] 25 rsync_target: Option<String>, 26 27 /// dput target for publishing .deb package. 28 #[clap(long, alias = "dput")] 29 dput_target: Option<String>, 30 31 /// Path to `ambient-execute-plan` binary to use to run CI in VM. 32 #[clap(long)] 33 executor: Option<PathBuf>, 34 35 /// Only pretend to run CI. 36 #[clap(long)] 37 dry_run: bool, 38 39 /// Run even if repository hasn't changed. 40 #[clap(long)] 41 force: bool, 42 43 /// Use UEFI with VM. 44 #[clap(long)] 45 uefi: bool, 46 } 47 48 impl Leaf for Run { 49 fn run(&self, config: &Config, runlog: &mut RunLog) -> Result<(), AmbientError> { 50 let mut config = config.clone(); 51 52 if let Some(executor) = &self.executor { 53 config.set_executor(Path::new(executor)); 54 }; 55 56 if let Some(s) = &self.rsync_target { 57 config.set_rsync_target(s); 58 } 59 60 if let Some(s) = &self.dput_target { 61 config.set_dput_target(s); 62 }; 63 64 let projects = if let Some(filename) = &self.projects { 65 filename.to_path_buf() 66 } else { 67 config.projects().into() 68 }; 69 let projects = Projects::from_file(&projects).map_err(RunError::Projects)?; 70 71 config.lint(&projects)?; 72 73 let result = cmd_run( 74 &config, 75 runlog, 76 &projects, 77 self.chosen.as_deref(), 78 self.dry_run, 79 self.force, 80 self.uefi || config.uefi(), 81 ); 82 match result { 83 Ok(_) => (), 84 // Err(ambient_ci::run::RunError::RunFailed) => (), 85 Err(_) => result.map_err(RunError::Run)?, 86 } 87 88 Ok(()) 89 } 90 } 91 92 #[derive(Debug, thiserror::Error)] 93 pub enum RunError { 94 #[error(transparent)] 95 Run(#[from] ambient_ci::run::RunError), 96 97 #[error("failed to load projects file")] 98 Projects(#[source] ambient_ci::project::ProjectError), 99 }