axl_lib/project/
group.rs

1use anyhow::Result;
2use std::{
3    collections::BTreeSet,
4    fs,
5    path::{Path, PathBuf},
6};
7use tracing::debug;
8
9use serde::{Deserialize, Serialize};
10
11use super::project_type::ConfigProject;
12
13#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
14pub struct ProjectGroupFile {
15    #[serde(skip)]
16    pub file_path: PathBuf,
17    #[serde(default = "tags_default")]
18    pub tags: BTreeSet<String>,
19    pub include: Vec<GroupItem>,
20}
21
22const fn tags_default() -> BTreeSet<String> {
23    BTreeSet::new()
24}
25
26#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
27#[serde(untagged)]
28pub enum GroupItem {
29    GroupFile(PathBuf),
30    Project(ConfigProject),
31}
32
33impl ProjectGroupFile {
34    pub fn new(path: &Path) -> Result<Self> {
35        debug!("reading projects directory file...");
36        let mut project_group_file: Self = serde_yaml::from_str(&fs::read_to_string(path)?)?;
37        project_group_file.file_path = path.to_path_buf();
38        debug!("finished reading project group file");
39        Ok(project_group_file)
40    }
41
42    pub fn get_projects(&self) -> Result<Vec<ConfigProject>> {
43        self.recurse_group_files(BTreeSet::new())
44    }
45
46    fn recurse_group_files(&self, tags: BTreeSet<String>) -> Result<Vec<ConfigProject>> {
47        let mut projects: Vec<_> = vec![];
48        let mut group_tags = tags;
49        group_tags.extend(self.tags.clone());
50        for item in self.include.clone() {
51            match item {
52                GroupItem::GroupFile(group_path) => {
53                    let config_projects = Self::new(&group_path)?
54                        .recurse_group_files(group_tags.clone())?
55                        .iter_mut()
56                        .map(|p| {
57                            p.tags.extend(group_tags.clone());
58                            p.clone()
59                        })
60                        .collect::<Vec<_>>();
61                    projects.extend(config_projects);
62                }
63                GroupItem::Project(mut p) => {
64                    p.tags.extend(group_tags.clone());
65                    projects.push(p)
66                }
67            }
68        }
69        Ok(projects)
70    }
71}