fix: fetchTarball

This commit is contained in:
2026-02-13 21:11:56 +08:00
parent 6d8f1e79e6
commit 48a43bed55
3 changed files with 13 additions and 76 deletions

View File

@@ -87,18 +87,17 @@ export const fetchClosure = (args: NixValue): never => {
throw new Error("Not implemented: fetchClosure"); throw new Error("Not implemented: fetchClosure");
}; };
interface FetchUrlResult { export interface FetchUrlResult {
store_path: string; store_path: string;
hash: string; hash: string;
} }
interface FetchTarballResult { export interface FetchTarballResult {
store_path: string; store_path: string;
hash: string;
nar_hash: string; nar_hash: string;
} }
interface FetchGitResult { export interface FetchGitResult {
out_path: string; out_path: string;
rev: string; rev: string;
short_rev: string; short_rev: string;
@@ -109,7 +108,7 @@ interface FetchGitResult {
nar_hash: string | null; nar_hash: string | null;
} }
interface FetchHgResult { export interface FetchHgResult {
out_path: string; out_path: string;
branch: string; branch: string;
rev: string; rev: string;
@@ -137,16 +136,11 @@ const normalizeUrlInput = (
return { url, hash, name, executable }; return { url, hash, name, executable };
}; };
const normalizeTarballInput = ( const normalizeTarballInput = (args: NixValue): { url: string; sha256?: string; name?: string } => {
args: NixValue,
): { url: string; sha256?: string; name?: string } => {
const forced = force(args); const forced = force(args);
if (isAttrs(forced)) { if (isAttrs(forced)) {
const url = forceStringNoCtx(forced.url); const url = forceStringNoCtx(forced.url);
const sha256 = const sha256 = "sha256" in forced ? forceStringNoCtx(forced.sha256) : undefined;
"sha256" in forced
? forceStringNoCtx(forced.sha256)
: undefined;
const name = "name" in forced ? forceStringNoCtx(forced.name) : undefined; const name = "name" in forced ? forceStringNoCtx(forced.name) : undefined;
return { url, sha256, name }; return { url, sha256, name };
} else { } else {
@@ -167,11 +161,7 @@ export const fetchurl = (args: NixValue): string => {
export const fetchTarball = (args: NixValue): string => { export const fetchTarball = (args: NixValue): string => {
const { url, name, sha256 } = normalizeTarballInput(args); const { url, name, sha256 } = normalizeTarballInput(args);
const result: FetchTarballResult = Deno.core.ops.op_fetch_tarball( const result: FetchTarballResult = Deno.core.ops.op_fetch_tarball(url, name ?? null, sha256 ?? null);
url,
name ?? null,
sha256 ?? null,
);
return result.store_path; return result.store_path;
}; };

View File

@@ -1,34 +1,5 @@
import type { NixRuntime } from ".."; import type { NixRuntime } from "..";
import type { FetchTarballResult, FetchUrlResult, FetchGitResult, FetchHgResult } from "../builtins/io";
interface FetchUrlResult {
store_path: string;
hash: string;
}
interface FetchTarballResult {
store_path: string;
hash: string;
nar_hash: string;
}
interface FetchGitResult {
out_path: string;
rev: string;
short_rev: string;
rev_count: number;
last_modified: number;
last_modified_date: string;
submodules: boolean;
nar_hash: string | null;
}
interface FetchHgResult {
out_path: string;
branch: string;
rev: string;
short_rev: string;
rev_count: number;
}
declare global { declare global {
var Nix: NixRuntime; var Nix: NixRuntime;

View File

@@ -32,7 +32,6 @@ pub struct FetchUrlResult {
#[derive(Serialize)] #[derive(Serialize)]
pub struct FetchTarballResult { pub struct FetchTarballResult {
pub store_path: String, pub store_path: String,
pub hash: String,
pub nar_hash: String, pub nar_hash: String,
} }
@@ -202,18 +201,12 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
.get("nar_hash") .get("nar_hash")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.unwrap_or(""); .unwrap_or("");
let cached_tarball_hash = cached_entry
.info
.get("tarball_hash")
.and_then(|v| v.as_str())
.unwrap_or("");
if let Some(ref hex) = expected_hex { if let Some(ref hex) = expected_hex {
if cached_nar_hash == hex { if cached_nar_hash == hex {
info!("Cache hit"); info!("Cache hit");
return Ok(FetchTarballResult { return Ok(FetchTarballResult {
store_path: cached_entry.store_path.clone(), store_path: cached_entry.store_path.clone(),
hash: cached_tarball_hash.to_string(),
nar_hash: cached_nar_hash.to_string(), nar_hash: cached_nar_hash.to_string(),
}); });
} }
@@ -221,7 +214,6 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
info!("Cache hit (no hash check)"); info!("Cache hit (no hash check)");
return Ok(FetchTarballResult { return Ok(FetchTarballResult {
store_path: cached_entry.store_path.clone(), store_path: cached_entry.store_path.clone(),
hash: cached_tarball_hash.to_string(),
nar_hash: cached_nar_hash.to_string(), nar_hash: cached_nar_hash.to_string(),
}); });
} }
@@ -235,17 +227,6 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
info!(bytes = data.len(), "Download complete"); info!(bytes = data.len(), "Download complete");
let tarball_hash = crate::nix_utils::sha256_hex(&String::from_utf8_lossy(&data));
if let Some(ref expected) = expected_hex
&& tarball_hash != *expected
{
return Err(NixRuntimeError::from(format!(
"Tarball hash mismatch for '{}': expected {}, got {}",
url, expected, tarball_hash
)));
}
info!("Extracting tarball"); info!("Extracting tarball");
let cache = FetcherCache::new().map_err(|e| NixRuntimeError::from(e.to_string()))?; let cache = FetcherCache::new().map_err(|e| NixRuntimeError::from(e.to_string()))?;
let (extracted_path, _temp_dir) = cache let (extracted_path, _temp_dir) = cache
@@ -258,19 +239,16 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
let nar_hash_hex = hex::encode(nar_hash); let nar_hash_hex = hex::encode(nar_hash);
debug!( debug!(
tarball_hash = %tarball_hash,
nar_hash = %nar_hash_hex, nar_hash = %nar_hash_hex,
"Hash computation complete" "Hash computation complete"
); );
if let Some(ref expected) = expected_sha256 if let Some(ref expected) = expected_hex
&& nar_hash != *expected && nar_hash_hex != *expected
{ {
return Err(NixRuntimeError::from(format!( return Err(NixRuntimeError::from(format!(
"NAR hash mismatch for '{}': expected {}, got {}", "Tarball hash mismatch for '{}': expected {}, got {}",
url, url, expected, nar_hash_hex
expected_hex.expect("must be Some"),
nar_hash_hex
))); )));
} }
@@ -284,8 +262,7 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
info!(store_path = %store_path, "Added to store"); info!(store_path = %store_path, "Added to store");
let info = serde_json::json!({ let info = serde_json::json!({
"tarball_hash": tarball_hash, "nar_hash": nar_hash_hex,
"nar_hash": nar_hash,
"url": url, "url": url,
}); });
@@ -296,7 +273,6 @@ pub fn op_fetch_tarball<Ctx: RuntimeContext>(
Ok(FetchTarballResult { Ok(FetchTarballResult {
store_path, store_path,
hash: tarball_hash,
nar_hash: nar_hash_hex, nar_hash: nar_hash_hex,
}) })
} }