Framework for simplifying flake setup [maintainer=@accelbread]
Go to file
Archit Gupta ff24d5d433 Allow bundlers to be functions that take pkgs
In addition to a regular bundler of the form `x: x`, this allows setting
bundler options to a function of the form `pkgs: x: x` which is passed
the package set for the system (for example: `{ hello, ... }: x: hello`
to always return hello). This allows, in particular, an autoloaded
bundler in its own file to access the package set.

This is non-trivial as we must tell `x: x` and `pkgs: x: x` apart.

Fortunately, given some derivation `drv`, `pkgs // drv` is a valid
derivation and a set with attr names matching pkgs. When applying this
to the function, if it returns a derivation, it was of the `x: x` form,
and if it returns a function, it was of the `pkgs: x: x` form.

In order to prevent IFD when evaluating the flake if the bundler is of
form `x: x` and uses IFD, we determine the form and apply pkgs when
applying the bundler instead of during flake evaluation. This is done by
wrapping the bundler.

Of note, we cannot rely on `builtins.functionArgs`, since
`pkgs: { hello, ... }: (x: hello) pkgs` is the same as the inner
function but with args hidden.
2023-11-06 23:13:47 -08:00
builtinModules Allow bundlers to be functions that take pkgs 2023-11-06 23:13:47 -08:00
nix/flakelightModules Add module for use in module flakes 2023-09-13 23:17:17 -07:00
templates Add basic flake template 2023-08-27 17:57:30 -07:00
.editorconfig Set git commit line lengths to 72 2023-04-14 19:04:11 -07:00
.envrc Initial commit 2023-04-13 01:08:26 -07:00
.gitignore Initial commit 2023-04-13 01:08:26 -07:00
api_guide.md Add support for bundlers 2023-11-05 15:14:26 -08:00
default.nix Allow bundlers to be functions that take pkgs 2023-11-06 23:13:47 -08:00
flake.lock Reimplement framework using the module system 2023-08-26 22:39:28 -07:00
flake.nix Add lib option 2023-09-13 23:17:17 -07:00
LICENSE Initial commit 2023-04-13 01:08:26 -07:00
README.md Update Rust example in README 2023-09-13 23:43:08 -07:00

Flakelight

A modular Nix flake framework for simplifying flake definitions.

Goals

  • Minimize boilerplate needed for flakes
  • Support straightforward configuration of all vanilla flake attributes
  • Allow sharing common configuration using modules
  • What can be done automatically, should be
  • Provide good defaults, but let them be changed/disabled

Features

  • Handles generating per-system attributes
  • Extensible using the module system
  • Given package definitions, generates package and overlay outputs
  • Automatically import attributes from nix files in a directory (default ./nix)
  • Builds formatter outputs that can format multiple file types
  • Provides outputs/perSystem options for easy migration

Documentation

See the API docs for available options and example usage.

Additional modules

The following modules are also available:

Examples

Shell

The following is an example flake.nix for a devshell, using the passed in nixpkgs. It outputs devShell.${system}.default attributes for each configured system. Systems can be left unset to use the default.

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixpkgs-unstable";
    flakelight.url = "github:accelbread/flakelight";
  };
  outputs = { flakelight, ... }@inputs:
    flakelight ./. {
      inherit inputs;
      systems = [ "x86_64-linux" "aarch64-linux" ];
      devShell.packages = pkgs: [ pkgs.hello pkgs.coreutils ];
    };
}

With this flake, calling nix develop will make hello and coreutils available.

Rust package

The following is an example flake for a Rust project using flakelight-rust, invoked by using flakelight-rust's wrapper. Package metadata is taken from the project's Cargo.toml.

{
  inputs.flakelight-rust.url = "github:accelbread/flakelight-rust";
  outputs = { flakelight-rust, ... }: flakelight-rust ./. { };
}

Alternatively, you can just use the flakelight-rust module as follows:

{
  inputs = {
    flakelight.url = "github:accelbread/flakelight";
    flakelight-rust.url = "github:accelbread/flakelight-rust";
  };
  outputs = { flakelight, flakelight-rust, ... }: flakelight ./. {
    imports = [ flakelight-rust.flakelightModules.default ];
  };
}

The above flakes export the following:

  • Per-system attributes for default systems (x86_64-linux and aarch64-linux)
  • packages.${system}.default attributes for each system
  • overlays.default providing an overlay with the package (built with the applied pkg set's dependencies)
  • devShells.${system}.default that provides rust-analyzer, cargo, clippy, rustc, and rustfmt as well as sets RUST_SRC_PATH
  • checks.${system}.${check} attributes for build, test, clippy, and formatting checks
  • formatter.${system} with additional support for formatting Rust files.

See flakelight-rust.nix to see how to configure it without the module.

C application

The following example flake is for a C project with a simple make setup.

{
  inputs.flakelight.url = "github:accelbread/flakelight";
  outputs = { flakelight, ... }:
    flakelight ./. {
      description = "My C application.";
      license = "AGPL-3.0-or-later";

      package = { stdenv, defaultMeta }:
        stdenv.mkDerivation {
          name = "hello-world";
          src = ./.;
          installPhase = ''
            runHook preInstall
            make DESTDIR=$out install
            runHook postInstall
          '';
          meta = defaultMeta;
        };

      devShell.packages = pkgs: with pkgs; [ clang-tools coreutils ];

      formatters."*.c | *.h" = "clang-format -i";
    };
}

This flake exports the following:

  • Per-system attributes for default systems (x86_64-linux and aarch64-linux)
  • packages.${system}.default attributes for each system
  • overlays.default providing an overlay with the package (built with the applied pkg set's dependencies)
  • devShells.${system}.default that provides clang-tools and coreutils.
  • checks.${system}.${check} attributes for build and formatting checks.
  • formatter.${system} with additional support for formatting c and h files with clang-format.

C application using autoloads

The above example can instead use the autoload directory feature for the package like the following. Most attributes can be autoloaded.

./flake.nix:

{
  inputs.flakelight.url = "github:accelbread/flakelight";
  outputs = { flakelight, ... }@inputs:
    flakelight ./. {
      description = "My C application.";
      license = "AGPL-3.0-or-later";

      devShell.packages = pkgs: with pkgs; [ clang-tools coreutils ];

      formatters."*.c | *.h" = "clang-format -i";
    };
}

./nix/packages/_default.nix:

{ stdenv, defaultMeta }:
stdenv.mkDerivation {
  name = "hello-world";
  src = ./.;
  installPhase = ''
    runHook preInstall
    make DESTDIR=$out install
    runHook postInstall
  '';
  meta = defaultMeta;
}