devalang_wasm/tools/cli/config/
path.rs

1#![cfg(feature = "cli")]
2
3use anyhow::Result;
4use std::{
5    env, fs,
6    path::{Path, PathBuf},
7};
8
9pub const DEVALANG_CONFIG: &str = ".devalang";
10pub const DEVA_DIR: &str = ".deva";
11
12/// Returns the current working directory.
13pub fn get_cwd() -> PathBuf {
14    env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
15}
16
17/// Returns true if the given directory looks like a devalang project root.
18/// Checks for the presence of `.devalang` config file or `.deva` directory.
19pub fn is_project_root(dir: &Path) -> bool {
20    let config = dir.join(DEVALANG_CONFIG);
21    if config.is_file() {
22        return true;
23    }
24    let deva = dir.join(DEVA_DIR);
25    deva.is_dir()
26}
27
28/// Walks upward from `start` to locate the first directory considered a project root.
29pub fn find_project_root_from(start: &Path) -> Option<PathBuf> {
30    for ancestor in start.ancestors() {
31        if is_project_root(ancestor) {
32            return Some(ancestor.to_path_buf());
33        }
34    }
35    None
36}
37
38/// Finds the project root from the current working directory.
39pub fn find_project_root() -> Option<PathBuf> {
40    find_project_root_from(&get_cwd())
41}
42
43/// Gets the project root or returns an error if not found.
44pub fn get_project_root() -> Result<PathBuf> {
45    find_project_root()
46        .ok_or_else(|| anyhow::anyhow!("Project root not found. Run 'devalang init' in your project or create a .deva directory."))
47}
48
49/// Returns the `.deva` directory inside the project root (without creating it).
50pub fn get_deva_dir() -> Result<PathBuf> {
51    let root = get_project_root()?;
52    Ok(root.join(DEVA_DIR))
53}
54
55/// Ensures the `.deva` directory exists in the project root and returns its path.
56pub fn ensure_deva_dir() -> Result<PathBuf> {
57    let deva = get_deva_dir()?;
58    if !deva.exists() {
59        fs::create_dir_all(&deva).map_err(|e| {
60            anyhow::anyhow!(
61                "Failed to create .deva directory '{}': {}",
62                deva.display(),
63                e
64            )
65        })?;
66    }
67    Ok(deva)
68}
69
70/// Gets the home directory's .deva (for user-level addons)
71pub fn get_home_deva_dir() -> Result<PathBuf> {
72    let home_dir =
73        dirs::home_dir().ok_or_else(|| anyhow::anyhow!("Cannot determine home directory"))?;
74    Ok(home_dir.join(".deva"))
75}
76
77/// Ensures the home directory's .deva exists
78pub fn ensure_home_deva_dir() -> Result<PathBuf> {
79    let deva = get_home_deva_dir()?;
80    if !deva.exists() {
81        fs::create_dir_all(&deva).map_err(|e| {
82            anyhow::anyhow!(
83                "Failed to create home .deva directory '{}': {}",
84                deva.display(),
85                e
86            )
87        })?;
88    }
89    Ok(deva)
90}