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

View File

@ -229,6 +229,7 @@ let
dreamLock,
inject,
sourceOverrides,
packageOverrides,
}@args:
let
@ -242,6 +243,14 @@ let
fetchedSources =
args.fetchedSources // changedSources;
produceDerivation = name: pkg:
utils.applyOverridesToPackage {
inherit pkg;
packages = formattedOutputs.packages;
pname = name;
conditionalOverrides = packageOverrides;
};
buildPackageWithOtherBuilder =
{
builder,
@ -258,16 +267,24 @@ let
in
callBuilder {
inherit builder builderArgs inject sourceOverrides;
inherit
builder
builderArgs
fetchedSources
inject
sourceOverrides
packageOverrides
;
dreamLock =
subDreamLockLoaded.lock;
inherit fetchedSources;
};
outputs = builder ( builderArgs // {
inherit
buildPackageWithOtherBuilder
produceDerivation
;
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
outputs;
formattedOutputs;
# produce outputs for a dream-lock or a source
@ -339,48 +381,28 @@ let
}).fetchedSources;
builderOutputs = callBuilder {
inherit
dreamLock
fetchedSources
sourceOverrides
;
builder = builder';
builderArgs = (args.builderArgs or {}) // {
packageOverrides =
lib.recursiveUpdate
(dreamOverrides."${dreamLock._generic.subsystem}" or {})
(args.packageOverrides or {});
};
inherit builderArgs;
packageOverrides =
lib.recursiveUpdate
(dreamOverrides."${dreamLock._generic.subsystem}" or {})
(args.packageOverrides or {});
inject =
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
formattedBuilderOutputs;
builderOutputs;
in
{

View File

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

View File

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