1
0
Fork 0
mirror of https://github.com/hercules-ci/flake-parts.git synced 2024-12-14 11:47:31 +00:00

Merge pull request #242 from hercules-ci/partition

Partitions
This commit is contained in:
Robert Hensing 2024-08-30 11:50:04 +02:00 committed by GitHub
commit 1e6fc322ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 189 additions and 79 deletions

12
ci.nix
View file

@ -1,12 +0,0 @@
# We're doing things a bit differently because Nix doesn't let us
# split out the dev dependencies and subflakes are broken, let alone "superflakes".
# See dev/README.md
let
flake = import ./dev;
inherit (flake.inputs.nixpkgs) lib;
in
{
inherit (flake) herculesCI;
} // {
checks = lib.recurseIntoAttrs flake.checks.${builtins.currentSystem};
}

View file

@ -1,6 +0,0 @@
# Separate `dev` flake
Wouldn't recommend this pattern normally, but I'm trying to keep
deps low for `flake-parts` until we have split dev inputs
that don't carry over to dependent lock files.

View file

@ -1,16 +0,0 @@
let
flake = builtins.getFlake (toString ./.);
fmc-lib = (builtins.getFlake (toString ../.)).lib;
args = {
inherit self;
} // flake.inputs;
self = {
inherit (flake) inputs;
outPath = ../.; # used by pre-commit module, etc
outputs = self.config.flake;
} //
fmc-lib.mkFlake
{ inputs = args; }
./flake-module.nix;
in
self.config.flake // { inherit (flake) inputs; }

View file

@ -3,7 +3,7 @@
inputs = {
# Flakes don't give us a good way to depend on .., so we don't.
# As a consequence, this flake is a little non-standard, and
# As a consequence, this flake only provides dependencies, and
# we can't use the `nix` CLI as expected.
nixpkgs.url = "github:NixOS/nixpkgs";
@ -16,5 +16,6 @@
{
# The dev tooling is in ./flake-module.nix
# See comment at `inputs` above.
# It is loaded into partitions.dev by the root flake.
};
}

View file

@ -1,3 +0,0 @@
# convenience for loading into nix repl
let self = builtins.getFlake (toString ./.);
in self // { inherit self; }

130
extras/partitions.nix Normal file
View file

@ -0,0 +1,130 @@
{ lib, config, inputs, extendModules, partitionStack, self, ... }:
let
inherit (lib)
literalMD
mapAttrs
mkOption
optionalAttrs
types
;
partitionModule = { config, options, name, ... }: {
options = {
extraInputsFlake = mkOption {
type = types.raw;
default = { };
description = ''
Location of a flake whose inputs to add to the inputs module argument in the partition.
'';
};
extraInputs = mkOption {
type = types.lazyAttrsOf types.raw;
description = ''
Extra inputs to add to the inputs module argument in the partition.
This can be used as a workaround for the fact that transitive inputs are locked in the "end user" flake.
That's not desirable for inputs they don't need, such as development inputs.
'';
default = { };
defaultText = literalMD ''
if `extraInputsFlake` is set, then `builtins.getFlake extraInputsFlake`, else `{ }`
'';
};
module = mkOption {
type = (extendModules {
specialArgs =
let
inputs2 = inputs // config.extraInputs // {
self = self2;
};
self2 = self // {
inputs = inputs2;
};
in
{
inputs = inputs2;
self = self2;
partitionStack = partitionStack ++ [ name ];
};
}).type;
default = { };
description = ''
A re-evaluation of the flake-parts top level modules.
You may define config definitions, imports, etc here, and it can be read like any other submodule.
'';
};
};
config = {
extraInputs = lib.mkIf options.extraInputsFlake.isDefined (
let
p = options.extraInputsFlake.value;
flake =
if builtins.typeOf p == "path"
then get-flake p
else builtins.getFlake p;
in
flake.inputs
);
};
};
# Nix does not recognize that a flake like "${./dev}", which is a content
# addressed store path is a pure input, so we have to fetch and wire it
# manually with get-flake.
# TODO: update this
get-flake = import (builtins.fetchTree {
type = "github";
owner = "ursi";
repo = "get-flake";
rev = "a6c57417d1b857b8be53aba4095869a0f438c502";
});
in
{
options = {
partitionedAttrs = mkOption {
type = types.attrsOf types.str;
default = { };
description = ''
A set of flake output attributes that are taken from a partition instead of the default top level flake-parts evaluation.
The attribute name refers to the flake output attribute name, and the value is the name of the partition to use.
The flake attributes are overridden with `lib.mkForce` priority.
See the `partitions` options to understand the purpose.
'';
};
partitions = mkOption {
type = types.attrsOf (types.submodule partitionModule);
default = { };
description = ''
By partitioning the flake, you can avoid fetching inputs that are not
needed for the evaluation of a particular attribute.
Each partition is a distinct module system evaluation. This allows
attributes of the final flake to be defined by multiple sets of modules,
so that for example the `packages` attribute can be evaluated without
loading development related inputs.
While the module system does a good job at preserving laziness, the fact
that a development related import can define `packages` means that
in order to evaluate `packages`, you need to evaluate at least to the
point where you can conclude that the development related import does
not actually define a `packages` attribute. While the actual evaluation
is cheap, it can only happen after fetching the input, which is not
as cheap.
'';
};
};
config = {
# Default, overriden with specialArgs inside partitions.
_module.args.partitionStack = [ ];
flake = optionalAttrs (partitionStack == [ ]) (
mapAttrs
(attrName: partition: lib.mkForce (config.partitions.${partition}.module.flake.${attrName}))
config.partitionedAttrs
);
};
}

View file

@ -5,7 +5,8 @@
nixpkgs-lib.url = "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"; # 9f918d616c5321ad374ae6cb5ea89c9e04bf3e58 /lib from nixos-unstable
};
outputs = { nixpkgs-lib, ... }: {
outputs = inputs@{ nixpkgs-lib, ... }:
let
lib = import ./lib.nix {
inherit (nixpkgs-lib) lib;
# Extra info for version check message
@ -47,6 +48,22 @@
flakeModules = {
easyOverlay = ./extras/easyOverlay.nix;
flakeModules = ./extras/flakeModules.nix;
partitions = ./extras/partitions.nix;
};
in
lib.mkFlake { inherit inputs; } {
systems = [ ];
imports = [ flakeModules.partitions ];
partitionedAttrs.checks = "dev";
partitionedAttrs.devShells = "dev";
partitionedAttrs.herculesCI = "dev";
partitions.dev.extraInputsFlake = ./dev;
partitions.dev.extraInputs.flake-parts = inputs.self;
partitions.dev.module = {
imports = [ ./dev/flake-module.nix ];
};
flake = {
inherit lib templates flakeModules;
};
};

View file

@ -1,2 +1 @@
# non-idiomatic, see tools/README.md
(import ./dev).devShells.${builtins.currentSystem}.default
(builtins.getFlake ("git+file://" + toString ./.)).devShells.${builtins.currentSystem}.default