projects.rs
1 use std::path::PathBuf; 2 3 use clap::Parser; 4 use serde::Serialize; 5 6 use super::{AmbientError, Config, Leaf}; 7 use ambient_ci::{ 8 project::{ProjectError, Projects}, 9 runlog::RunLog, 10 }; 11 12 #[derive(Debug, Parser)] 13 pub struct ProjectsCmd { 14 #[clap(long)] 15 oneline: bool, 16 17 /// Name of YAML file with projects. 18 #[clap(long)] 19 projects: Option<PathBuf>, 20 } 21 22 impl Leaf for ProjectsCmd { 23 fn run(&self, config: &Config, _runlog: &mut RunLog) -> Result<(), AmbientError> { 24 let projects = if let Some(filename) = &self.projects { 25 filename.to_path_buf() 26 } else { 27 config.projects().into() 28 }; 29 30 let projects = Projects::from_file(&projects) 31 .map_err(|err| ProjectsCmdError::FromFile(projects, err))?; 32 33 config.lint(&projects)?; 34 35 let mut names: Vec<String> = projects.iter().map(|(name, _)| name.to_string()).collect(); 36 names.sort(); 37 38 let list = ProjectsList { projects: names }; 39 40 let json = if self.oneline { 41 serde_json::to_string(&list).map_err(ProjectsCmdError::ToJson)? 42 } else { 43 serde_json::to_string_pretty(&list).map_err(ProjectsCmdError::ToJson)? 44 }; 45 46 println!("{json}"); 47 48 Ok(()) 49 } 50 } 51 52 #[derive(Serialize)] 53 struct ProjectsList { 54 projects: Vec<String>, 55 } 56 57 #[derive(Debug, thiserror::Error)] 58 pub enum ProjectsCmdError { 59 #[error("failed to load project list from file {0}")] 60 FromFile(PathBuf, #[source] ProjectError), 61 62 #[error("failed to serialize project list to JSON")] 63 ToJson(#[source] serde_json::Error), 64 }