feat: builtins.placeholder

This commit is contained in:
2026-01-31 18:06:53 +08:00
parent 547f8f3828
commit a08f0e78a3
3 changed files with 22 additions and 8 deletions

View File

@@ -262,8 +262,9 @@ export const parseFlakeRef = (s: NixValue): never => {
throw new Error("Not implemented: parseFlakeRef");
};
export const placeholder = (output: NixValue): never => {
throw new Error("Not implemented: placeholder");
export const placeholder = (output: NixValue): NixValue => {
const outputStr = forceStringNoCtx(output);
return Deno.core.ops.op_make_placeholder(outputStr);
};
export const replaceStrings =

View File

@@ -42,6 +42,7 @@ declare global {
function op_read_dir(path: string): Record<string, string>;
function op_path_exists(path: string): boolean;
function op_sha256_hex(data: string): string;
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_output_path_name(drv_name: string, output_name: string): string;

View File

@@ -49,6 +49,7 @@ fn runtime_extension<Ctx: RuntimeContext>() -> Extension {
op_path_exists(),
op_resolve_path(),
op_sha256_hex(),
op_make_placeholder(),
op_decode_span::<Ctx>(),
op_make_store_path::<Ctx>(),
op_output_path_name(),
@@ -132,12 +133,11 @@ fn op_import<Ctx: RuntimeContext>(
}
let current_dir = ctx.get_current_dir();
let mut absolute_path = current_dir
.join(&path);
// Do NOT resolve symlinks (eval-okay-symlink-resolution)
// TODO: is this correct?
// .canonicalize()
// .map_err(|e| format!("Failed to resolve path {}: {}", path, e))?;
let mut absolute_path = current_dir.join(&path);
// Do NOT resolve symlinks (eval-okay-symlink-resolution)
// TODO: is this correct?
// .canonicalize()
// .map_err(|e| format!("Failed to resolve path {}: {}", path, e))?;
if absolute_path.is_dir() {
absolute_path.push("default.nix")
}
@@ -284,6 +284,18 @@ fn op_sha256_hex(#[string] data: String) -> String {
crate::nix_hash::sha256_hex(&data)
}
#[deno_core::op2]
#[string]
fn op_make_placeholder(#[string] output: String) -> String {
use sha2::{Digest, Sha256};
let input = format!("nix-output:{}", output);
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
let hash: [u8; 32] = hasher.finalize().into();
let encoded = crate::nix_hash::nix_base32_encode(&hash);
format!("/{}", encoded)
}
#[deno_core::op2]
#[serde]
fn op_decode_span<Ctx: RuntimeContext>(