storm_workspace/
utils.rs

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
45/// Get the workspace root
46///
47/// This function will return the workspace root directory by checking the current directory and its ancestors for the presence of a workspace root file.
48///
49/// The file list checked to determine the workspace root directory include:
50/// - storm.json
51/// - storm.toml
52/// - storm.yaml
53/// - storm.yml
54/// - storm.xml
55/// - storm.config.js
56/// - storm.config.ts
57/// - .storm.json
58/// - .storm.yaml
59/// - .storm.yml
60/// - .storm.js
61/// - .storm.ts
62/// - lerna.json
63/// - nx.json
64/// - turbo.json
65/// - Cargo.lock
66/// - npm-workspace.json
67/// - yarn-workspace.json
68/// - pnpm-workspace.json
69/// - npm-workspace.yaml
70/// - yarn-workspace.yaml
71/// - pnpm-workspace.yaml
72/// - npm-workspace.yml
73/// - yarn-workspace.yml
74/// - pnpm-workspace.yml
75/// - npm-lock.json
76/// - yarn-lock.json
77/// - pnpm-lock.json
78/// - npm-lock.yaml
79/// - yarn-lock.yaml
80/// - pnpm-lock.yaml
81/// - npm-lock.yml
82/// - yarn-lock.yml
83/// - pnpm-lock.yml
84/// - bun.lockb
85///
86/// ```rust,no_run
87/// use storm_workspace::utils::get_workspace_root;
88///
89/// match get_workspace_root() {
90///     Ok(p) => println!("Current project root is {:?}", p),
91///     Err(e) => println!("Error obtaining project root {:?}", e)
92/// };
93/// ```
94pub 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}