feat: package extend, dynamic propagation
This commit is contained in:
parent
3f9d287065
commit
7d94b7f665
|
@ -49,18 +49,18 @@ lib: {
|
|||
##
|
||||
## @type Attrs -> Attrs
|
||||
create =
|
||||
settings@{
|
||||
name,
|
||||
description ? name,
|
||||
fallback ? { },
|
||||
check ? lib.fp.const true,
|
||||
merge ? lib.options.merge.default,
|
||||
functor ? lib.types.functor name,
|
||||
mergeType ? lib.types.merge functor,
|
||||
getSubOptions ? lib.fp.const { },
|
||||
getSubModules ? null,
|
||||
withSubModules ? lib.fp.const null,
|
||||
children ? { },
|
||||
settings@{ name
|
||||
, description ? name
|
||||
, fallback ? { }
|
||||
, check ? lib.fp.const true
|
||||
, merge ? lib.options.merge.default
|
||||
, functor ? lib.types.functor name
|
||||
, mergeType ? lib.types.merge functor
|
||||
, getSubOptions ? lib.fp.const { }
|
||||
, getSubModules ? null
|
||||
, withSubModules ? lib.fp.const null
|
||||
, children ? { }
|
||||
,
|
||||
}:
|
||||
{
|
||||
__type__ = "type";
|
||||
|
@ -108,7 +108,7 @@ lib: {
|
|||
identifier = lib.options.getIdentifier location;
|
||||
first = builtins.elemAt definitions 0;
|
||||
|
||||
files = builtins.map lib.modules.getFiles definitions;
|
||||
files = lib.modules.getFiles definitions;
|
||||
serializedFiles = builtins.concatStringsSep " and " files;
|
||||
|
||||
getType =
|
||||
|
@ -118,13 +118,16 @@ lib: {
|
|||
else
|
||||
builtins.typeOf value;
|
||||
|
||||
commonType = builtins.foldl' (
|
||||
commonType = builtins.foldl'
|
||||
(
|
||||
type: definition:
|
||||
if getType definition.value != type then
|
||||
builtins.throw "The option `${identifier}` has conflicting definitions in ${files}"
|
||||
builtins.throw "The option `${identifier}` has conflicting definitions in ${serializedFiles}"
|
||||
else
|
||||
type
|
||||
) (getType first.value) definitions;
|
||||
)
|
||||
(getType first.value)
|
||||
definitions;
|
||||
|
||||
mergeStringifiableAttrs = lib.options.merge.one;
|
||||
|
||||
|
@ -132,7 +135,7 @@ lib: {
|
|||
|
||||
mergeList =
|
||||
if builtins.length definitions > 1 then
|
||||
builtins.throw "The option `${identifier}` has conflicting definitions in ${files}"
|
||||
builtins.throw "The option `${identifier}` has conflicting definitions in ${serializedFiles}"
|
||||
else
|
||||
(lib.types.list.of lib.types.any).merge;
|
||||
|
||||
|
@ -140,10 +143,12 @@ lib: {
|
|||
location: definitions: x:
|
||||
let
|
||||
resolvedLocation = location ++ [ "<function body>" ];
|
||||
resolvedDefinitions = builtins.map (definition: {
|
||||
resolvedDefinitions = builtins.map
|
||||
(definition: {
|
||||
__file__ = definition.__file__;
|
||||
value = definition.value x;
|
||||
}) definitions;
|
||||
})
|
||||
definitions;
|
||||
in
|
||||
lib.types.any.merge resolvedLocation resolvedDefinitions;
|
||||
|
||||
|
@ -200,7 +205,8 @@ lib: {
|
|||
## @type Int -> Int -> Attrs
|
||||
between =
|
||||
start: end:
|
||||
assert lib.errors.trace (
|
||||
assert lib.errors.trace
|
||||
(
|
||||
start <= end
|
||||
) "lib.types.ints.between start must be less than or equal to end";
|
||||
lib.types.withCheck lib.types.int (value: value >= start && value <= end)
|
||||
|
@ -317,7 +323,8 @@ lib: {
|
|||
## @type Int -> Int -> Attrs
|
||||
between =
|
||||
start: end:
|
||||
assert lib.errors.trace (
|
||||
assert lib.errors.trace
|
||||
(
|
||||
start <= end
|
||||
) "lib.types.numbers.between start must be less than or equal to end";
|
||||
lib.types.withCheck lib.types.number (value: value >= start && value <= end)
|
||||
|
@ -447,8 +454,7 @@ lib: {
|
|||
};
|
||||
|
||||
attrs = {
|
||||
## A type that allows an attribute set containing any type of value. The merged
|
||||
## definitions must all be.
|
||||
## A type that allows an attribute set containing any type of value.
|
||||
##
|
||||
## @type Attrs
|
||||
any = lib.types.create {
|
||||
|
@ -480,10 +486,12 @@ lib: {
|
|||
let
|
||||
normalize =
|
||||
definition:
|
||||
builtins.mapAttrs (name: value: {
|
||||
builtins.mapAttrs
|
||||
(name: value: {
|
||||
__file__ = definition.__file__;
|
||||
value = value;
|
||||
}) definition.value;
|
||||
})
|
||||
definition.value;
|
||||
normalized = builtins.map normalize definitions;
|
||||
zipper =
|
||||
name: definitions: (lib.options.merge.definitions (location ++ [ name ]) type definitions).optional;
|
||||
|
@ -520,10 +528,12 @@ lib: {
|
|||
let
|
||||
normalize =
|
||||
definition:
|
||||
builtins.mapAttrs (name: value: {
|
||||
builtins.mapAttrs
|
||||
(name: value: {
|
||||
__file__ = definition.__file__;
|
||||
value = value;
|
||||
}) definition.value;
|
||||
})
|
||||
definition.value;
|
||||
normalized = builtins.map normalize definitions;
|
||||
zipper =
|
||||
name: definitions:
|
||||
|
@ -606,9 +616,11 @@ lib: {
|
|||
merge =
|
||||
location: definitions:
|
||||
let
|
||||
result = lib.lists.mapWithIndex1 (
|
||||
result = lib.lists.mapWithIndex1
|
||||
(
|
||||
i: definition:
|
||||
lib.lists.mapWithIndex1 (
|
||||
lib.lists.mapWithIndex1
|
||||
(
|
||||
j: value:
|
||||
let
|
||||
resolved =
|
||||
|
@ -622,9 +634,12 @@ lib: {
|
|||
];
|
||||
in
|
||||
resolved.optional
|
||||
) definition.value
|
||||
) definitions;
|
||||
merged = builtins.concatLists result;
|
||||
)
|
||||
definition.value
|
||||
)
|
||||
definitions;
|
||||
|
||||
merged = lib.lists.flatten result;
|
||||
filtered = builtins.filter (definition: definition ? value) merged;
|
||||
values = lib.options.getDefinitionValues filtered;
|
||||
in
|
||||
|
@ -777,11 +792,11 @@ lib: {
|
|||
##
|
||||
## @type { modules :: List Module, args? :: Attrs, description? :: String | Null, shorthand? :: Bool } -> Attrs
|
||||
of =
|
||||
settings@{
|
||||
modules,
|
||||
args ? { },
|
||||
description ? null,
|
||||
shorthand ? true,
|
||||
settings@{ modules
|
||||
, args ? { }
|
||||
, description ? null
|
||||
, shorthand ? true
|
||||
,
|
||||
}:
|
||||
let
|
||||
getModules = builtins.map (
|
||||
|
@ -790,9 +805,12 @@ lib: {
|
|||
let
|
||||
# TODO: Figure out if we can apply additional attributes to the generated module.
|
||||
# Currently this causes issues to do with redefined options.
|
||||
rest = builtins.removeAttrs (lib.attrs.filter (
|
||||
rest = builtins.removeAttrs
|
||||
(lib.attrs.filter
|
||||
(
|
||||
name: value: builtins.elem name lib.modules.VALID_KEYS
|
||||
) definition.value) [ "freeform" ];
|
||||
)
|
||||
definition.value) [ "freeform" ];
|
||||
in
|
||||
if definition.value ? config then
|
||||
rest
|
||||
|
@ -922,10 +940,12 @@ lib: {
|
|||
merge = location: definitions: {
|
||||
includes =
|
||||
modules
|
||||
++ builtins.map (definition: {
|
||||
++ builtins.map
|
||||
(definition: {
|
||||
__file__ = "${definition.__file__}; via ${lib.options.getIdentifier location}";
|
||||
includes = [ definition.value ];
|
||||
}) definitions;
|
||||
})
|
||||
definitions;
|
||||
};
|
||||
getSubOptions = submodule.getSubOptions;
|
||||
getSubModules = submodule.getSubModules;
|
||||
|
@ -961,10 +981,12 @@ lib: {
|
|||
location: definitions:
|
||||
let
|
||||
first = builtins.elemAt definitions 0;
|
||||
modules = builtins.map (definition: {
|
||||
modules = builtins.map
|
||||
(definition: {
|
||||
__file__ = definition.__file__;
|
||||
options = lib.options.create { type = definition.value; };
|
||||
}) definitions;
|
||||
})
|
||||
definitions;
|
||||
merged = lib.modules.fixup location (lib.options.merge.declarations location modules);
|
||||
in
|
||||
if builtins.length definitions == 1 then first.value else merged.type;
|
||||
|
@ -1197,10 +1219,12 @@ lib: {
|
|||
merge =
|
||||
location: definitions:
|
||||
submodule.merge location (
|
||||
builtins.map (definition: {
|
||||
builtins.map
|
||||
(definition: {
|
||||
__file__ = definition.__file__;
|
||||
value = normalize definition;
|
||||
}) definitions
|
||||
})
|
||||
definitions
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
},
|
||||
"locked": {
|
||||
"dir": "foundation",
|
||||
"dirtyRev": "42e69f7d43c0fb108ac70fde118c4a8ff6a777b0-dirty",
|
||||
"dirtyShortRev": "42e69f7-dirty",
|
||||
"lastModified": 1720466389,
|
||||
"narHash": "sha256-Zrmbcb+42r6eZV05QbcG2znHXrOh0sbdRaEZYxV0C7A=",
|
||||
"dirtyRev": "3f9d287065ac685ce500c2cddb35428b2927f5a2-dirty",
|
||||
"dirtyShortRev": "3f9d287-dirty",
|
||||
"lastModified": 1720514984,
|
||||
"narHash": "sha256-AuixwSlYk34Z6+GEc7y4QotF3Hk963zC9I9hAwX5KCE=",
|
||||
"type": "git",
|
||||
"url": "file:../?dir=foundation"
|
||||
},
|
||||
|
@ -24,10 +24,10 @@
|
|||
"lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"dirtyRev": "42e69f7d43c0fb108ac70fde118c4a8ff6a777b0-dirty",
|
||||
"dirtyShortRev": "42e69f7-dirty",
|
||||
"lastModified": 1720466389,
|
||||
"narHash": "sha256-Zrmbcb+42r6eZV05QbcG2znHXrOh0sbdRaEZYxV0C7A=",
|
||||
"dirtyRev": "3f9d287065ac685ce500c2cddb35428b2927f5a2-dirty",
|
||||
"dirtyShortRev": "3f9d287-dirty",
|
||||
"lastModified": 1720514984,
|
||||
"narHash": "sha256-AuixwSlYk34Z6+GEc7y4QotF3Hk963zC9I9hAwX5KCE=",
|
||||
"type": "git",
|
||||
"url": "file:../?dir=lib"
|
||||
},
|
||||
|
|
|
@ -20,8 +20,6 @@ in
|
|||
|
||||
hooks = lib.packages.hooks.create dependencies context;
|
||||
|
||||
cflags = builtins.concatStringsSep " " (context.build.host.cflags or [ ]);
|
||||
|
||||
phasesWithHooks =
|
||||
let
|
||||
all = lib.lists.flatten [
|
||||
|
|
|
@ -101,6 +101,7 @@ in
|
|||
dependencies = lib.attrs.selectOrThrow path collected;
|
||||
contexts = builtins.map (dependency: dependency.context or { }) dependencies;
|
||||
result = lib.modules.run {
|
||||
prefix = [ "<package>" ];
|
||||
modules = builtins.map (context: { config = context; }) contexts ++ [
|
||||
{
|
||||
freeform = lib.types.any;
|
||||
|
@ -210,13 +211,15 @@ in
|
|||
path:
|
||||
let
|
||||
dependencies = lib.attrs.selectOrThrow path collected;
|
||||
hooks = builtins.map (
|
||||
hooks = builtins.map
|
||||
(
|
||||
dependency:
|
||||
let
|
||||
getHooks = dependency.hooks or (lib.fp.const { });
|
||||
in
|
||||
getHooks ctx
|
||||
) dependencies;
|
||||
)
|
||||
dependencies;
|
||||
in
|
||||
hooks;
|
||||
in
|
||||
|
|
|
@ -214,7 +214,7 @@ in
|
|||
};
|
||||
|
||||
submodule =
|
||||
{ config }:
|
||||
{ config, meta }:
|
||||
let
|
||||
build = config.platform.build;
|
||||
host = config.platform.host;
|
||||
|
@ -230,6 +230,34 @@ in
|
|||
default.value = [ ];
|
||||
};
|
||||
|
||||
extend = lib.options.create {
|
||||
description = "Extend the package definition.";
|
||||
type = lib.types.function lib.types.raw;
|
||||
internal = true;
|
||||
writable = false;
|
||||
default.value = module:
|
||||
let
|
||||
normalized =
|
||||
if builtins.isList module then
|
||||
module
|
||||
else if builtins.isFunction module || module ? config then
|
||||
[ module ]
|
||||
else
|
||||
[{
|
||||
config = module;
|
||||
}];
|
||||
result = meta.extend {
|
||||
modules =
|
||||
normalized ++ [
|
||||
{
|
||||
config.__modules__ = lib.modules.overrides.force (config.__modules__ ++ normalized);
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
result.config;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = lib.options.create {
|
||||
description = "The description for the package.";
|
||||
|
|
|
@ -26,8 +26,18 @@ in
|
|||
|
||||
builder = builders.basic;
|
||||
|
||||
deps = {
|
||||
build = {
|
||||
host = {
|
||||
c = packages.aux.c.versions.latest.extend {
|
||||
propagate = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
context = {
|
||||
cflags = [ "-I $AUX_B/include" ];
|
||||
"foundation:cflags" = [ "-I $AUX_B/include" ];
|
||||
};
|
||||
|
||||
hooks = ctx: { "aux:b:env" = lib.dag.entry.after [ "unpack" ] ''export AUX_B=${config.package}''; };
|
||||
|
|
44
tidepool/src/packages/aux/c.nix
Normal file
44
tidepool/src/packages/aux/c.nix
Normal file
|
@ -0,0 +1,44 @@
|
|||
{ config }:
|
||||
let
|
||||
inherit (config) lib builders packages;
|
||||
in
|
||||
{
|
||||
config.packages.aux.c = {
|
||||
versions = {
|
||||
"latest" =
|
||||
{ config }:
|
||||
{
|
||||
options = {
|
||||
custom = lib.options.create { type = lib.types.bool; };
|
||||
};
|
||||
|
||||
config = {
|
||||
meta = {
|
||||
platforms = [ "i686-linux" ];
|
||||
};
|
||||
|
||||
name = "${config.pname}-${config.version}";
|
||||
|
||||
custom = true;
|
||||
|
||||
pname = "c";
|
||||
version = "1.0.0";
|
||||
|
||||
builder = builders.basic;
|
||||
|
||||
context = {
|
||||
"foundation:cflags" = [ "-I $AUX_C/include" ];
|
||||
};
|
||||
|
||||
hooks = ctx: { "aux:c:env" = lib.dag.entry.after [ "unpack" ] ''export AUX_C=${config.package}''; };
|
||||
|
||||
phases = {
|
||||
install = ''
|
||||
echo "c" > $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -11,6 +11,7 @@ in
|
|||
./foundation
|
||||
./aux/a.nix
|
||||
./aux/b.nix
|
||||
./aux/c.nix
|
||||
];
|
||||
|
||||
options = {
|
||||
|
@ -55,7 +56,8 @@ in
|
|||
config = {
|
||||
packages.cross = lib.attrs.generate doubles (
|
||||
system:
|
||||
builtins.mapAttrs (
|
||||
builtins.mapAttrs
|
||||
(
|
||||
namespace:
|
||||
builtins.mapAttrs (
|
||||
name: alias:
|
||||
|
@ -80,7 +82,8 @@ in
|
|||
in
|
||||
updated
|
||||
)
|
||||
) packages
|
||||
)
|
||||
packages
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@ let
|
|||
;
|
||||
in
|
||||
{
|
||||
config.packages.context.options = {
|
||||
"foundation:cflags" = lib.options.create {
|
||||
type = lib.types.list.of lib.types.string;
|
||||
default.value = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config.packages.foundation.gcc = {
|
||||
versions = {
|
||||
"latest" =
|
||||
|
|
Loading…
Reference in a new issue