1use crate::fetchers::Fetch;
4use nix_compat::{derivation::Derivation, nixhash::CAHash};
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("out").ok_or(Error::NoFOD)?;
27 let ca_hash = out_output.ca_hash.clone().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 match ca_hash {
43 CAHash::Flat(hash) => {
44 return Ok((
45 name,
46 Fetch::URL {
47 url,
48 exp_hash: Some(hash),
49 },
50 ));
51 }
52 CAHash::Nar(hash) => {
53 if drv.environment.get("executable").map(|v| v.as_slice()) == Some(b"1") {
54 Ok((name, Fetch::Executable { url, hash }))
55 } else {
56 Ok((name, Fetch::NAR { url, hash }))
57 }
58 }
59 CAHash::Text(_) => panic!("Snix bug: got CaHash::Text in drv"),
61 }
62}
63
64#[derive(Debug, thiserror::Error)]
65pub(crate) enum Error {
66 #[error("Invalid builder")]
67 BuilderInvalid,
68 #[error("invalid arguments")]
69 ArgumentsInvalud,
70 #[error("Invalid system")]
71 SystemInvalid,
72 #[error("Derivation is not fixed-output")]
73 NoFOD,
74 #[error("Missing URL")]
75 URLMissing,
76 #[error("Invalid URL")]
77 URLInvalid,
78 #[error("Missing Name")]
79 NameMissing,
80 #[error("Name invalid")]
81 NameInvalid,
82}