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)?
I’ve noticed that
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
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
highPrio that update the prio accordingly (for
-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.
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 -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
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.