What is the significance of nix channels’ aliases on nix-shells? I just ran into a situation where I was trying to install rust-analyzer, but was unable to do so until I created another channel alias called nixpkgs.
To be clear, I originally had this output from nix-channel --list
nixos https://nixos.org/channels/nixos-unstable
Running nix search rust-analyzer yielded the following (among other nixos... results):
nixos.rust-analyzer (rust-analyzer-unstable)
So I knew the package was there, but I was still told that the attribute didn’t exist.
When I added a new alias for the same channel, suddenly everything worked. The output of nix-channel --list looks like this now:
Why does it matter what alias is used? I’m sure I’m missing something, but I haven’t been able to find any info on this.
And while we’re at it, what’s the difference between the root channels (sudo nix-channel --list) and the user level ones? I use the latest stable for nixos for root, but unstable for the user. Is this good? Bad? Normal? Is there a guide for how to do this somewhere?
The aliases are used between the <> brackets in Nix code, like <nixpkgs> or <nixos> – that’s a valid Nix expression in code which is why you see things like import <nixpkgs> {}. I’m assuming you’re using nix-env to install packages, so what you’d need to do is nix-env -f '<nixos>' -iA rust-analyzer. The -A is important, it says “dump all the fields in nixpkgs to my top-level scope” so you can simply refer to it as rust-analyzer.
By default nix-env uses <nixpkgs>, or specifically a partial set of it without things like haskellPackages because they slow things down and you explicitly need use -f '<nixpkgs>' (or <nixos>) to force evaluation of the whole thing, but unless your package is a specific language’s library or tool, it’s likely outside of these languagePackages attributes.
For root and user channels, your system (nixos-rebuild) uses the root ones, and your user uses the user ones through nix-env, nix repl, nix-build, nix-shell, and so forth. So you’d upgrade the packages your system has available if you did sudo nix-channel --update.
Also instead of nix search you can use nix repl '<nixpkgs>' to see what <nixpkgs> contains. <> expressions also support sub-directories, so nix repl '<nixpkgs/nixos>' evaluates the NixOS specific parts of nixpkgs (i.e. default.nix in nixpkgs/nixos), that your system uses, albeit – as mentioned – from the channel defined by root.
Edit: sorry just noticed you mentioned nix-shell, yeah, it uses <nixpkgs> by default. You can override it with e.g. nix-shell -I nixpkgs=/home/user/nixpkgs. Instead of a path you can also provide an URL to a tarball: nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/tarball/master -p hello
If you do echo $NIX_PATH you’ll see something like nixpkgs=foo nixos-config=bar and those are indeed available within <> brackets.
@Shou Thanks for the detailed answer. That explains a lot! I think I originally had nixpkgs, but changed it to nixos because something wasn’t working as expected, but I can’t remember what now. I’ll see if I can find out.
Thanks also for the clarification on root vs user level channels. This was very much in line with my understanding, so I’m glad to see that I at least got something right, hah.
About the nix repl: is there a guide on how to do find packages or use it for anything useful? I’ve never used it because I’m not sure what I’d use it for.
As for nix-shell and shell.nix files: I usually see files that start with:
{ pkgs ? import <nixpkgs> {} }:
If that was changed to
{ pkgs ? import <foo> {} }:
would it have made it use the foo channel instead?
Actually, the angle bracket syntax is Nix feature unrelated to channels. It only happens that a directory containing channel symlinks is listed in the NIX_PATH environment variable by default.
Yup, as long as you have /nix/var/nix/profiles/per-user/root/channels in your $NIX_PATH (or $HOME/.nix-defexpr/channels for the user channels).