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