use crate::prelude::*;
use std::path::PathBuf;
pub fn find_project_root(start_dir: &Path) -> Option<PathBuf> {
let mut dir = start_dir;
loop {
if dir.join(".wsb").join("state.json").exists() {
return Some(dir.to_path_buf());
}
dir = dir.parent()?;
}
}
pub fn find_super_root(start_dir: &Path) -> Option<PathBuf> {
let repo = gix::discover(start_dir).ok()?;
let workdir = repo.workdir()?.to_path_buf();
let mut current = workdir;
while let Some(parent) = current.parent() {
if parent == current {
break;
}
if parent.join(".git").exists() {
if let Ok(parent_repo) = gix::discover(parent) {
if let Some(parent_workdir) = parent_repo.workdir() {
let parent_workdir = parent_workdir.to_path_buf();
if current.starts_with(&parent_workdir) {
current = parent_workdir;
continue;
}
}
}
}
break;
}
Some(current)
}
pub fn find_super_root_or_project(start_dir: &Path) -> PathBuf {
find_super_root(start_dir)
.or_else(|| find_project_root(start_dir))
.unwrap_or_else(|| start_dir.to_path_buf())
}
pub fn require_project_root(start_dir: &Path) -> Result<PathBuf> {
find_project_root(start_dir).with_context(|| {
format!(
"Not in a wsb workspace (no .wsb/state.json found walking up from {}). \
Run 'wsb init' to initialize one.",
start_dir.display()
)
})
}