fix: derivation references

This commit is contained in:
2026-01-31 20:19:00 +08:00
parent ba3e2ae3de
commit a68681b4f5
4 changed files with 46 additions and 5 deletions

View File

@@ -46,7 +46,7 @@ const validateBuilder = (attrs: NixAttrs, outContext: NixStringContext): string
if (!("builder" in attrs)) {
throw new Error("derivation: missing required attribute 'builder'");
}
return coerceToString(attrs.builder, StringCoercionMode.ToString, false, outContext);
return coerceToString(attrs.builder, StringCoercionMode.ToString, true, outContext);
};
const validateSystem = (attrs: NixAttrs): string => {
@@ -87,7 +87,7 @@ const extractArgs = (attrs: NixAttrs, outContext: NixStringContext): string[] =>
return [];
}
const argsList = forceList(attrs.args);
return argsList.map((a) => coerceToString(a, StringCoercionMode.ToString, false, outContext));
return argsList.map((a) => coerceToString(a, StringCoercionMode.ToString, true, outContext));
};
const structuredAttrsExcludedKeys = new Set([
@@ -190,7 +190,7 @@ const extractEnv = (
if (ignoreNulls && forcedValue === null) {
continue;
}
env.set(key, coerceToString(value, StringCoercionMode.ToString, false, outContext));
env.set(key, coerceToString(value, StringCoercionMode.ToString, true, outContext));
}
}
}
@@ -281,6 +281,17 @@ export const derivationStrict = (args: NixValue): NixAttrs => {
const { inputDrvs, inputSrcs } = extractInputDrvsAndSrcs(collectedContext);
const collectDrvReferences = (): string[] => {
const refs = new Set<string>();
for (const src of inputSrcs) {
refs.add(src);
}
for (const drvPath of inputDrvs.keys()) {
refs.add(drvPath);
}
return Array.from(refs).sort();
};
let outputInfos: Map<string, OutputInfo>;
let drvPath: string;
@@ -318,7 +329,7 @@ export const derivationStrict = (args: NixValue): NixAttrs => {
};
const finalAterm = generateAterm(finalDrv);
const finalDrvHash = Deno.core.ops.op_sha256_hex(finalAterm);
drvPath = Deno.core.ops.op_make_store_path("text", finalDrvHash, `${drvName}.drv`);
drvPath = Deno.core.ops.op_make_text_store_path(finalDrvHash, `${drvName}.drv`, collectDrvReferences());
} else {
const maskedOutputs = new Map<string, OutputInfo>(
outputs.map((o) => [
@@ -369,7 +380,7 @@ export const derivationStrict = (args: NixValue): NixAttrs => {
const finalAterm = generateAterm(finalDrv);
const finalDrvHash = Deno.core.ops.op_sha256_hex(finalAterm);
drvPath = Deno.core.ops.op_make_store_path("text", finalDrvHash, `${drvName}.drv`);
drvPath = Deno.core.ops.op_make_text_store_path(finalDrvHash, `${drvName}.drv`, collectDrvReferences());
}
const result: NixAttrs = {};

View File

@@ -45,6 +45,7 @@ declare global {
function op_make_placeholder(output: string): string;
function op_decode_span(span: string): { file: string | null; line: number | null; column: number | null };
function op_make_store_path(ty: string, hash_hex: string, name: string): string;
function op_make_text_store_path(hash_hex: string, name: string, references: string[]): string;
function op_output_path_name(drv_name: string, output_name: string): string;
function op_make_fixed_output_path(
hash_algo: string,

View File

@@ -93,6 +93,20 @@ pub fn make_store_path(store_dir: &str, ty: &str, hash_hex: &str, name: &str) ->
format!("{}/{}-{}", store_dir, encoded, name)
}
pub fn make_text_store_path(
store_dir: &str,
hash_hex: &str,
name: &str,
references: &[String],
) -> String {
let mut ty = String::from("text");
for reference in references {
ty.push(':');
ty.push_str(reference);
}
make_store_path(store_dir, &ty, hash_hex, name)
}
pub fn output_path_name(drv_name: &str, output_name: &str) -> String {
if output_name == "out" {
drv_name.to_string()

View File

@@ -52,6 +52,7 @@ fn runtime_extension<Ctx: RuntimeContext>() -> Extension {
op_make_placeholder(),
op_decode_span::<Ctx>(),
op_make_store_path::<Ctx>(),
op_make_text_store_path::<Ctx>(),
op_output_path_name(),
op_make_fixed_output_path::<Ctx>(),
op_add_path::<Ctx>(),
@@ -360,6 +361,20 @@ fn op_make_store_path<Ctx: RuntimeContext>(
crate::nix_hash::make_store_path(store_dir, &ty, &hash_hex, &name)
}
#[deno_core::op2]
#[string]
fn op_make_text_store_path<Ctx: RuntimeContext>(
state: &mut OpState,
#[string] hash_hex: String,
#[string] name: String,
#[serde] references: Vec<String>,
) -> String {
let ctx: &Ctx = state.get_ctx();
let store = ctx.get_store();
let store_dir = store.get_store_dir();
crate::nix_hash::make_text_store_path(store_dir, &hash_hex, &name, &references)
}
#[deno_core::op2]
#[string]
fn op_output_path_name(#[string] drv_name: String, #[string] output_name: String) -> String {