runmat_package/source/path_project/
mod.rs1mod freeze;
2mod load;
3mod model;
4
5use crate::{GraphError, HostCapability};
6#[cfg(not(target_arch = "wasm32"))]
7use runmat_config::project::discover_project_manifest_from;
8use runmat_config::project::{
9 discover_project_manifest_from_async, ProjectManifestLoadError, ProjectSourceIndexError,
10};
11use std::collections::BTreeSet;
12use std::path::{Path, PathBuf};
13use thiserror::Error;
14
15pub use freeze::{build_frozen_project_async, PathProjectError};
16
17use super::FrozenProject;
18
19#[derive(Debug, Error)]
20pub enum FrozenProjectError {
21 #[error(transparent)]
22 Project(#[from] PathProjectError),
23 #[error(transparent)]
24 Graph(#[from] GraphError),
25 #[error("failed to load root project manifest {path}: {source}")]
26 RootManifestLoad {
27 path: PathBuf,
28 #[source]
29 source: Box<ProjectManifestLoadError>,
30 },
31 #[error("failed to load dependency manifest {path} for dependency `{dependency}` of package `{package}`: {source}")]
32 DependencyManifestLoad {
33 package: String,
34 dependency: String,
35 path: PathBuf,
36 #[source]
37 source: Box<ProjectManifestLoadError>,
38 },
39 #[error("dependency `{dependency}` in package `{package}` points to missing manifest {path}")]
40 MissingDependencyManifest {
41 package: String,
42 dependency: String,
43 path: PathBuf,
44 },
45 #[error("dependency `{dependency}` in package `{package}` does not define a local `path`")]
46 DependencyPathRequired { package: String, dependency: String },
47 #[error("failed to build source index for package `{package}`: {source}")]
48 SourceIndex {
49 package: String,
50 #[source]
51 source: Box<ProjectSourceIndexError>,
52 },
53 #[error("dependency cycle detected while loading project composition: {cycle}")]
54 DependencyCycle { cycle: String },
55 #[error("synchronous project freezing is unavailable on WebAssembly; use the async API")]
56 SyncUnavailable,
57}
58
59pub fn discover_frozen_project_from(
60 start: &Path,
61 host_capabilities: BTreeSet<HostCapability>,
62) -> Result<Option<FrozenProject>, FrozenProjectError> {
63 #[cfg(not(target_arch = "wasm32"))]
64 {
65 let Some(manifest_path) = discover_project_manifest_from(start) else {
66 return Ok(None);
67 };
68 build_frozen_project(&manifest_path, host_capabilities).map(Some)
69 }
70 #[cfg(target_arch = "wasm32")]
71 {
72 let _ = start;
73 let _ = host_capabilities;
74 Ok(None)
75 }
76}
77
78pub async fn discover_frozen_project_from_async(
79 start: &Path,
80 host_capabilities: BTreeSet<HostCapability>,
81) -> Result<Option<FrozenProject>, FrozenProjectError> {
82 let Some(manifest_path) = discover_project_manifest_from_async(start).await else {
83 return Ok(None);
84 };
85 build_frozen_project_async(&manifest_path, host_capabilities)
86 .await
87 .map(Some)
88}
89
90pub fn build_frozen_project(
91 manifest_path: &Path,
92 host_capabilities: BTreeSet<HostCapability>,
93) -> Result<FrozenProject, FrozenProjectError> {
94 #[cfg(not(target_arch = "wasm32"))]
95 {
96 futures::executor::block_on(build_frozen_project_async(manifest_path, host_capabilities))
97 }
98 #[cfg(target_arch = "wasm32")]
99 {
100 let _ = manifest_path;
101 let _ = host_capabilities;
102 Err(FrozenProjectError::SyncUnavailable)
103 }
104}