glory_cli/config/
mod.rs

1#[cfg(test)]
2mod tests;
3
4mod assets;
5mod bin_package;
6mod cli;
7mod dotenvs;
8mod end2end;
9mod lib_package;
10mod profile;
11mod project;
12mod style;
13mod tailwind;
14
15use std::{fmt::Debug, sync::Arc};
16
17pub use self::cli::{Cli, Commands, Log, Opts};
18use crate::ext::{
19    anyhow::{Context, Result},
20    MetadataExt,
21};
22use anyhow::bail;
23use camino::{Utf8Path, Utf8PathBuf};
24use cargo_metadata::Metadata;
25pub use profile::Profile;
26pub use project::{Project, ProjectConfig};
27pub use style::StyleConfig;
28pub use tailwind::TailwindConfig;
29
30pub struct Config {
31    /// absolute path to the working dir
32    pub working_dir: Utf8PathBuf,
33    pub projects: Vec<Arc<Project>>,
34    pub cli: Opts,
35    pub watch: bool,
36}
37
38impl Debug for Config {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        f.debug_struct("Config")
41            .field("projects", &self.projects)
42            .field("cli", &self.cli)
43            .field("watch", &self.watch)
44            .finish_non_exhaustive()
45    }
46}
47
48impl Config {
49    pub fn load(cli: Opts, cwd: &Utf8Path, manifest_path: &Utf8Path, watch: bool) -> Result<Self> {
50        let metadata = Metadata::load_cleaned(manifest_path)?;
51
52        let mut projects = Project::resolve(&cli, cwd, &metadata, watch).dot()?;
53
54        if projects.is_empty() {
55            bail!("Please define glory projects in the workspace Cargo.toml sections [[workspace.metadata.glory]]")
56        }
57
58        if let Some(proj_name) = &cli.project {
59            if let Some(proj) = projects.iter().find(|p| p.name == *proj_name) {
60                projects = vec![proj.clone()];
61            } else {
62                bail!(
63                    r#"The specified project "{proj_name}" not found. Available projects: {}"#,
64                    names(&projects)
65                )
66            }
67        }
68
69        Ok(Self {
70            working_dir: metadata.workspace_root,
71            projects,
72            cli,
73            watch,
74        })
75    }
76
77    #[cfg(test)]
78    pub fn test_load(cli: Opts, cwd: &str, manifest_path: &str, watch: bool) -> Self {
79        use crate::ext::PathBufExt;
80
81        let manifest_path = Utf8PathBuf::from(manifest_path).canonicalize_utf8().unwrap();
82        let mut cwd = Utf8PathBuf::from(cwd).canonicalize_utf8().unwrap();
83        cwd.clean_windows_path();
84        Self::load(cli, &cwd, &manifest_path, watch).unwrap()
85    }
86
87    pub fn current_project(&self) -> Result<Arc<Project>> {
88        if self.projects.len() == 1 {
89            Ok(self.projects[0].clone())
90        } else {
91            bail!(
92                "There are several projects available ({}). Please select one of them with the command line parameter --project",
93                names(&self.projects)
94            );
95        }
96    }
97}
98
99fn names(projects: &[Arc<Project>]) -> String {
100    projects.iter().map(|p| p.name.clone()).collect::<Vec<_>>().join(", ")
101}