fix: handle __functor in forceFunction
This commit is contained in:
@@ -204,14 +204,32 @@ interface FixedOutputInfo {
|
|||||||
hashMode: string;
|
hashMode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const extractFixedOutputInfo = (attrs: NixAttrs): FixedOutputInfo | null => {
|
const extractFixedOutputInfo = (attrs: NixAttrs, ignoreNulls: boolean): FixedOutputInfo | null => {
|
||||||
if (!("outputHash" in attrs)) {
|
if (!("outputHash" in attrs)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hashValue = force(attrs.outputHash);
|
||||||
|
if (ignoreNulls && hashValue === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const hash = forceStringValue(attrs.outputHash);
|
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") {
|
if (hashMode !== "flat" && hashMode !== "recursive") {
|
||||||
throw new Error(`derivation: invalid outputHashMode '${hashMode}' (must be 'flat' or '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 builder = validateBuilder(attrs, collectedContext);
|
||||||
const platform = validateSystem(attrs);
|
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 structuredAttrs = "__structuredAttrs" in attrs ? force(attrs.__structuredAttrs) === true : false;
|
||||||
|
|
||||||
const ignoreNulls = "__ignoreNulls" in attrs ? force(attrs.__ignoreNulls) === 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) {
|
if ("__contentAddressed" in attrs && force(attrs.__contentAddressed) === true) {
|
||||||
throw new Error("ca derivations are not supported");
|
throw new Error("ca derivations are not supported");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import type {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
import { isStringWithContext, isNixPath } from "./types";
|
import { isStringWithContext, isNixPath } from "./types";
|
||||||
import { force } from "./thunk";
|
import { force } from "./thunk";
|
||||||
import { getStringValue } from "./string-context";
|
|
||||||
import { isAttrs, isFunction, typeOf } from "./builtins/type-check";
|
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
|
* Force a value and assert it's a function or functor
|
||||||
* @throws TypeError if value is not a function after forcing
|
* @throws TypeError if value is not a function or functor after forcing
|
||||||
*/
|
*/
|
||||||
export const forceFunction = (value: NixValue): NixFunction => {
|
export const forceFunction = (value: NixValue): NixFunction => {
|
||||||
const forced = force(value);
|
const forced = force(value);
|
||||||
if (!isFunction(forced)) {
|
if (isFunction(forced)) {
|
||||||
throw new TypeError(`Expected function, got ${typeOf(forced)}`);
|
|
||||||
}
|
|
||||||
return 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_ir = ctx.get_ir(inner);
|
||||||
let inner_span = inner_ir.span();
|
let inner_span = inner_ir.span();
|
||||||
|
|
||||||
code!(buf, "let expr{}=Nix.createThunk(()=>(", slot.0);
|
|
||||||
inner_ir.compile(ctx, buf);
|
|
||||||
code!(
|
code!(
|
||||||
buf,
|
buf, ctx;
|
||||||
"),\"expr{} {}:{}:{}\");",
|
"let expr" slot.0 "=Nix.createThunk(()=>(" inner_ir "),"
|
||||||
slot.0,
|
"\"expr" slot.0 " "
|
||||||
ctx.get_current_source().get_name(),
|
ctx.get_current_source().get_name() ":"
|
||||||
usize::from(inner_span.start()),
|
usize::from(inner_span.start()) ":"
|
||||||
usize::from(inner_span.end())
|
usize::from(inner_span.end())
|
||||||
|
"\");"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user