1use std::env;
2use std::fs::read_dir;
3use std::path::PathBuf;
4
5use crate::errors::StormWorkspaceError;
6
7const WORKSPACE_ROOT_FILES: [&str; 35] = [
8 "storm.json",
9 "storm.toml",
10 "storm.yaml",
11 "storm.yml",
12 "storm.xml",
13 "storm.config.js",
14 "storm.config.ts",
15 ".storm.json",
16 ".storm.yaml",
17 ".storm.yml",
18 ".storm.js",
19 ".storm.ts",
20 "lerna.json",
21 "nx.json",
22 "turbo.json",
23 "Cargo.lock",
24 "npm-workspace.json",
25 "yarn-workspace.json",
26 "pnpm-workspace.json",
27 "npm-workspace.yaml",
28 "yarn-workspace.yaml",
29 "pnpm-workspace.yaml",
30 "npm-workspace.yml",
31 "yarn-workspace.yml",
32 "pnpm-workspace.yml",
33 "npm-lock.json",
34 "yarn-lock.json",
35 "pnpm-lock.json",
36 "npm-lock.yaml",
37 "yarn-lock.yaml",
38 "pnpm-lock.yaml",
39 "npm-lock.yml",
40 "yarn-lock.yml",
41 "pnpm-lock.yml",
42 "bun.lockb",
43];
44
45pub fn get_workspace_root() -> Result<PathBuf, StormWorkspaceError> {
95 match env::var("STORM_WORKSPACE_ROOT") {
96 Ok(workspace_root) => {
97 return Ok(PathBuf::from(workspace_root));
98 }
99 Err(_) => {}
100 }
101 match env::var("NX_WORKSPACE_ROOT") {
102 Ok(workspace_root) => {
103 return Ok(PathBuf::from(workspace_root));
104 }
105 Err(_) => {}
106 }
107
108 match env::current_dir() {
109 Ok(path) => {
110 let mut path_ancestors = path.as_path().ancestors();
111
112 while let Some(p) = path_ancestors.next() {
113 match read_dir(p) {
114 Ok(dir) => {
115 if dir
116 .into_iter()
117 .any(|p| WORKSPACE_ROOT_FILES.contains(&p.unwrap().file_name().to_str().unwrap()))
118 {
119 return Ok(PathBuf::from(p));
120 }
121 }
122
123 Err(_) => {
124 return Err(StormWorkspaceError::ReadDirectoryFailure(p.to_str().unwrap().to_string()))
125 }
126 }
127 }
128 Err(StormWorkspaceError::WorkspaceRootNotFound(
129 WORKSPACE_ROOT_FILES.iter().map(|f| f.to_string()).collect::<Vec<String>>().join(", \r\n"),
130 ))
131 }
132 Err(_) => Err(StormWorkspaceError::NoCurrentDirectory),
133 }
134}