fix: handle __functor in forceFunction
This commit is contained in:
@@ -204,14 +204,32 @@ interface FixedOutputInfo {
|
||||
hashMode: string;
|
||||
}
|
||||
|
||||
const extractFixedOutputInfo = (attrs: NixAttrs): FixedOutputInfo | null => {
|
||||
const extractFixedOutputInfo = (attrs: NixAttrs, ignoreNulls: boolean): FixedOutputInfo | null => {
|
||||
if (!("outputHash" in attrs)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const hashValue = force(attrs.outputHash);
|
||||
if (ignoreNulls && hashValue === null) {
|
||||
return null;
|
||||
}
|
||||
const hash = forceStringValue(attrs.outputHash);
|
||||
const hashAlgo = "outputHashAlgo" in attrs ? forceStringValue(attrs.outputHashAlgo) : "sha256";
|
||||
const hashMode = "outputHashMode" in attrs ? forceStringValue(attrs.outputHashMode) : "flat";
|
||||
|
||||
let hashAlgo = "sha256";
|
||||
if ("outputHashAlgo" in attrs) {
|
||||
const algoValue = force(attrs.outputHashAlgo);
|
||||
if (!(ignoreNulls && algoValue === null)) {
|
||||
hashAlgo = forceStringValue(attrs.outputHashAlgo);
|
||||
}
|
||||
}
|
||||
|
||||
let hashMode = "flat";
|
||||
if ("outputHashMode" in attrs) {
|
||||
const modeValue = force(attrs.outputHashMode);
|
||||
if (!(ignoreNulls && modeValue === null)) {
|
||||
hashMode = forceStringValue(attrs.outputHashMode);
|
||||
}
|
||||
}
|
||||
|
||||
if (hashMode !== "flat" && hashMode !== "recursive") {
|
||||
throw new Error(`derivation: invalid outputHashMode '${hashMode}' (must be 'flat' or 'recursive')`);
|
||||
@@ -234,14 +252,13 @@ export const derivationStrict = (args: NixValue): NixAttrs => {
|
||||
const builder = validateBuilder(attrs, collectedContext);
|
||||
const platform = validateSystem(attrs);
|
||||
|
||||
const outputs = extractOutputs(attrs);
|
||||
const fixedOutputInfo = extractFixedOutputInfo(attrs);
|
||||
validateFixedOutputConstraints(fixedOutputInfo, outputs);
|
||||
|
||||
const structuredAttrs = "__structuredAttrs" in attrs ? force(attrs.__structuredAttrs) === true : false;
|
||||
|
||||
const ignoreNulls = "__ignoreNulls" in attrs ? force(attrs.__ignoreNulls) === true : false;
|
||||
|
||||
const outputs = extractOutputs(attrs);
|
||||
const fixedOutputInfo = extractFixedOutputInfo(attrs, ignoreNulls);
|
||||
validateFixedOutputConstraints(fixedOutputInfo, outputs);
|
||||
|
||||
if ("__contentAddressed" in attrs && force(attrs.__contentAddressed) === true) {
|
||||
throw new Error("ca derivations are not supported");
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import type {
|
||||
} from "./types";
|
||||
import { isStringWithContext, isNixPath } from "./types";
|
||||
import { force } from "./thunk";
|
||||
import { getStringValue } from "./string-context";
|
||||
import { isAttrs, isFunction, typeOf } from "./builtins/type-check";
|
||||
|
||||
/**
|
||||
@@ -32,15 +31,25 @@ export const forceList = (value: NixValue): NixList => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Force a value and assert it's a function
|
||||
* @throws TypeError if value is not a function after forcing
|
||||
* Force a value and assert it's a function or functor
|
||||
* @throws TypeError if value is not a function or functor after forcing
|
||||
*/
|
||||
export const forceFunction = (value: NixValue): NixFunction => {
|
||||
const forced = force(value);
|
||||
if (!isFunction(forced)) {
|
||||
throw new TypeError(`Expected function, got ${typeOf(forced)}`);
|
||||
}
|
||||
if (isFunction(forced)) {
|
||||
return forced;
|
||||
}
|
||||
if (
|
||||
typeof forced === "object" &&
|
||||
!Array.isArray(forced) &&
|
||||
forced !== null &&
|
||||
"__functor" in forced
|
||||
) {
|
||||
const functorSet = forced as NixAttrs;
|
||||
const functor = forceFunction(functorSet.__functor);
|
||||
return (arg: NixValue) => forceFunction(functor(functorSet))(arg);
|
||||
}
|
||||
throw new TypeError(`Expected function, got ${typeOf(forced)}`);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -473,15 +473,14 @@ impl<Ctx: CodegenContext> Compile<Ctx> for [(ExprId, ExprId)] {
|
||||
let inner_ir = ctx.get_ir(inner);
|
||||
let inner_span = inner_ir.span();
|
||||
|
||||
code!(buf, "let expr{}=Nix.createThunk(()=>(", slot.0);
|
||||
inner_ir.compile(ctx, buf);
|
||||
code!(
|
||||
buf,
|
||||
"),\"expr{} {}:{}:{}\");",
|
||||
slot.0,
|
||||
ctx.get_current_source().get_name(),
|
||||
usize::from(inner_span.start()),
|
||||
buf, ctx;
|
||||
"let expr" slot.0 "=Nix.createThunk(()=>(" inner_ir "),"
|
||||
"\"expr" slot.0 " "
|
||||
ctx.get_current_source().get_name() ":"
|
||||
usize::from(inner_span.start()) ":"
|
||||
usize::from(inner_span.end())
|
||||
"\");"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user