omne-cli 0.1.1

CLI for managing omne volumes: init, upgrade, and validate kernel and distro releases
Documentation
//! Volume root detection.
//!
//! The primary entry point is `find_omne_root`, which walks up from a
//! starting directory looking for an ancestor that contains a `.omne/`
//! subdirectory. `upgrade` and `validate` use this so they work from
//! any subdirectory of a volume; `init` deliberately does **not** walk
//! up (R13 — `init` creates in the current directory only).
//!
//! The Python module's `is_mounted()` helper is **not ported** per R12:
//! the submodule/mount model was removed when releases-based
//! distribution replaced the submodule architecture. Dead code
//! deletion happens in Unit 12.

#![allow(dead_code)]

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

/// Walk up from `start` looking for an ancestor that contains a
/// `.omne/` subdirectory. Returns the first match, or `None` when the
/// walk reaches the filesystem root without finding one.
///
/// `start` is canonicalized first so relative paths, `..` segments,
/// and symlinks are resolved before the walk begins. If `start` does
/// not exist or cannot be canonicalized, the function returns `None`
/// — the caller surfaces this as `CliError::NotAVolume` at the
/// command boundary.
pub fn find_omne_root(start: &Path) -> Option<PathBuf> {
    let mut current = start.canonicalize().ok()?;
    loop {
        if current.join(".omne").is_dir() {
            return Some(current);
        }
        if !current.pop() {
            return None;
        }
    }
}

#[cfg(test)]
mod tests {
    use std::fs;

    use tempfile::TempDir;

    use super::*;

    #[test]
    fn finds_root_when_omne_exists_at_start() {
        let tmp = TempDir::new().expect("create tempdir");
        fs::create_dir(tmp.path().join(".omne")).expect("create .omne");

        let found = find_omne_root(tmp.path());
        let expected = tmp.path().canonicalize().expect("canonicalize tmpdir");
        assert_eq!(found, Some(expected));
    }

    #[test]
    fn finds_root_from_subdirectory() {
        let tmp = TempDir::new().expect("create tempdir");
        fs::create_dir(tmp.path().join(".omne")).expect("create .omne");

        let deep = tmp.path().join("src").join("deep");
        fs::create_dir_all(&deep).expect("create deep subdir");

        let found = find_omne_root(&deep);
        let expected = tmp.path().canonicalize().expect("canonicalize tmpdir");
        assert_eq!(found, Some(expected));
    }

    #[test]
    fn walk_up_matches_actual_ancestor_chain() {
        // Do NOT create `.omne` in the tempdir itself. Derive the
        // expected result from the canonicalized ancestor chain so the
        // test stays hermetic even if some ambient ancestor (e.g.
        // `/tmp/.omne` on a developer machine) already contains a
        // `.omne` directory. In a clean environment this still asserts
        // `None`; on a contaminated environment it asserts the
        // contaminating ancestor's path instead of failing.
        let tmp = TempDir::new().expect("create tempdir");
        let canonical_start = tmp.path().canonicalize().expect("canonicalize tmpdir");
        let expected = canonical_start
            .ancestors()
            .find(|ancestor| ancestor.join(".omne").is_dir())
            .map(Path::to_path_buf);

        let found = find_omne_root(tmp.path());
        assert_eq!(found, expected);
    }

    #[test]
    fn returns_none_when_start_does_not_exist() {
        let tmp = TempDir::new().expect("create tempdir");
        let missing = tmp.path().join("does-not-exist");

        let found = find_omne_root(&missing);
        assert_eq!(found, None);
    }
}