builder API; move override logic into produceDerivation

This should simplify writing builders
This commit is contained in:
DavHau 2021-11-13 17:41:48 +07:00
parent 163db67245
commit f1e34e0e89
4 changed files with 118 additions and 72 deletions

View File

@ -32,10 +32,11 @@
# where versions is a list of version strings # where versions is a list of version strings
packageVersions, packageVersions,
# Overrides # function which applies overrides to a package
# Those must be applied by the builder to each individual derivation # It must be applied by the builder to each individual derivation
# using `utils.applyOverridesToPackage` # Example:
packageOverrides ? {}, # produceDerivation name (mkDerivation {...})
produceDerivation,
# Custom Options: (parametrize builder behavior) # Custom Options: (parametrize builder behavior)
# These can be passed by the user via `builderArgs`. # These can be passed by the user via `builderArgs`.
@ -70,6 +71,10 @@ let
makePackage name version)) makePackage name version))
packageVersions; packageVersions;
outputs = {
inherit defaultPackage packages;
};
# Generates a derivation for a specific package name + version # Generates a derivation for a specific package name + version
makePackage = name: version: makePackage = name: version:
let let
@ -88,7 +93,7 @@ let
deps)); deps));
pkg = pkg =
stdenv.mkDerivation rec { produceDerivation name (stdenv.mkDerivation rec {
packageName = name; packageName = name;
@ -300,13 +305,16 @@ let
done done
fi fi
''; '';
}; });
in in
pkg;
# apply packageOverrides to current derivation # apply packageOverrides to current derivation
(utils.applyOverridesToPackage packageOverrides pkg name); # (utils.applyOverridesToPackage {
# inherit outputs pkg;
# conditionalOverrides = packageOverrides;
# pname = name;
# });
in in
{ outputs
inherit defaultPackage packages;
}

View File

