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