canic_host/release_set/paths/
artifacts.rs1use std::path::{Path, PathBuf};
2use thiserror::Error as ThisError;
3
4use super::super::ROOT_RELEASE_SET_MANIFEST_FILE;
5
6#[derive(Debug, Eq, PartialEq, ThisError)]
8pub enum ArtifactRootError {
9 #[error("missing built ICP artifacts under {artifact_root}")]
10 Missing { artifact_root: PathBuf },
11
12 #[error("built ICP artifact root escapes the canonical ICP project root: {artifact_root}")]
13 OutsideProject { artifact_root: PathBuf },
14}
15
16pub fn resolve_artifact_root(
18 icp_root: &Path,
19 artifact_environment: &str,
20) -> Result<PathBuf, ArtifactRootError> {
21 let artifact_root = artifact_root_path(icp_root, artifact_environment);
22 resolve_artifact_root_path(icp_root, &artifact_root)
23}
24
25pub fn resolve_artifact_root_path(
27 icp_root: &Path,
28 artifact_root: &Path,
29) -> Result<PathBuf, ArtifactRootError> {
30 if !artifact_root.is_dir() {
31 return Err(ArtifactRootError::Missing {
32 artifact_root: artifact_root.to_path_buf(),
33 });
34 }
35
36 let canonical_project = icp_root
37 .canonicalize()
38 .map_err(|_| ArtifactRootError::Missing {
39 artifact_root: icp_root.to_path_buf(),
40 })?;
41 let canonical_artifact =
42 artifact_root
43 .canonicalize()
44 .map_err(|_| ArtifactRootError::Missing {
45 artifact_root: artifact_root.to_path_buf(),
46 })?;
47 if !canonical_artifact.starts_with(&canonical_project) {
48 return Err(ArtifactRootError::OutsideProject {
49 artifact_root: artifact_root.to_path_buf(),
50 });
51 }
52
53 Ok(canonical_artifact)
54}
55
56#[must_use]
58pub fn artifact_root_path(icp_root: &Path, artifact_environment: &str) -> PathBuf {
59 icp_root
60 .join(".icp")
61 .join(artifact_environment)
62 .join("canisters")
63}
64
65#[must_use]
67pub fn root_release_set_manifest_path(artifact_root: &Path) -> PathBuf {
68 artifact_root
69 .join("root")
70 .join(ROOT_RELEASE_SET_MANIFEST_FILE)
71}