@ -229,6 +229,7 @@ let
dreamLock, dreamLock,
inject, inject,
sourceOverrides, sourceOverrides,
packageOverrides,
}@args: }@args:
let let
@ -242,6 +243,14 @@ let
fetchedSources = fetchedSources =
args.fetchedSources // changedSources; args.fetchedSources // changedSources;
produceDerivation = name: pkg:
utils.applyOverridesToPackage {
inherit pkg;
packages = formattedOutputs.packages;
pname = name;
conditionalOverrides = packageOverrides;
};
buildPackageWithOtherBuilder = buildPackageWithOtherBuilder =
{ {
builder, builder,
@ -258,16 +267,24 @@ let
in in
callBuilder { callBuilder {
inherit builder builderArgs inject sourceOverrides; inherit
builder
builderArgs
fetchedSources
inject
sourceOverrides
packageOverrides
;
dreamLock = dreamLock =
subDreamLockLoaded.lock; subDreamLockLoaded.lock;
inherit fetchedSources;
}; };
outputs = builder ( builderArgs // { outputs = builder ( builderArgs // {
inherit inherit
buildPackageWithOtherBuilder buildPackageWithOtherBuilder
produceDerivation
; ;
inherit (dreamLockInterface) inherit (dreamLockInterface)
@ -283,8 +300,33 @@ let
}); });
# Makes the packages tree compatible with flakes schema.
# For each package the attr `{pname}` will link to the latest release.
# Other package versions will be inside: `{pname}.versions`
formattedOutputs = outputs // {
packages =
let
allPackages = outputs.packages or {};
latestPackages =
lib.mapAttrs'
(pname: releases:
let
latest =
releases."${utils.latestVersion (b.attrNames releases)}";
in
(lib.nameValuePair
"${pname}"
(latest // {
versions = releases;
})))
allPackages;
in
latestPackages;
};
in in
outputs; formattedOutputs;
# produce outputs for a dream-lock or a source # produce outputs for a dream-lock or a source
@ -339,48 +381,28 @@ let
}).fetchedSources; }).fetchedSources;
builderOutputs = callBuilder { builderOutputs = callBuilder {
inherit inherit
dreamLock dreamLock
fetchedSources fetchedSources
sourceOverrides sourceOverrides
; ;
builder = builder'; builder = builder';
builderArgs = (args.builderArgs or {}) // {
packageOverrides = inherit builderArgs;
lib.recursiveUpdate
(dreamOverrides."${dreamLock._generic.subsystem}" or {}) packageOverrides =
(args.packageOverrides or {}); lib.recursiveUpdate
}; (dreamOverrides."${dreamLock._generic.subsystem}" or {})
(args.packageOverrides or {});
inject = inject =
utils.dreamLock.decompressDependencyGraph args.inject or {}; utils.dreamLock.decompressDependencyGraph args.inject or {};
}; };
# Makes the packages tree compatible with flakes schema.
# For each package the attr `{pname}` will link to the latest release.
# Other package versions will be inside: `{pname}.versions`
formattedBuilderOutputs = builderOutputs // {
packages =
let
allPackages = builderOutputs.packages or {};
latestPackages =
lib.mapAttrs'
(pname: releases:
let
latest =
releases."${utils.latestVersion (b.attrNames releases)}";
in
(lib.nameValuePair
"${pname}"
(latest // {
versions = releases;
})))
allPackages;
in
latestPackages;
};
in in
formattedBuilderOutputs; builderOutputs;
in in
{ {

View File

@ -28,10 +28,11 @@
# where versions is a list of version strings # where versions is a list of version strings
packageVersions, packageVersions,
# Overrides # function which applies overrides to a package
# Those must be applied by the builder to each individual derivation # It must be applied by the builder to each individual derivation
# using `utils.applyOverridesToPackage` # Example:
packageOverrides ? {}, # produceDerivation name (mkDerivation {...})
produceDerivation,
# Custom Options: (parametrize builder behavior) # Custom Options: (parametrize builder behavior)
# These can be passed by the user via `builderArgs`. # These can be passed by the user via `builderArgs`.

View File

@ -54,19 +54,32 @@ let
``` ```
''; '';
applyOverridesToPackage = conditionalOverrides: pkg: pname: getOverrideFunctionArgs = function:
# if ! conditionalOverrides ? "${pname}" then let
# pkg funcArgs = lib.functionArgs function;
# else in
if funcArgs != {} then
b.attrNames funcArgs
else
(
function (old: {passthru.funcArgs = lib.attrNames old;})
).funcArgs;
applyOverridesToPackage =
{
conditionalOverrides,
pkg,
pname,
packages,
}:
let let
# if condition is unset, it will be assumed true # if condition is unset, it will be assumed true
evalCondition = condOverride: pkg: evalCondition = condOverride: pkg:
if condOverride ? _condition then if condOverride ? _condition then
condOverride._condition pkg condOverride._condition pkg
else else
true; true;
# filter the overrides by the package name and conditions # filter the overrides by the package name and conditions
overridesToApply = overridesToApply =
@ -88,7 +101,9 @@ let
overridesListForPackage = overridesListForPackage =
lib.mapAttrsToList lib.mapAttrsToList
(_name: data: data // { inherit _name; }) (_name: data:
data // { inherit _name; }
)
overridesForPackage; overridesForPackage;
in in
(lib.filter (lib.filter
@ -97,10 +112,10 @@ let
# apply single attribute override # apply single attribute override
applySingleAttributeOverride = oldVal: functionOrValue: applySingleAttributeOverride = oldVal: functionOrValue:
if b.isFunction functionOrValue then if b.isFunction functionOrValue then
functionOrValue oldVal functionOrValue oldVal
else else
functionOrValue; functionOrValue;
# helper to apply one conditional override # helper to apply one conditional override
# the condition is not evaluated anymore here # the condition is not evaluated anymore here
@ -128,7 +143,7 @@ let
let let
availableFunctions = availableFunctions =
lib.mapAttrs lib.mapAttrs
(funcName: func: lib.attrNames (lib.functionArgs func)) (funcName: func: getOverrideFunctionArgs func)
(lib.filterAttrs (lib.filterAttrs
(funcName: func: lib.hasPrefix "override" funcName) (funcName: func: lib.hasPrefix "override" funcName)
base_derivation); base_derivation);
@ -143,8 +158,8 @@ let
in in
if b.length applicableFuncs == 0 then if b.length applicableFuncs == 0 then
"overrideAttrs" "overrideAttrs"
else if b.length applicableFuncs >= 1 then else if b.length applicableFuncs > 1 then
throwErrorUnclearAttributeOverride pname condOverride._name attrName throwErrorUnclearAttributeOverride Hpname condOverride._name attrName
else else
b.elemAt applicableFuncs 0; b.elemAt applicableFuncs 0;
@ -175,12 +190,12 @@ let
updateAttrsFuncs)) updateAttrsFuncs))
base_derivation base_derivation
(overrideFuncs ++ singleArgOverrideFuncs); (overrideFuncs ++ singleArgOverrideFuncs);
in in
# apply the overrides to the given pkg # apply the overrides to the given pkg
(lib.foldl (lib.foldl
(pkg: condOverride: applyOneOverride pkg condOverride) (pkg: condOverride: applyOneOverride pkg condOverride)
pkg pkg
overridesToApply); overridesToApply);
in in
{ {