use std::env;
use std::fs::read_dir;
use std::path::PathBuf;
use crate::errors::StormWorkspaceError;
const WORKSPACE_ROOT_FILES: [&str; 35] = [
"storm-workspace.json",
"storm-workspace.toml",
"storm-workspace.yaml",
"storm-workspace.yml",
"storm-workspace.xml",
"storm-workspace.config.js",
"storm-workspace.config.ts",
".storm-workspace.json",
".storm-workspace.yaml",
".storm-workspace.yml",
".storm-workspace.js",
".storm-workspace.ts",
"lerna.json",
"nx.json",
"turbo.json",
"Cargo.lock",
"npm-workspace.json",
"yarn-workspace.json",
"pnpm-workspace.json",
"npm-workspace.yaml",
"yarn-workspace.yaml",
"pnpm-workspace.yaml",
"npm-workspace.yml",
"yarn-workspace.yml",
"pnpm-workspace.yml",
"npm-lock.json",
"yarn-lock.json",
"pnpm-lock.json",
"npm-lock.yaml",
"yarn-lock.yaml",
"pnpm-lock.yaml",
"npm-lock.yml",
"yarn-lock.yml",
"pnpm-lock.yml",
"bun.lockb",
];
pub fn get_workspace_root() -> Result<PathBuf, StormWorkspaceError> {
if let Ok(workspace_root) = env::var("STORM_WORKSPACE_ROOT") {
return Ok(PathBuf::from(workspace_root));
}
if let Ok(workspace_root) = env::var("NX_WORKSPACE_ROOT") {
return Ok(PathBuf::from(workspace_root));
}
if let Ok(workspace_root) = env::var("WORKSPACE_DIR") {
return Ok(PathBuf::from(workspace_root));
}
if let Ok(workspace_root) = env::var("CARGO_WORKSPACE_DIR") {
return Ok(PathBuf::from(workspace_root));
}
match env::current_dir() {
Ok(path) => {
let mut path_ancestors = path.as_path().ancestors();
while let Some(p) = path_ancestors.next() {
match read_dir(p) {
Ok(dir) => {
if dir
.into_iter()
.any(|p| WORKSPACE_ROOT_FILES.contains(&p.unwrap().file_name().to_str().unwrap()))
{
return Ok(PathBuf::from(p));
}
}
Err(_) => {
return Err(StormWorkspaceError::ReadDirectoryFailure(p.to_str().unwrap().to_string()));
}
}
}
Err(StormWorkspaceError::WorkspaceRootNotFound(
WORKSPACE_ROOT_FILES.iter().map(|f| f.to_string()).collect::<Vec<String>>().join(", \r\n"),
))
}
Err(_) => Err(StormWorkspaceError::NoCurrentDirectory),
}
}