I’ve noticed that nix-env -u
will frequently avoid applying updates that nix-env -qc
claims are available. For example, I have nodejs-8.15.1
installed, and nix-env -qc
tells me that version 11.13.0
is available, but nix-env -u
doesn’t apply that update. This is good, as there are multiple nodejs
packages for different major versions, but how does nix-env -u
know that it shouldn’t update (and why does nix-env -qc
not use the same logic)?
What prompted this question is I’m interested in having a second package for cocoapods
that provides access to the current beta, as cocoapods has a long beta cycle and really wants people to use them (and in fact you can’t even submit a package update with the stable right now because they updated the server to expect something the current beta does ). My question is, if I create a e.g. nixpkgs.cocoapods-beta
, with the same cocoapods
package name but the beta version, will nix-env -u
know not to upgrade from the stable version to the beta version? And then what happens when the beta is released and the stable is updated, will nix-env -u
upgrade from the beta to the stable, or will the cocoapods-beta
package have to adopt the stable version too? If the latter, what will nix-env -u
do when cocoapods-beta
once again has a new beta version?
Packages can specify a meta.prio
field (which defaults to 0
). nix-env
will prefer derivations with a lower meta.prio
(numerically speaking, to add extra confusion this is referred to as high prio in Nixpkgs), even if it has a lower version number. lib
defines the functions lowPrio
and highPrio
that update the prio accordingly (for 10
and -10
, respectively). This is what the Node 8.x package does.
As long as cocoapods-beta
has a higher (numerical) prio
, yes, it will prefer cocoapods
. However, it also won’t upgrade cocoapods-beta
installs to new beta releases, since the preferred release will be stable cocoapods
(which it will refuse to install since it has a lower version number).
At that point cocoapods
will have both a higher version number and a lower (numerical) prio, so nix-env -u
will upgrade to it. However, nixos-rebuild
and other tools that use Nixpkgs attribute names will not, so -beta
packages should still point to the stable build if there is no current beta release.
In general nix-env
(and especially upgrades) is a huge mess, and I’d strongly suggest avoiding using it to install individual packages, especially when you care about different package variants. Instead, use environment.systemPackages
(for system packages) or define a meta-package and install that (for single-user packages and non-NixOS systems).
Huh, I was under the impression that the priority only affected what happens if you try and install 2 derivations that both have the same output path. If this affects updating too, surely nix-env
won’t “update” to 8.x if I install a different version with a lower priority? Or does this only work if the highPrio
package is the one with the lowest version number?
I’m on macOS so I would have to do the meta-package route, but it seems kinda crappy for me to have to edit an overlay on disk any time I want to install or uninstall a package. I don’t suppose there are any plans to overhaul nix-env
upgrades?
nix-env -u
won’t downgrade a package, even if the newer version package is no longer longer available (or is shadowed by prios).
I can’t remember the name right now, but IIRC that’s a similar but unrelated system.
It’s pretty much the same workflow as for NixOS, which works fine for me (though it did take some getting used to). I expect this will be fixed when/if nix-env
is merged into nix
(which has replaced package names with attributes, removing the need for the prio system at all).
There is also Declarative package management for normal users - #2 by Mic92 which manages the meta-package for you.
I’ve been looking more into this approach and I’m a bit confused. The linked gist just declares packages as direct children of userPackages
(I assume, though haven’t verified, that if nix-env
is given a set it installs all members of the set), but the documentation on building an environment demonstrates using buildEnv
(with packageOverrides
but it seems I can ignore that bit).
I can’t find any documentation on buildEnv
itself. As best as I can figure from the example in building an environment, it can be used to change the paths to link from the whole package set without having to override each individual package, but if I don’t care about changing the paths to link, are there any pros or cons to using it? Would best practice be to take the aforelinked gist and tweak it to use buildEnv
or is that a problem if I then want multiple overlays to contribute to the package set?
IIRC removing a package from a buildEnv
will uninstall it on the next “rebuild”, while the lightweight meta-package can only ever add new packages, but don’t quote me on that.
I take it buildEnv
presents itself as a single installed package, so e.g. nix-env -q
won’t show me all the software it includes, it’ll just show me the name of the env?
Ok, thanks. So it sounds like buildEnv
is the way to go if I want to be able to use nix-env -i
to install individual packages in addition to the common collection, but avoiding buildEnv
and doing what’s in this gist is better if I want my overlay to be the single source of truth for all packages and want to be able to use nix-env -q
to query for what’s installed.