Skip to main content

canic_host/release_set/paths/
artifacts.rs

1use std::path::{Path, PathBuf};
2use thiserror::Error as ThisError;
3
4use super::super::ROOT_RELEASE_SET_MANIFEST_FILE;
5
6/// Failure to locate the exact artifact root for a selected artifact environment.
7#[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
16/// Resolve the built artifact directory for the selected artifact environment.
17pub 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
25/// Resolve one exact built artifact directory confined to the canonical project root.
26pub 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/// Return the canonical artifact directory for one artifact environment.
57#[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/// Return the canonical manifest path for the staged root release set.
66#[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}