forked from auxolotl/labs
362 lines
13 KiB
Nix
362 lines
13 KiB
Nix
{ lib, config }:
|
|
let
|
|
lib' = config.lib;
|
|
in
|
|
{
|
|
config = {
|
|
lib.packages = {
|
|
dependencies = {
|
|
get =
|
|
dependencies:
|
|
let
|
|
exists = value: !(builtins.isNull value);
|
|
available = builtins.filter exists dependencies;
|
|
in
|
|
builtins.map (dependency: dependency.package) available;
|
|
|
|
build =
|
|
build': host': target':
|
|
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
|
|
|
|
collect =
|
|
package:
|
|
let
|
|
isPropagated = name: package: package.propagate or false;
|
|
getPropagatedDependencies = target: builtins.attrValues (lib.attrs.filter isPropagated target);
|
|
|
|
process =
|
|
dependencies:
|
|
let
|
|
getDeps =
|
|
name: dependency:
|
|
let
|
|
deps = {
|
|
build = {
|
|
only = getPropagatedDependencies dependency.deps.build.only ++ process dependency.deps.build.only;
|
|
build =
|
|
getPropagatedDependencies dependency.deps.build.build
|
|
++ process dependency.deps.build.build;
|
|
host = getPropagatedDependencies dependency.deps.build.host ++ process dependency.deps.build.host;
|
|
target =
|
|
getPropagatedDependencies dependency.deps.build.target
|
|
++ process dependency.deps.build.target;
|
|
};
|
|
host = {
|
|
only = getPropagatedDependencies dependency.deps.host.only ++ process dependency.deps.host.only;
|
|
host = getPropagatedDependencies dependency.deps.host.host ++ process dependency.deps.host.host;
|
|
target =
|
|
getPropagatedDependencies dependency.deps.host.target
|
|
++ process dependency.deps.host.target;
|
|
};
|
|
target = {
|
|
only = getPropagatedDependencies dependency.deps.target.only ++ process dependency.deps.target.only;
|
|
target =
|
|
getPropagatedDependencies dependency.deps.target.target
|
|
++ process dependency.deps.target.target;
|
|
};
|
|
};
|
|
in
|
|
lib.lists.flatten [
|
|
deps.build.only
|
|
deps.build.build
|
|
deps.build.host
|
|
deps.build.target
|
|
deps.host.only
|
|
deps.host.host
|
|
deps.host.target
|
|
deps.target.only
|
|
deps.target.target
|
|
];
|
|
|
|
propagated = lib.attrs.mapToList getDeps dependencies;
|
|
in
|
|
lib.lists.flatten propagated;
|
|
in
|
|
{
|
|
build = {
|
|
only = builtins.attrValues package.deps.build.only ++ process package.deps.build.only;
|
|
build = builtins.attrValues package.deps.build.build ++ process package.deps.build.build;
|
|
host = builtins.attrValues package.deps.build.host ++ process package.deps.build.host;
|
|
target = builtins.attrValues package.deps.build.target ++ process package.deps.build.target;
|
|
};
|
|
host = {
|
|
only = builtins.attrValues package.deps.host.only ++ process package.deps.host.only;
|
|
host = builtins.attrValues package.deps.host.host ++ process package.deps.host.host;
|
|
target = builtins.attrValues package.deps.host.target ++ process package.deps.host.target;
|
|
};
|
|
target = {
|
|
only = builtins.attrValues package.deps.target.only ++ process package.deps.target.only;
|
|
target = builtins.attrValues package.deps.target.target ++ process package.deps.target.target;
|
|
};
|
|
};
|
|
};
|
|
|
|
context = {
|
|
create =
|
|
collected: ctx:
|
|
let
|
|
process =
|
|
path:
|
|
let
|
|
dependencies = lib.attrs.selectOrThrow path collected;
|
|
contexts = builtins.map (dependency: dependency.context or { }) dependencies;
|
|
result = lib.modules.run {
|
|
modules = builtins.map (context: { config = context; }) contexts ++ [
|
|
{
|
|
freeform = lib.types.any;
|
|
|
|
options = config.packages.context.options // {
|
|
target = lib.options.create {
|
|
description = "The dependency target that is being generated.";
|
|
type = lib.types.enum [
|
|
"build.only"
|
|
"build.build"
|
|
"build.host"
|
|
"build.target"
|
|
"host.only"
|
|
"host.host"
|
|
"host.target"
|
|
"target.only"
|
|
"target.target"
|
|
];
|
|
writable = false;
|
|
default.value = builtins.concatStringsSep "." path;
|
|
};
|
|
|
|
deps = lib.options.create {
|
|
description = "The collected dependencies.";
|
|
writable = false;
|
|
default.value = collected;
|
|
type = lib.types.submodule {
|
|
options = {
|
|
build = {
|
|
only = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
build = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
host = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
target = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
};
|
|
host = {
|
|
only = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
host = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
target = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
};
|
|
target = {
|
|
only = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
target = lib.options.create { type = lib.types.list.of lib'.types.package; };
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = ctx;
|
|
}
|
|
];
|
|
};
|
|
in
|
|
result.config;
|
|
in
|
|
{
|
|
build = {
|
|
only = process [
|
|
"build"
|
|
"only"
|
|
];
|
|
build = process [
|
|
"build"
|
|
"build"
|
|
];
|
|
host = process [
|
|
"build"
|
|
"host"
|
|
];
|
|
target = process [
|
|
"build"
|
|
"target"
|
|
];
|
|
};
|
|
host = {
|
|
only = process [
|
|
"host"
|
|
"only"
|
|
];
|
|
host = process [
|
|
"host"
|
|
"host"
|
|
];
|
|
target = process [
|
|
"host"
|
|
"target"
|
|
];
|
|
};
|
|
target = {
|
|
only = process [
|
|
"target"
|
|
"only"
|
|
];
|
|
target = process [
|
|
"target"
|
|
"target"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
hooks = {
|
|
create =
|
|
collected: ctx:
|
|
let
|
|
process =
|
|
path:
|
|
let
|
|
dependencies = lib.attrs.selectOrThrow path collected;
|
|
hooks = builtins.map (
|
|
dependency:
|
|
let
|
|
getHooks = dependency.hooks or (lib.fp.const { });
|
|
in
|
|
getHooks ctx
|
|
) dependencies;
|
|
in
|
|
hooks;
|
|
in
|
|
{
|
|
build = {
|
|
only = process [
|
|
"build"
|
|
"only"
|
|
];
|
|
build = process [
|
|
"build"
|
|
"build"
|
|
];
|
|
host = process [
|
|
"build"
|
|
"host"
|
|
];
|
|
target = process [
|
|
"build"
|
|
"target"
|
|
];
|
|
};
|
|
host = {
|
|
only = process [
|
|
"host"
|
|
"only"
|
|
];
|
|
host = process [
|
|
"host"
|
|
"host"
|
|
];
|
|
target = process [
|
|
"host"
|
|
"target"
|
|
];
|
|
};
|
|
target = {
|
|
only = process [
|
|
"target"
|
|
"only"
|
|
];
|
|
target = process [
|
|
"target"
|
|
"target"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
getLatest =
|
|
alias:
|
|
let
|
|
versions = builtins.attrNames alias.versions;
|
|
sorted = builtins.sort (lib.versions.gte) versions;
|
|
in
|
|
builtins.head sorted;
|
|
|
|
resolve =
|
|
alias:
|
|
if alias ? versions then
|
|
alias.versions.${config.preferences.packages.version}
|
|
or (alias.versions.${lib'.packages.getLatest alias})
|
|
else
|
|
alias;
|
|
|
|
build =
|
|
alias: build: host: target:
|
|
let
|
|
package = lib'.packages.resolve alias;
|
|
|
|
buildDependencies =
|
|
build': host': target':
|
|
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
|
|
|
|
platform = {
|
|
build = lib.modules.overrides.force build;
|
|
host = lib.modules.overrides.force host;
|
|
target = lib.modules.overrides.force target;
|
|
};
|
|
|
|
withPlatform = lib.modules.run {
|
|
modules = package.__modules__ ++ [
|
|
lib'.types.package.children.submodule
|
|
(
|
|
{ config }:
|
|
{
|
|
config = {
|
|
__modules__ = package.__modules__;
|
|
|
|
inherit platform;
|
|
};
|
|
}
|
|
)
|
|
];
|
|
};
|
|
|
|
# Not all platform information can be effectively handled via submodules. To handle
|
|
# the case where a user copies the resolved config over we need to ensure that
|
|
# dependencies are appropriately updated.
|
|
withDeps = withPlatform.config // {
|
|
deps = {
|
|
build = {
|
|
only = buildDependencies build build build withPlatform.config.deps.build.only;
|
|
build = buildDependencies build build target withPlatform.config.deps.build.build;
|
|
host = buildDependencies build host target withPlatform.config.deps.build.host;
|
|
target = buildDependencies build target target withPlatform.config.deps.build.target;
|
|
};
|
|
host = {
|
|
only = buildDependencies host host host withPlatform.config.deps.host.only;
|
|
host = buildDependencies host host target withPlatform.config.deps.host.host;
|
|
target = buildDependencies host target target withPlatform.config.deps.host.target;
|
|
};
|
|
target = {
|
|
only = buildDependencies target target target withPlatform.config.deps.target.only;
|
|
target = buildDependencies target target target withPlatform.config.deps.target.target;
|
|
};
|
|
};
|
|
};
|
|
|
|
withPackage = lib.modules.run {
|
|
modules = package.__modules__ ++ [
|
|
lib'.types.package.children.submodule
|
|
(
|
|
{ config }:
|
|
{
|
|
config = {
|
|
__modules__ = package.__modules__;
|
|
|
|
inherit platform;
|
|
|
|
deps = lib.modules.overrides.force withDeps.deps;
|
|
|
|
package = lib.modules.overrides.force (withDeps.builder.build withDeps);
|
|
};
|
|
}
|
|
)
|
|
];
|
|
};
|
|
in
|
|
withPackage.config;
|
|
};
|
|
};
|
|
}
|