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"); throw new Error("Not implemented: parseFlakeRef");
}; };
export const placeholder = (output: NixValue): never => { export const placeholder = (output: NixValue): NixValue => {
throw new Error("Not implemented: placeholder"); const outputStr = forceStringNoCtx(output);
return Deno.core.ops.op_make_placeholder(outputStr);
}; };
export const replaceStrings = export const replaceStrings =

View File

@@ -42,6 +42,7 @@ declare global {
function op_read_dir(path: string): Record<string, string>; function op_read_dir(path: string): Record<string, string>;
function op_path_exists(path: string): boolean; function op_path_exists(path: string): boolean;
function op_sha256_hex(data: string): string; 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_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_store_path(ty: string, hash_hex: string, name: string): string;
function op_output_path_name(drv_name: string, output_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_path_exists(),
op_resolve_path(), op_resolve_path(),
op_sha256_hex(), op_sha256_hex(),
op_make_placeholder(),
op_decode_span::<Ctx>(), op_decode_span::<Ctx>(),
op_make_store_path::<Ctx>(), op_make_store_path::<Ctx>(),
op_output_path_name(), op_output_path_name(),
@@ -132,8 +133,7 @@ fn op_import<Ctx: RuntimeContext>(
} }
let current_dir = ctx.get_current_dir(); let current_dir = ctx.get_current_dir();
let mut absolute_path = current_dir let mut absolute_path = current_dir.join(&path);
.join(&path);
// Do NOT resolve symlinks (eval-okay-symlink-resolution) // Do NOT resolve symlinks (eval-okay-symlink-resolution)
// TODO: is this correct? // TODO: is this correct?
// .canonicalize() // .canonicalize()
@@ -284,6 +284,18 @@ fn op_sha256_hex(#[string] data: String) -> String {
crate::nix_hash::sha256_hex(&data) 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] #[deno_core::op2]
#[serde] #[serde]
fn op_decode_span<Ctx: RuntimeContext>( fn op_decode_span<Ctx: RuntimeContext>(