hawk_cli/models/
config.rs1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::fs;
4use std::path::Path;
5
6use crate::models::environment_files::{list_dirs, search_file, PackageJson, PnpmWorkspace};
7use crate::models::files;
8use crate::models::files::File;
9use crate::models::workspace;
10
11pub type Result<T> = std::result::Result<T, ConfigError>;
12
13#[derive(Debug)]
14pub enum ConfigError {
15 YamlError(serde_yaml::Error),
16 FileNotFound,
17 Any,
18}
19
20impl fmt::Display for ConfigError {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 match self {
23 ConfigError::FileNotFound => write!(f, "Could not find config file"),
24 ConfigError::YamlError(err) => {
25 write!(f, "{}", err)
26 }
27 ConfigError::Any => {
28 write!(f, "Something went wrong")
29 }
30 }
31 }
32}
33
34#[derive(Debug, Clone, Deserialize, Serialize)]
35pub struct Config {
36 pub workspaces: Vec<workspace::Workspace>,
37 pub target: String,
38}
39
40impl Config {
41 #[deprecated(since = "1.0.3")]
42 pub fn load_old(filepath: &str) -> Result<Config> {
43 if !Path::new(filepath).exists() {
44 return Err(ConfigError::FileNotFound);
45 }
46
47 let f = fs::File::open(filepath).expect("Unable to open file");
48
49 match serde_yaml::from_reader(f) {
50 Ok(data) => Ok(data),
51 Err(e) => Err(ConfigError::YamlError(e)),
52 }
53 }
54
55 #[deprecated(since = "1.0.3")]
56 pub fn validate_workspaces(&self) -> workspace::Result<()> {
57 for workspace in &self.workspaces {
58 workspace.validate_name()?;
59 workspace.validate_path()?;
60 }
61
62 Ok(())
63 }
64
65 pub fn new(target: &str) -> Config {
66 Config {
67 target: target.into(),
68 workspaces: Vec::new(),
69 }
70 }
71
72 pub fn init(target: &str, workflows_dir: &str) -> files::Result<Config> {
75 let mut config = Config::new(target);
76 let package_json_path = search_file(".", "package.json");
77 let pnpm_workspace_path = search_file(".", "pnpm-workspace.yaml");
78
79 if pnpm_workspace_path.is_some() {
80 let mut workspaces: Vec<workspace::Workspace> = Vec::new();
81 let pnpm_workspace: PnpmWorkspace = PnpmWorkspace::load(&pnpm_workspace_path.unwrap())?;
82
83 for el in pnpm_workspace.packages {
84 add_workspaces(
85 &mut workspaces,
86 Path::new(&format!("./{}", el.replace("/*", ""))),
87 workflows_dir,
88 )?;
89 }
90
91 config.workspaces = workspaces;
92
93 return Ok(config);
94 }
95
96 if let Some(path) = package_json_path {
97 let package_json = PackageJson::load(&path)?;
98 let mut workspaces: Vec<workspace::Workspace> = Vec::new();
99
100 if !package_json.clone().has_workspaces() {
101 return Ok(config);
102 }
103
104 for el in package_json.workspaces.unwrap() {
105 add_workspaces(
106 &mut workspaces,
107 Path::new(&format!("./{}", el.replace("/*", ""))),
108 workflows_dir,
109 )?;
110 }
111
112 config.workspaces = workspaces;
113 }
114
115 Ok(config)
116 }
117}
118
119fn add_workspaces(
120 workspaces: &mut Vec<workspace::Workspace>,
121 directory: &Path,
122 workflows_dir: &str,
123) -> files::Result<()> {
124 for dir in list_dirs(directory) {
125 if search_file(dir.to_str().unwrap(), "package.json").is_some() {
126 let pkg = PackageJson::load(dir.join("package.json").as_path())
127 .expect("could not find package json");
128
129 let wk = workspace::Workspace {
130 name: pkg.name,
131 package_json: Some(dir.to_str().unwrap().into()),
132 path: dir.join(workflows_dir).to_str().unwrap_or_default().into(),
133 };
134
135 workspaces.push(wk);
136 } else {
137 workspaces.push(workspace::Workspace {
138 name: dir.file_stem().unwrap().to_str().unwrap().into(),
139 package_json: None,
140 path: dir.join(workflows_dir).to_str().unwrap_or_default().into(),
141 });
142 }
143 }
144
145 Ok(())
146}
147
148impl File<Config> for Config {}