Skip to main content

systemprompt_cli/shared/
project.rs

1use std::path::{Path, PathBuf};
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5pub enum ProjectError {
6    #[error("Not a systemprompt.io project: {path}\n\nLooking for .systemprompt directory")]
7    ProjectNotFound { path: PathBuf },
8
9    #[error("Failed to resolve path {path}: {source}")]
10    PathResolution {
11        path: PathBuf,
12        #[source]
13        source: std::io::Error,
14    },
15}
16
17#[derive(Debug, Clone)]
18pub struct ProjectRoot(PathBuf);
19
20impl ProjectRoot {
21    pub fn discover() -> Result<Self, ProjectError> {
22        let current = std::env::current_dir().map_err(|e| ProjectError::PathResolution {
23            path: PathBuf::from("."),
24            source: e,
25        })?;
26
27        if current.join(".systemprompt").is_dir() {
28            return Ok(Self(current));
29        }
30
31        let mut search = current.as_path();
32        while let Some(parent) = search.parent() {
33            if parent.join(".systemprompt").is_dir() {
34                return Ok(Self(parent.to_path_buf()));
35            }
36            search = parent;
37        }
38
39        Err(ProjectError::ProjectNotFound { path: current })
40    }
41
42    #[must_use]
43    pub fn as_path(&self) -> &Path {
44        &self.0
45    }
46}
47
48impl AsRef<Path> for ProjectRoot {
49    fn as_ref(&self) -> &Path {
50        &self.0
51    }
52}