Capture flake source path

I would like to generate a script or alias that would execute nix-rebuild switch --flake /some/path/to/flake#hostname from wherever I call it. I can of course hard code the path to some convention like ~/nix-config or similar. But is there any way to capture the source directory of the flake during build? When I try to use a simple relative path I obviously get a nix store path in the result.

This should not be possible with pure builds, that would result in the build output being dependent on the directory your flake is in, which is impure and breaks evaluation caching. flakes copy themselves to /nix/store precisely to prevent this kind of thing.

Rather than trying to have a hard-coded path in the build output (but not hard-coded in the actual code), why not let your nixos config set an environment variable that points at the path where the flake is supposed to be, and use that to identify where the flake is at runtime?

nixos-rebuild supports NIXOS_CONFIG, but only for non-flake builds. I figure there might be some appetite for allowing flake builds to use that variable as well if you want to make those changes directly to nixos-rebuild.

Thanks for your reply @TLATER. As I’m new to Nix, I fail to think your suggestion through to a working solution. Would you mind elaborating on it in more detail?

Something like this:

# configuration.nix
{ pkgs, ... }: {
  environment.variables.NIXOS_CONFIG = "/etc/nixos";

  environment.systemPackages = [
    (pkgs.writeShellApplication {
      name = "rebuild-system";
      runtimeInputs = with pkgs; [ nixos-rebuild ];
      text = ''
        nixos-rebuild switch --flake "$NIXOS_CONFIG" $@
      '';
    })
  ];
}

Substitute the script with more fancy argument parsing as you see fit, or alternatively, contribute changes upstream that would make the nixos-rebuild command just natively support this (or even patch it downstream with an overlay).

This is still very close to hard-coding, but you have the opportunity to change the path on a per-system basis and override the path at runtime as you see fit, which should cover most of the use cases for snapshotting the repository path at build time. Either way, it’s the most dynamic you can get without breaking the purity of the build.

1 Like

Thanks a lot @TLATER! Now I see what you mean.