1
0
Fork 0
mirror of https://github.com/hercules-ci/flake-parts.git synced 2024-12-14 11:47:31 +00:00
❄️ Simplify Nix Flakes with the module system
Find a file
2022-10-11 19:20:13 +01:00
dev Add hercules-ci-effects doc 2022-05-29 18:30:11 +02:00
modules Remove redundant null filters 2022-09-28 19:13:41 +02:00
site Write a bit about integrations 2022-05-29 18:42:42 +02:00
template Only depend on nixpkgs/lib. 2022-10-11 13:59:40 -04:00
.gitignore Add .gitignore 2022-05-25 16:38:27 +02:00
all-modules.nix add formatter schema 2022-09-19 16:59:51 +02:00
bors.toml Add bors bot 2022-05-19 09:48:46 +02:00
ChangeLog.md Update ChangeLog.md 2022-10-11 19:20:13 +01:00
ci.nix dev: Add nixpkgs-fmt to pre-commit 2022-05-17 10:37:27 +02:00
flake.lock Only depend on nixpkgs/lib. 2022-10-11 13:59:40 -04:00
flake.nix Only depend on nixpkgs/lib. 2022-10-11 13:59:40 -04:00
lib.nix perSystem: functionTo -> deferredModule 2022-05-25 18:18:50 +02:00
LICENSE Initial commit 2021-10-27 11:03:43 +02:00
README.md Only depend on nixpkgs/lib. 2022-10-11 13:59:40 -04:00
shell.nix Add local tooling and CI wiring without bloating flake.nix 2022-05-17 10:12:40 +02:00

Flake Parts

Core of a distributed framework for writing Nix Flakes.

flake-parts provides the options that represent standard flake attributes and establishes a way of working with system. Opinionated features are provided by an ecosystem of modules that you can import.

Why Modules?

Flakes are configuration. The module system lets you refactor configuration into modules that can be shared.

It reduces the proliferation of custom Nix glue code, similar to what the module system has done for NixOS configurations.

Unlike NixOS, but following Flakes' spirit, flake-parts is not a monorepo with the implied goal of absorbing all of open source, but rather a single module that other repositories can build upon, while ensuring a baseline level of compatibility: which core attribute make up a flake and how these are represented as module options.

Getting Started

If your project does not have a flake yet:

nix flake init -t github:hercules-ci/flake-parts

Otherwise, add the input,

    flake-parts.url = "github:hercules-ci/flake-parts";

then slide mkFlake between your outputs function head and body,

  outputs = { self, flake-parts, ... }:
    flake-parts.lib.mkFlake { inherit self; } {
      flake = {
        # Put your original flake attributes here.
      };
      systems = [
        # systems for which you want to build the `perSystem` attributes
        "x86_64-linux"
        # ...
      ];
    };

Now you can add the remaining module attributes like in the the template.

Example

See the template.

Options Reference

See flake.parts

Top-level module parameters

  • config, options, lib, ...: standard module system parameters.

  • getSystem: function from system string to the config of the appropriate perSystem.

  • moduleWithSystem: function that brings the perSystem module arguments. This allows a module to reference the defining flake without introducing global variables (which may conflict).

    { moduleWithSystem, ... }:
    {
      nixosModules.default = moduleWithSystem (
        perSystem@{ config }:  # NOTE: only explicit params will be in perSystem
        nixos@{ ... }:
        {
          services.foo.package = perSystem.config.packages.foo;
          imports = [ ./nixos-foo.nix ];
        }
      );
    }
    
  • withSystem: enter the scope of a system. Worked example:

    { withSystem, ... }:
    {
      # perSystem = ...;
    
      nixosConfigurations.foo = withSystem "x86_64-linux" (ctx@{ pkgs, ... }:
        pkgs.nixos ({ config, lib, packages, pkgs, ... }: {
          _module.args.packages = ctx.config.packages;
          imports = [ ./nixos-configuration.nix ];
          services.nginx.enable = true;
          environment.systemPackages = [
            packages.hello
          ];
        }));
    }
    

perSystem module parameters

  • pkgs: Defaults to inputs.nixpkgs.legacyPackages.${system}. Can be set via config._module.args.pkgs.

  • inputs': The flake inputs parameter, but with system pre-selected. Note the last character of the name, ', pronounced "prime".

    system selection is handled by the extensible function perInput.

  • self': The flake self parameter, but with system pre-selected. This might trigger an infinite recursion (#22), so prefer config.

  • system: The system parameter, describing the architecture and platform of the host system (where the thing will run).

Equivalences

  • Getting the locally defined hello package on/for an x86_64-linux host:
    • nix build #hello (assuming systems has x86_64-linux)
    • config.packages.hello (if config is the perSystem module argument)
    • allSystems."x86_64-linux".packages.hello (assuming systems has x86_64-linux)
    • (getSystem "x86_64-linux").packages.hello)
    • withSystem "x86_64-linux" ({ config, ... }: config.packages.hello)

Why so many ways?

  1. Flakes counterintuitively handles system by enumerating all of them in attribute sets. flake-parts does not impose this restriction, but does need to support it.
  2. flake-parts provides an extensible structure that is richer than the flakes interface alone.