flake-parts

repository·main·Indexed 23 days ago

https://github.com/hercules-ci/flake-parts

A modular framework for writing Nix Flakes that provides a module system to split complex configurations into reusable units and simplifies the management of multi-system (perSystem) outputs.

Tokens
951
Snippets
3
Records
6
Agent score
79%

What's inside flake-parts

  1. What is flake-parts and why use modules?

    main

    flake-parts is a distributed framework for writing Nix Flakes. It provides a module system for flakes, allowing you to:

    • Refactor configuration: Split your flake.nix into focused, reusable modules.
    • Manage systems: Simplify the handling of perSystem attributes (e.g., building different outputs for x86_64-linux vs aarch64-darwin).
    • Reduce glue code: Avoid writing custom Nix logic to manage flake outputs.
    • Enable integration: Allow users of your library to easily integrate your generated flake outputs into their own flakes.

    flake-parts itself acts as a minimal mirror of the Nix flake schema, while providing an ecosystem of opinionated modules for advanced features.

  2. Migrate an existing flake to flake-parts

    main

    To migrate an existing Nix flake to use flake-parts, follow these steps:

    1. Add flake-parts as an input in your flake.nix:

      flake-parts.url = "github:hercules-ci/flake-parts";
    2. Wrap your existing outputs function using flake-parts.lib.mkFlake. The mkFlake function takes two arguments: the inputs and a configuration attribute set.

    3. Move your original flake attributes into the flake block, and specify the target architectures in the systems list.

      outputs = inputs@{ flake-parts, ... }: 
        flake-parts.lib.mkFlake { inherit inputs; } {
          flake = {
            # Put your original flake attributes here.
          };
          systems = [
            # systems for which you want to build the `perSystem` attributes
            "x86_64-linux"
            # ...
          ];
        };
  3. Fixing shell mismatch in nix develop

    main

    By default, nix develop is designed for Nixpkgs stdenv, which uses bash. If you want to use your preferred shell (e.g., zsh or fish) instead of being dropped into bash, consider these three approaches:

    1. Recommended: Use direnv. Use direnv to manage your development environments automatically. Refer to the direnv-guide for implementation details.
    2. The shellHook hack (Unreliable). You can attempt to force your shell using a shellHook in your devShells definition. Use this with caution as it can cause various issues:
      devShells.default = pkgs.mkShell {
        shellHook = ''
          exec $SHELL
        '';
      };
    3. Use nix print-dev-env. If you only need the environment variables and not the interactive shell, use nix print-dev-env. This is an incomplete solution for full shell replacement but works for extracting environment state.
  4. Create project scripts using mission-control

    main

    You can manage project scripts by integrating mission-control within your Nix flake. This approach serves as an alternative to using a Makefile, a scripts/ directory convention, or a bin/ directory.

    In this pattern, scripts are added to the shell environment. If you use wrapperName = "run"; in your configuration, the commands will be invoked using the run <command> syntax within the Nix shell.

    nix develop
    # Once in the shell:
    run build