use std::path::PathBuf;
use clap::Parser;
use serde::Serialize;
use super::{AmbientError, Config, Leaf};
use ambient_ci::{
project::{ProjectError, Projects},
runlog::RunLog,
};
#[derive(Debug, Parser)]
pub struct ProjectsCmd {
#[clap(long)]
oneline: bool,
#[clap(long)]
projects: Option<PathBuf>,
}
impl Leaf for ProjectsCmd {
fn run(&self, config: &Config, _runlog: &mut RunLog) -> Result<(), AmbientError> {
let projects = if let Some(filename) = &self.projects {
filename.to_path_buf()
} else {
config.projects().into()
};
let projects = Projects::from_file(&projects)
.map_err(|err| ProjectsCmdError::FromFile(projects, err))?;
config.lint(&projects)?;
let mut names: Vec<String> = projects.iter().map(|(name, _)| name.to_string()).collect();
names.sort();
let list = ProjectsList { projects: names };
let json = if self.oneline {
serde_json::to_string(&list).map_err(ProjectsCmdError::ToJson)?
} else {
serde_json::to_string_pretty(&list).map_err(ProjectsCmdError::ToJson)?
};
println!("{json}");
Ok(())
}
}
#[derive(Serialize)]
struct ProjectsList {
projects: Vec<String>,
}
#[derive(Debug, thiserror::Error)]
pub enum ProjectsCmdError {
#[error("failed to load project list from file {0}")]
FromFile(PathBuf, #[source] ProjectError),
#[error("failed to serialize project list to JSON")]
ToJson(#[source] serde_json::Error),
}