Etapa G capa-de-adaptación #3: traducir mirror:// de nix a URLs concretas
nix resuelve `mirror://<sitio>/...` en eval; un import los deja literales y el curl de hammer no los entiende. expand_nix_mirror() mapea los comunes (gnu/savannah/kernel/sourceforge/gnome/ apache/xorg/pypi/cpan/debian) a un espejo real; lo no mapeado se deja igual. +1 test. Validado: import hello → tarball https://ftp.gnu.org/gnu/hello/... (antes mirror://gnu/...). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -63,7 +63,7 @@ pub fn classify_source(raw: &RawSource) -> Result<NixSource, String> {
|
||||
return Err(format!("source flat sin hash: {}", raw.url));
|
||||
}
|
||||
let hex = nix_hash_to_hex(&raw.output_hash)?;
|
||||
Ok(NixSource::Tarball { url: raw.url.clone(), sha256: hex })
|
||||
Ok(NixSource::Tarball { url: expand_nix_mirror(&raw.url), sha256: hex })
|
||||
}
|
||||
"recursive" => Err(format!(
|
||||
"source recursivo no-github (hash NAR no reusable): {} — fijá repo+commit a mano",
|
||||
@@ -73,6 +73,33 @@ pub fn classify_source(raw: &RawSource) -> Result<NixSource, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Traduce el esquema `mirror://<sitio>/...` de nix a una URL concreta. nix resuelve estos
|
||||
/// mirrors en tiempo de eval; un import los deja literales y el fetch de hammer (curl) no los
|
||||
/// entiende. Mapeamos los más comunes a un mirror real; lo no mapeado se deja igual + el usuario
|
||||
/// elige espejo. (nixpkgs tiene la lista completa en `pkgs/build-support/fetchurl/mirrors.nix`.)
|
||||
fn expand_nix_mirror(url: &str) -> String {
|
||||
let Some(rest) = url.strip_prefix("mirror://") else {
|
||||
return url.to_string();
|
||||
};
|
||||
let Some((site, path)) = rest.split_once('/') else {
|
||||
return url.to_string();
|
||||
};
|
||||
let base = match site {
|
||||
"gnu" => "https://ftp.gnu.org/gnu/",
|
||||
"savannah" => "https://download.savannah.gnu.org/releases/",
|
||||
"kernel" => "https://www.kernel.org/pub/",
|
||||
"sourceforge" => "https://downloads.sourceforge.net/",
|
||||
"gnome" => "https://download.gnome.org/",
|
||||
"apache" => "https://dlcdn.apache.org/",
|
||||
"xorg" => "https://www.x.org/releases/",
|
||||
"pypi" => "https://files.pythonhosted.org/packages/",
|
||||
"cpan" => "https://cpan.metacpan.org/",
|
||||
"debian" => "https://deb.debian.org/debian/",
|
||||
_ => return url.to_string(), // desconocido: dejamos el mirror:// (el humano resuelve)
|
||||
};
|
||||
format!("{base}{path}")
|
||||
}
|
||||
|
||||
/// Extrae `(owner, repo, rev)` de una URL de descarga de GitHub (las que arma `fetchFromGitHub`):
|
||||
/// `https://github.com/<owner>/<repo>/archive/<rev>.tar.gz` o
|
||||
/// `https://codeload.github.com/<owner>/<repo>/tar.gz/<rev>`.
|
||||
@@ -335,7 +362,8 @@ mod tests {
|
||||
let recipe = hammer_core::Recipe::from_toml(&toml).expect("recipe válida");
|
||||
assert_eq!(recipe.name, "hello");
|
||||
assert_eq!(recipe.version, "2.12.1");
|
||||
assert_eq!(recipe.source.tarball.as_deref(), Some("mirror://gnu/hello/hello-2.12.1.tar.gz"));
|
||||
// mirror://gnu/ se traduce a una URL concreta que el fetch de hammer entiende.
|
||||
assert_eq!(recipe.source.tarball.as_deref(), Some("https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz"));
|
||||
assert_eq!(
|
||||
recipe.source.sha256.as_deref(),
|
||||
Some("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
|
||||
@@ -360,6 +388,22 @@ mod tests {
|
||||
assert_eq!(recipe.deps.build, vec!["pcre2", "rustc"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expands_common_nix_mirrors() {
|
||||
assert_eq!(
|
||||
expand_nix_mirror("mirror://gnu/hello/hello-2.12.1.tar.gz"),
|
||||
"https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz"
|
||||
);
|
||||
assert_eq!(
|
||||
expand_nix_mirror("mirror://savannah/foo/foo-1.tar.gz"),
|
||||
"https://download.savannah.gnu.org/releases/foo/foo-1.tar.gz"
|
||||
);
|
||||
// desconocido se deja igual (no rompe, el humano resuelve).
|
||||
assert_eq!(expand_nix_mirror("mirror://raro/x"), "mirror://raro/x");
|
||||
// url normal pasa sin tocar.
|
||||
assert_eq!(expand_nix_mirror("https://x/y.tar.gz"), "https://x/y.tar.gz");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_github_uses_git() {
|
||||
let json = r#"{
|
||||
|
||||
Reference in New Issue
Block a user