Skip to main content

callisto_graph/locate/
mod.rs

1use std::path::PathBuf;
2
3use callisto_model::{DeclaredEdge, ProjectRoot};
4
5pub mod ignore_walk;
6mod membership;
7pub mod root;
8
9pub use ignore_walk::IgnoreWalkLocator;
10pub use root::find_workspace_root;
11
12pub trait ProjectLocator: Send + Sync {
13    fn projects(&self) -> Result<Vec<ProjectRoot>, LocateError>;
14    fn declared_edges(&self) -> Option<Vec<DeclaredEdge>> {
15        None
16    }
17}
18
19#[derive(Clone, Debug, thiserror::Error, miette::Diagnostic, PartialEq, Eq)]
20#[non_exhaustive]
21pub enum LocateError {
22    #[error("workspace root not found starting from `{start}`")]
23    #[diagnostic(
24        code(E030),
25        help(
26            "No workspace root found. Ensure the directory tree contains a workspace manifest: \
27             Cargo.toml with [workspace], package.json with a workspaces field, \
28             pnpm-workspace.yaml, or a .moon directory."
29        )
30    )]
31    WorkspaceRootNotFound { start: PathBuf },
32
33    #[error("failed to walk filesystem under `{path}`: {message}")]
34    #[diagnostic(code(E031))]
35    Walk { path: PathBuf, message: String },
36
37    #[error("project path `{path}` is outside the workspace root `{root}`")]
38    #[diagnostic(code(E032))]
39    OutsideWorkspaceRoot { path: PathBuf, root: PathBuf },
40
41    /// A VCS operation failed during workspace location. This variant exists
42    /// so that callers who need to distinguish filesystem-structure errors
43    /// (WorkspaceRootNotFound, Walk) from VCS errors (e.g., a git repository
44    /// that could not be opened or queried during locate) can do so.
45    #[error("VCS error during workspace location: {0}")]
46    #[diagnostic(code(E033))]
47    Vcs(Box<callisto_vcs::VcsError>),
48
49    #[error("moon CLI is unavailable or exited non-zero")]
50    MoonUnavailable,
51
52    #[error("Failed to parse moon project-graph output: {message}")]
53    MoonOutputParse { message: String },
54
55    #[error("Incompatible moon version found: {found}, required: {required}")]
56    IncompatibleMoonVersion { found: String, required: String },
57
58    #[error(transparent)]
59    Graph(#[from] Box<crate::error::GraphError>),
60}
61
62impl From<callisto_vcs::VcsError> for LocateError {
63    fn from(e: callisto_vcs::VcsError) -> Self {
64        LocateError::Vcs(Box::new(e))
65    }
66}