nix

How do I test each of the attributes in my Nix flake’s outputs’s formatter attribute set?


I have a concern that I think about whenever I create Nix flakes. At the moment, I use a x86_64-linux system, but I might end up using a different system in the future. I’m concerned that the flakes that I write right now will end up only working on x86_64-linux systems. In order to alleviate my concern, I now have a rule that I follow whenever I create flakes: all of the outputs should work on at least two different systems. If all of my flakes’s outputs support at least two different systems, then (hopefully) it will be easy to add support for a third system in the future. At the moment, I’ve been using x86_64-linux as the primary system for my flakes and i686-linux as the secondary system for my flakes. I chose to use i686-linux as the secondary system because it’s easy to run i686-linux code on x86_64-linux systems.

Consider this flake. flake.nix:

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
  outputs =
    { self, nixpkgs }:
    let
      supportedSystems = [
        "i686-linux"
        "x86_64-linux"
      ];
      forEachSupportedSystem =
        function:
        nixpkgs.lib.attrsets.genAttrs supportedSystems (
          system: function nixpkgs.legacyPackages."${system}"
        );
    in
    {
      devShells = forEachSupportedSystem (pkgs: {
        default = pkgs.mkShell {
          name = "example-shell";
          packages = [ pkgs.hello ];
        };
      });
      formatter = forEachSupportedSystem (pkgs: pkgs.nixfmt-rfc-style);
    };
}

flake.lock:

{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": 1745487689,
        "narHash": "sha256-FQoi3R0NjQeBAsEOo49b5tbDPcJSMWc3QhhaIi9eddw=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "5630cf13cceac06cefe9fc607e8dfa8fb342dde3",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixos-24.11",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs"
      }
    }
  },
  "root": "root",
  "version": 7
}

I can easily test that flake’s dev shells by running these two commands:

nix --extra-experimental-features 'nix-command flakes' develop '.#devShells.i686-linux.default'
nix --extra-experimental-features 'nix-command flakes' develop '.#devShells.x86_64-linux.default'

How would I go about testing that flake’s formatters? I know that I can run nix --extra-experimental-features 'nix-command flakes' fmt to test the x86_64-linux one, but how do I test the i686-linux one?

I tried using similar commands to the ones that I used for the dev shells, but those two commands didn’t work:

$ nix --extra-experimental-features 'nix-command flakes' fmt '.#formatter.i686-linux'
Passing directories or non-Nix files (such as ".#formatter.i686-linux") is deprecated and will be unsupported soon, please use https://treefmt.com/ instead, e.g. via https://github.com/numtide/treefmt-nix
$ nix --extra-experimental-features 'nix-command flakes' fmt '.#formatter.x86_64-linux'
Passing directories or non-Nix files (such as ".#formatter.x86_64-linux") is deprecated and will be unsupported soon, please use https://treefmt.com/ instead, e.g. via https://github.com/numtide/treefmt-nix
$ 

Instead of interpreting .#formatter.i686-linux as “use this specific thing from this specific flake’s outputs”, that argument was interpreted as “try to format a file named .#formatter.i686-linux”.


Solution

  • You can test each of the attributes in a flake’s outputs’s formatter attribute set by using nix run:

    nix --extra-experimental-features 'nix-command flakes' run '.#formatter.i686-linux' flake.nix
    nix --extra-experimental-features 'nix-command flakes' run '.#formatter.x86_64-linux' flake.nix