arcature-cli 2026.2.0

Developer lifecycle CLI for Arcature applications.
Documentation
//! Workspace-root discovery (AP2.1-10).
//!
//! Walk up from the project root to find the Arcature workspace root (the
//! directory whose `Cargo.toml` contains a `[workspace]` table). The
//! workspace root is where `Cargo.lock` lives and where
//! `crates/arcature/Cargo.toml` (the framework version source) is found. A
//! project root may be a subdirectory of a dogfood app, so walking up is
//! necessary; a standalone app falls back to its own root.

use std::path::{Path, PathBuf};

/// Walk up from `start` to find the workspace root (the directory whose
/// `Cargo.toml` contains a `[workspace]` table). Falls back to `start` if
/// no workspace root is found (a standalone app).
pub(super) fn discover_workspace_root(start: &Path) -> PathBuf {
    let mut candidate: Option<&Path> = Some(start);
    while let Some(dir) = candidate {
        let cargo_toml = dir.join("Cargo.toml");
        if let Ok(text) = std::fs::read_to_string(&cargo_toml)
            && let Ok(value) = toml::from_str::<toml::Value>(&text)
            && value.get("workspace").is_some()
        {
            return dir.to_path_buf();
        }
        candidate = dir.parent();
    }
    start.to_path_buf()
}