One thing I have been missing ever since I started using NixOS was a way to see how package versions were changing whenever I updated Nixpkgs. I wanted something like the “pretend” output from other distros’ package managers, but also something that wouldn’t produce thousands of lines of output when a mass rebuild happened.
So today I’m happy to announce nvd, a short script I’ve written that does just that. It prints out any versions that differ between two given closures. It also recognizes packages that are in environment.systemPackages and adds highlighting for them.
I hope this can be useful to you too. Most of the documentation is in the man page in the repo. I’m not aware of any Nix tools that provide similar output, so please let me know if there is something similar that I’ve missed.
[Edit 2024-09-29: Updated the link, since the nvd repo is moving.]
Thanks. I have not tried home-manager yet so I will have to look into how home.packages is represented. You can at least pass nvd the paths to the buildEnvs and it will do the right thing. When it’s given two regular store paths, it takes the closures and then highlights direct dependencies.
There’s special handling for NixOS system configurations, where if sw exists in both arguments then their direct dependencies get highlighted instead. Maybe something similar would help with home-manager? For example if
nvd ~/.nix-profile "$(home-manager build)"
(or whatever the correct line is) doesn’t work as expected?
nix-diff provides similar functionality, it’s very useful. This looks much nicer especially for things like system generations, although maybe it looks less nice on arbitrary derivations.
Being greedy… It seems to me like from a UX perspective it would be nice to have both the nix-diff and nvd functionality as output options of one derivation-diffing tool. Have you thought at all about whether you could consider merging them?
The main difference between nvd and nix-diff is not the output format, I think: it is that nvd works on store paths and nix-diff works on derivations. This makes it natural for nvd to answer the question “what user-visible things changed” and for nix-diff to answer “what causes this derivation to be different”.
On the other hand, I seem to remember the mechanisms are similar for both closures and derivations (in both cases, you call nix-store --query --requisites), so doing both might actually be doable.
Is it expected that the nixos-system-schwarzbaer is not separated into smaller chunks? Or should I use different profile paths?
Thanks!
EDIT: The NUR package failed to build, so I remove it for now, not sure why this is the case:
Run nix-env -f . -qa \* --meta --xml \
error: cannot import '/nix/store/xyg1nj013dafwcfg2z472xflxqm245yb-source', since path '/nix/store/ixka5r0lqqrf25j9fafxf2zd1c5ywmhn-source.drv' is not valid, at /home/runner/work/nur-packages/nur-packages/default.nix:30:9
Error: Process completed with exit code 1.
@madjar, that’s interesting, I hadn’t thought about calling this post-activation, but that’s a really good idea.
And right, there’s nix-diff which I should have mentioned. That’s definitely the tool for finding out why results differ. It’s always a bit of work to get a good picture of the difference between two store paths. nix-diff does a really good job of showing you everything, but you have to navigate the output. If only one config file deep in the dependency tree changed, you have to think “okay I know all these hashes only changed for this reason,” since Nix has no idea about the meaning of the change. Until we can teach Nix that… nvd simplifies things by parsing names in store paths and grouping things under those names, but it can’t give the full picture – e.g. why there are two versions of a package, do they differ in build flags or architecture, or maybe it’s an entirely different package that simply shares the name. If I could have three Nix wishes, I’d ask for additional metadata on built packages to make the UI so that these things would be easier to present to the user.
nvd used to be callable with derivations, but the result isn’t pretty or usable. Lots of things in derivation closures don’t have nice names and parsing them breaks down, e.g. with source directories, or many cases of <long hex string>.patch or CVE-XXXX-XXXXX.patch. (Used to: it looks like I broke it, I’ll have to fix that. nvd should work if given a derivation or non-directory store path. It does just call nix-store -qR under the hood. Right now, the code’s expecting it to be a directory though.)
Though @michaelpj I agree that on the UI front, having a combined tool would be nice.
@dschrempf, that’s fine by me if you want to package it. Thanks! I don’t have a NUR repository set up for myself. If you’re asking about the parsing into nixos-system-schwarzbaer and 21.05pre282432.311ceed827f, that’s as correct as it can be, following how builtins.parseDrvName works. If you want to cut out the system name and the kernel and modules, you could perhaps pass /run/current-system/sw instead.
I’ve been running nvd on an SSD so far and ran it on a hard drive for the first time today. Crawling through the system-path derivation can sure take a while. I originally had a NixOS module to produce a manifest file based on environment.systemPackages, and nvd would read that file rather than walking the filesystem. I’d be open to restoring that functionality if there’s interest. (Edit: Or for home-manager of course. The idea is just to take the list of explicitly selected packages and write all their store paths to a file at a well-known path for nvd to find.)
That would be best. I will submit a PR. There are a couple of quick improvements I want to make first (one of them being getting rid of that directory crawl). I hadn’t seen the issues you filed @DamienCassou, apologies, when I created the GitLab repo it didn’t automatically set me to be notified on activity.
It turns out that evaluation the Nix option restrict-eval is enabled for builds in NURs, that’s why the nvd build worked locally, but failed when I uploaded the change to NUR. I guess we have to wait for the nixpkgs pull request.
@ony are you using a new version of nix? nix 2.3.10 does not have a store command (at least I cannot find it).