1use nix_compat::derivation::{Derivation, OutputHash, OutputName};
4use snix_build_glue::fetchers::Fetch;
5use tracing::instrument;
6use url::Url;
7
8#[instrument]
11pub(crate) fn fetchurl_derivation_to_fetch(drv: &Derivation) -> Result<(String, Fetch), Error> {
12 if drv.builder != "builtin:fetchurl" {
13 return Err(Error::BuilderInvalid);
14 }
15 if !drv.arguments.is_empty() {
16 return Err(Error::ArgumentsInvalud);
17 }
18 if drv.system != "builtin" {
19 return Err(Error::SystemInvalid);
20 }
21
22 if drv.outputs.len() != 1 {
24 return Err(Error::NoFOD);
25 }
26 let out_output = &drv.outputs.get(&OutputName::out()).ok_or(Error::NoFOD)?;
27 let output_hash = out_output.output_hash.as_ref().ok_or(Error::NoFOD)?;
28
29 let name: String = drv
30 .environment
31 .get("name")
32 .ok_or(Error::NameMissing)?
33 .to_owned()
34 .try_into()
35 .map_err(|_| Error::NameInvalid)?;
36
37 let url: Url = std::str::from_utf8(drv.environment.get("url").ok_or(Error::URLMissing)?)
38 .map_err(|_| Error::URLInvalid)?
39 .parse()
40 .map_err(|_| Error::URLInvalid)?;
41
42 Ok(match output_hash {
43 OutputHash {
44 mode: nix_compat::derivation::OutputHashMode::Flat,
45 hash,
46 } => (
47 name,
48 Fetch::URL {
49 url,
50 exp_hash: Some(hash.to_owned()),
51 },
52 ),
53 OutputHash {
54 mode: nix_compat::derivation::OutputHashMode::Recursive,
55 hash,
56 } => {
57 if drv.environment.get("executable").map(|v| v.as_slice()) == Some(b"1") {
58 (
59 name,
60 Fetch::Executable {
61 url,
62 hash: hash.to_owned(),
63 },
64 )
65 } else {
66 (
67 name,
68 Fetch::NAR {
69 url,
70 hash: hash.to_owned(),
71 },
72 )
73 }
74 }
75 })
76}
77
78#[derive(Debug, thiserror::Error)]
79pub(crate) enum Error {
80 #[error("Invalid builder")]
81 BuilderInvalid,
82 #[error("invalid arguments")]
83 ArgumentsInvalud,
84 #[error("Invalid system")]
85 SystemInvalid,
86 #[error("Derivation is not fixed-output")]
87 NoFOD,
88 #[error("Missing URL")]
89 URLMissing,
90 #[error("Invalid URL")]
91 URLInvalid,
92 #[error("Missing Name")]
93 NameMissing,
94 #[error("Name invalid")]
95 NameInvalid,
96}