Using the global registry to create the initial flake.lock

I’m on NixOS unstable and through my configuration, I’ve pinned the specific revision of nixpkgs my system builds off of to the global flake registry. I want to re-use that revision when I create new flakes (that consume nixpkgs as an input) to avoid having multiple revisions of nixpkgs scattered across my various flakes (and thereby my /nix/store).

I am aware that you can have the flake use the global registry by doing inputs.nixpkgs.url = "nixpkgs", but this produces an impure lock file that doesn’t use the correct nixpkgs version on other machines (unless this has changed in recent versions?).

What I’m hoping to do (in theory, and if possible), is to create a flake with a valid nixpkgs flake reference, and during the creation of the initial lock file, use the revision information from the global registry to sync nixpkgs to the exact revision used by the global registry.

To demonstrate the idea visually, I want to be able to create a flake with the same branch ref as my NixOS system:

# flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # not trying to use flake registry at all
  };

  outputs = { … }: {
    # <omitted>
  };
}

Then, I want to be able to invoke some nix3 command that can create the initial flake.lock file with the same revision information as what is saved in the flake registry:

# flake.lock
{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": "FROM_REGISTRY",
        "narHash": "FROM_REGISTRY",
        "rest_FROM_REGISTRY": "<omitted>",
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixos-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "nixpkgs": "nixpkgs"
    }
  },
  "root": "root",
  "version": 7
}

Is this possible at all? If so, how? If not, maybe I should post it as a feature request.

Make your flake.nix as normal, and for the lockfile you can probably use something like

myrev=$(nix flake metadata nixpkgs --json | nix run nixpkgs#jq .locked.rev)
nix flake update --override-input nixpkgs github:NixOS/nixpkgs/$myrev

NB /etc/nix/registry.json is not the global registry, that’s the system registry. I’m not nitpicking - you can use the global registry in flake inputs, but not the system registry. nix registry - Nix 2.32.7 Reference Manual

1 Like

Beautiful snippet of code, thank you very much! Also, thanks for clarifying the global vs system registry. I didn’t even realize that nix tries to download a global registry, I had thought there was only the local and system registries. I learned something new from that.

Minor fix to the above snippet though, jq needs the -r flag to prevent the quotes from causing issues. Otherwise, the snippet works exactly as I was imagining.

$ nix flake update --override-input nixpkgs $(nix flake metadata nixpkgs --json | nix run nixpkgs#jq -- -r '.locked.rev')
1 Like