1use snix_castore::{
2 blobservice::BlobService, directoryservice::DirectoryService, import::fs::ingest_path,
3};
4use tracing::instrument;
5
6use nix_compat::{
7 nixhash::{CAHash, NixHash},
8 store_path::{self, StorePath},
9};
10
11use crate::{
12 nar::NarCalculationService,
13 pathinfoservice::{PathInfo, PathInfoService},
14 proto::nar_info,
15};
16
17impl From<CAHash> for nar_info::Ca {
18 fn from(value: CAHash) -> Self {
19 let hash_type: nar_info::ca::Hash = (&value).into();
20 let digest: bytes::Bytes = value.hash().to_string().into();
21 nar_info::Ca {
22 r#type: hash_type.into(),
23 digest,
24 }
25 }
26}
27
28#[instrument(skip_all, fields(name=name.as_ref(), path=?path.as_ref()), err)]
36pub async fn import_path_as_nar_ca<BS, DS, PS, NS, P>(
37 path: P,
38 name: impl AsRef<str>,
39 blob_service: BS,
40 directory_service: DS,
41 path_info_service: PS,
42 nar_calculation_service: NS,
43) -> Result<PathInfo, std::io::Error>
44where
45 P: AsRef<std::path::Path>,
46 BS: BlobService + Clone,
47 DS: DirectoryService,
48 PS: AsRef<dyn PathInfoService>,
49 NS: NarCalculationService,
50{
51 let root_node = ingest_path::<_, _, _, &[u8]>(blob_service, directory_service, path, None)
53 .await
54 .map_err(std::io::Error::other)?;
55
56 let (nar_size, nar_sha256) = nar_calculation_service
58 .calculate_nar(&root_node)
59 .await
60 .map_err(std::io::Error::other)?;
61
62 let ca = CAHash::Nar(NixHash::Sha256(nar_sha256));
63
64 let output_path: StorePath<String> =
67 store_path::build_ca_path(name.as_ref(), &ca, std::iter::empty::<&str>(), false).map_err(
68 |_| {
69 std::io::Error::new(
70 std::io::ErrorKind::InvalidData,
71 format!("invalid name: {0}", name.as_ref()),
72 )
73 },
74 )?;
75
76 path_info_service
78 .as_ref()
79 .put(PathInfo {
80 store_path: output_path.to_owned(),
81 node: root_node,
82 references: vec![],
84 nar_size,
85 nar_sha256,
86 signatures: vec![],
87 deriver: None,
88 ca: Some(ca),
89 })
90 .await
91 .map_err(std::io::Error::other)
92}