I found a nice flake in the docs of nix shell (GitHub - tomberek/-) and now I want to add it to my local registry. But that flake has a flake input for nixpkgs so I thought “that should follow my nixpkgs” (so I will have less copies in the store and need not evaluate so many nixpkgs versions).
But my experiments show that the flake input gets written to the same store path no matter if I let its input follow something or not.
Here is a minimal flake that demonstrates the problem:
{
description = "How can I link to a modified flake from my inputs?";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
original.url = "github:tomberek/-";
following.url = "github:tomberek/-";
following.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = inputs: let
pkgs = import inputs.nixpkgs {system = "x86_64-linux";};
info = flake: {inherit (flake) lastModified narHash shortRev;};
traceAndBuild = input: let
flake = inputs.${input};
clean = info flake // {nixpkgs = info flake.inputs.nixpkgs; name = input;};
in
pkgs.lib.debug.traceSeqN 2 clean
''
cat <<EOF | ${pkgs.lib.getExe pkgs.jq} > $out/${input}.json
${builtins.toJSON clean}
EOF
ln -s ${flake} $out/${input}
'';
in {
packages.x86_64-linux.default = pkgs.runCommand "debug" {} ''
mkdir $out
${traceAndBuild "original"}
${traceAndBuild "following"}
'';
};
}
The result looks like this
$ ls -l result/
total 8
lrwxrwxrwx 1 root root 50 Jan 1 1970 following -> /nix/store/zizzgvr1i4rg3ygicmzs34c9a6fq0j8p-source
-r--r--r-- 1 root root 297 Jan 1 1970 following.json
lrwxrwxrwx 1 root root 50 Jan 1 1970 original -> /nix/store/zizzgvr1i4rg3ygicmzs34c9a6fq0j8p-source
-r--r--r-- 1 root root 296 Jan 1 1970 original.json
$ diff result/*.json
3c3
< "name": "following",
---
> "name": "original",
6,8c6,8
< "lastModified": 1753694789,
< "narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=",
< "shortRev": "dc96378"
---
> "lastModified": 1744232761,
> "narHash": "sha256-gbl9hE39nQRpZaLjhWKmEu5ejtQsgI5TWYrIVVJn30U=",
> "shortRev": "f675531"
Note that I had to remove some attributes from the flakes before dumping them to json, otherwise their outPath would be show or I would get evaluation errors from some derivations in nixpkgs if I seq’ed to deep.
My question is thus: Can I get a modified outPath for my flake input that follows my nixpkgs? How do I do that?
Yes, because you’re not changing the upstream flake, you’re changing your own flake’s lockfile. So the upstream flake’s narHash won’t change.
This sounds x-y but I don’t know what you’re trying to accomplish here. Using follows will not save space in the storage of the upstream flake, as it’s going to download the whole thing regardless. It just won’t fetch multiple nixpkgs inputs.
Saving disk space (and even more so evaluation time) by not having two different versions of nixpkgs is my aim.
I want to write this github:tomberek/- to my local nix registry. It is actually a utility flake with very little code (so this flake itself does not take much disk space) so I want to write nix shell p#python3With.requests instead of nix shell github:tomberek/-#python3With.requests. So I do this:
But this results in two versions of nixpkgs and if I use nix shell p#... later on these packages get pulled from the locked input of tomberek/- instead of my nixpkgs version.
You’re already doing that with follows*. Again, not sure what the rigmarole about store paths is.
*well, sort of. If you have the same nixpkgs input but they are configured differently or otherwise reimported then you’d still have multiple instances.
Use --override-input nixpkgs nixpkgs. (By default, NixOS creates a nixpkgs system registry entry tied to the nixpkgs that built your config.) That has nithing to do with follows though, as you’re now outside of your downstream flake context.
You can try. I’m not sure that will work due to the recent nix changes that ignore the system and user registries as flake inputs, combined with the fact that under various conditions nix just ignores the lockfile and does whatever it wants.
i.e. you may end up back to the solution I mentioned
I was thinking about that initially but than I would loose shell completion (or would have to write some for my script).
I could of course make a shell alias for just alias nsn=nix shell --override-input nixpkgs nixpkgs but that feels strange and would spit out errors if used with a flake that does not have the nixpkgs input:
warning: input '' has an override for a non-existent input 'nixpkgs'
warning: the flag '--override-input nixpkgs flake:nixpkgs' does not match any input