UpdateScript makeBinPath or nix-shell

Some update scripts use export PATH=${lib.makeBinPath [ ... ] for the deps of the script and some use #!nix-shell -i bash -p .... Which is better?

As is often the case, there are trade-offs.

The main difference is that the former takes the dependencies from the current Nixpkgs, while the latter from different one (unless something like -I nixpkgs=../../../.. is also passed). That can be a benefit (e.g. when you modify update-source-version to fix an update script) or a downside (e.g. when trying to upgrade a package on staging branch and you do not have the time to rebuild the world).

Somewhat related to this is the time when you evaluate the Nix expression. nix-shell needs to evaluate Nixpkgs every time it is started, which makes it pretty slow. This is especially visible when running multiple update scripts at the same time. But that should not be a big issue with update scripts, whose runtime will probably be dominated by downloading sources, and people tend to run the update scripts in background anyway.

Additionally, the fact that evaluation of the shell expression of a nix-shell-shebang script is completely decoupled from Nixpkgs expression, makes it easier to miss when it breaks (e.g. due to removal of a package alias).

Lastly, there is a consideration of style – constructing the update script within the package expression requires the package expression to have extra dependency arguments for the update script (or at least callPackage). I am not very fond of that but in the end, I still tend to prefer it over nix-shell-shebang scripts.

I guess for me, the main deciding factor is that, if I cannot use parametric update scripts like unstableGitUpdater or nix-update-script (where nix-shell-shebang scripts are not an option), I will want to access multiple attributes from the package (e.g. version, meta.platforms, …; example) and at that point, while it is possible to obtain their values in a separate file using nix-instantiate, direct access to them using Nix is IMO much nicer.

But some people still want to have the ability to run the update script directly rather than through nix-shell maintainers/scripts/update.nix and for that, nix-shell-shebang scripts are nice.

2 Likes

Thanks for your answer!

So if I want to pass some varibles from nix to shell directly I can’t run the script directly. But anyway it’s just a alias.

The latter will execute setup hooks. These you typically do not want to be executed because you do not want a development environment. When your invocation starts relying on those hooks you start relying on an implementation detail, and that’s not good.