Nix commands returning unexpected packages

Hi I’m trying to understand (and perhaps fix) these unexpected results to simple nix commands

Given nix-env -qaP ‘ruby.*’ output includes this…

nixpkgs.ruby                                                    ruby-2.7.5
nixpkgs.ruby_3_0                                                ruby-3.0.3
nixpkgs.ruby_3_1                                                ruby-3.1.0

And I can :

$nix-shell -p "ruby_3_0" --run "which ruby"    
/nix/store/nhy5jkwh4g87msljr9ig3mym6w0fvij6-ruby-3.0.2/bin/ruby

and

 $ nix-shell -p "ruby" --run "which ruby"                                                                                                                                /nix/store/fc9zf2l14j9z213dnj1rz71rc04qzqch-ruby-2.7.4/bin/ruby

Shouldn’t I expect something similar for ruby_3_1:

$nix-shell -p "ruby_3_1" --run "which ruby"                                                                                                         error: undefined variable 'ruby_3_1'
 at «string»:1:107:
 1| {...}@args: with import <nixpkgs> args; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (ruby_3_1) ]; } ""

Another scenario; the package ‘rubyPackages_3_0.rails’ should return rails 7 but instead it returns rails 6:

$>nix-env -qaP 'ruby.*'|grep rails|grep 3_0|grep 7
nixpkgs.rubyPackages_3_0.rails                                  ruby3.0.3-rails-7.0.1
$> nix-shell -p "rubyPackages_3_0.rails" --run "rails --version" --pure
Rails 6.1.4.1

Do I fundamentally have a misunderstanding of how these commands should work? or, is there something else going on? And is there a way I can have these commands behave as expected?

Thanks in advance,

As meantioned in the discord earlier today, it doesn’t really make sense on the first glance, though on the second it might be related to the different ways how nix-env and the rest of the nix ecosystem treat channels.

Can you please share the output of each of these commands?

sudo nix-channel --list
nix-channel --list
printenv NIX_PATH

Hey NoobZ, man you are everywhere… thanks for replying

glenn@quokka> sudo nix-channel --list                                                                                                                                               ~/w/rails-template-01
Password:
darwin https://github.com/LnL7/nix-darwin/archive/master.tar.gz
home-manager https://github.com/nix-community/home-manager/archive/master.tar.gz
nixpkgs https://nixos.org/channels/nixpkgs-unstable
glenn@quokka> nix-channel --list                                                                                                                                                    
darwin https://github.com/LnL7/nix-darwin/archive/master.tar.gz
home-manager https://github.com/nix-community/home-manager/archive/master.tar.gz
nixpkgs https://nixos.org/channels/nixpkgs-unstable
glenn@quokka> printenv NIX_PATH                                                                                                                                                     
darwin-config=/Users/glenn/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels:/Users/glenn/.nix-defexpr/channels

Is this a single user install or multiuser?

multi user (at least as I understand it… it uses a nix daemon)

This supports my claim of the different behaviour between nix-env and the rest of the nix-world.

nix-env looks in ~/.nix-defexpr and only there, unless -f is provided.

Though the rest of the world uses NIX_PATH to resolve. They will look up in /nix/var/nix/profiles/per-user/root/channels first, and if they find a folder nixpgs there, they will not search further.

So your roots channels “win” when you do nix-shell, while nix-env doesn’t consider them.

Try nix-shell -I nixpkgs=/Users/glenn/.nix-defexpr/channels/nixpkgs -p "ruby_3_1" --run "which ruby" to enforce usage of the users channel.

Alternatively you should be able to do nix-env -f '<nixpkgs>' -qaP 'ruby.*' to actually search the channels of root, as -f '<nixpkgs>' enforces NIX_PATH resolution.

The rails version mismatch is probably because of the channel mismatches as well, and versions would congruent if usage of same channel locations is enforced.

1 Like

Oh my… seems crazy to me… but, you are correct, that invocation of nix-shell does install the correct version of ruby. Thanks again, that was very enlightening.