Saving expressions versions with nix-shell

I’m using direnv integration with nix-shell and it makes for a very nice workflow, and I always get the most recent version of all, say, my R packages whenever I do a system --update, which is good.

However it might happen that I leave the code for a couple of months (durnig which I might nix-collect-garbage), go back to it, get a flurry of new package versions, and something doesn’t work anymore.

In order to pinpoint what the problem is, it would be useful to know which was the version of each package that was installed (or rather, linked to the environment) through the default.nix during the last nix-shell invocation.

Is there a way to get that information, so that I can save it to a file and compare later? Something like:

default.nix run, 2018-11-26


it should be possible to “add a Garbage Collection root” or something like that
if i understand correctly this should prevent nix-collect-garbage removing the dep’s of your shell
nix-instantiate shell.nix --indirect --add-root $DIR/.nix-gc-roots/shell.drv ...

" --indirect and --add-root"

the comment here suggest this is no longer the case =/

The nix-shell options quoted above seem to be silently ignored today. I’m accomplishing something similar by parsing the output of nix show-derivation somewhat laboriously. It would be much nicer for nix tools to have some first-class way to reference a build-time closure.

nix-shell dependencies can be garbage collected any time now / persistent nix-shell envs · Issue #2208 · NixOS/nix · GitHub # nix-shell dependencies can be garbage collected any time now / persistent nix-shell envs

--indirect is now ignored as of 19477e8 this also no longer works as gcroot to the output is no longer created.

… +more scrips and hints in the above link

I think pinning nixpkgs directly in the default.nix may be a good solution?

1 Like

There is also a wiki article for persistent direnv shells:

1 Like

Great stuff, thanks.

I would still like to be able to generate the equivalent of a packrat.lock or requirement.txt file on each run, though.

Using these approaches it wouldn’t be easy to find which packages have changed versions (or would it?), while if I had a text file with the versions I would simply be a diff away from knowing which package is the culprit.

Something like nix-store -q for the current nix-shell environment, minus the default one for the user.

1 Like

Fully persistent Nix shell (gist)
more discussion @ [Nix-dev] truly persistent nix-shell

A bit late to the party… but a tool doing what you want was created in March 2019: GitHub - target/lorri: Your project's nix-env

Thanks! I tried that, but it gave me a weird problem. I cannot be enterely precise (I forgot in the meantime), but it was something like:

  • I have a shell.nix in the directory
  • it callPackage's another file somewhere else, providing package xyz
  • enter the environment, all fine
  • I update the version of that package to something newer
  • the environment still loads the the old version of xyz
  • i have to manually run nix-shell to get the new version

Again, not sure if that’s exactly what happened, but I do remember needing to run nix-shell manually

@mredaelli> I believe that’s weird indeed (though I’m not a lorri expert).

Did you install the daemon:

? The daemon is responsible for listening to updates.

I did.

Will give it another try sometime :slight_smile: