use std::path::{Path, PathBuf};
use clap::Parser;
use super::{AmbientError, Config, Leaf};
use ambient_ci::{project::Projects, run::cmd_run, runlog::RunLog};
#[derive(Debug, Parser)]
pub struct Run {
#[clap(long)]
projects: Option<PathBuf>,
chosen: Option<Vec<String>>,
#[clap(long)]
log: Option<PathBuf>,
#[clap(long, aliases = ["rsync", "target"])]
rsync_target: Option<String>,
#[clap(long, alias = "dput")]
dput_target: Option<String>,
#[clap(long)]
executor: Option<PathBuf>,
#[clap(long)]
dry_run: bool,
#[clap(long)]
force: bool,
#[clap(long)]
uefi: bool,
}
impl Leaf for Run {
fn run(&self, config: &Config, runlog: &mut RunLog) -> Result<(), AmbientError> {
let mut config = config.clone();
if let Some(executor) = &self.executor {
config.set_executor(Path::new(executor));
};
if let Some(s) = &self.rsync_target {
config.set_rsync_target(s);
}
if let Some(s) = &self.dput_target {
config.set_dput_target(s);
};
let projects = if let Some(filename) = &self.projects {
filename.to_path_buf()
} else {
config.projects().into()
};
let projects = Projects::from_file(&projects).map_err(RunError::Projects)?;
config.lint(&projects)?;
let result = cmd_run(
&config,
runlog,
&projects,
self.chosen.as_deref(),
self.dry_run,
self.force,
self.uefi || config.uefi(),
);
match result {
Ok(_) => (),
Err(_) => result.map_err(RunError::Run)?,
}
Ok(())
}
}
#[derive(Debug, thiserror::Error)]
pub enum RunError {
#[error(transparent)]
Run(#[from] ambient_ci::run::RunError),
#[error("failed to load projects file")]
Projects(#[source] ambient_ci::project::ProjectError),
}