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