flakelight/README.md
2023-08-27 18:36:21 -07:00

4.9 KiB

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. Package metadata is taken from the project's Cargo.toml.

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

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 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;
}