nix-shell -p is too magical

Created on 2 Dec 2015  路  8Comments  路  Source: NixOS/nix

With nix-shell -A, I can pass it a .nix file to run expressions against, but I can't emulate that behavior easily with nix-shell -p. For example, nix-shell -p foo will install foo in my shell. If I run nix-shell '<nixpkgs>' -A foo, that doesn't give me the same thing. If I want something similar, @puffnfresh on IRC suggested this nasty thing:

nix-shell -E 'with import <nixpkgs> { }; runCommand "ignored" { buildInputs = [ (import ./.).foo ]; } ""'

which doesn't seem great. Can we have an easy way to get behavior like -p without relying on NIX_PATH voodoo or the incantation above?

Most helpful comment

@fkz nice! I didn't realise that was possible. Means we can do things like:

nix-shell -p "haskellPackages.ghcWithPackages (p: [p.lens p.JuicyPixels])"

Thanks :+1:

All 8 comments

A general nix question that might turn out to be relevant: is https://github.com/NixOS/nix/blob/master/corepkgs/buildenv.nix used just by nix-env or also used for making build environments?

The nix expression used is constructed here: https://github.com/NixOS/nix/blob/master/scripts/nix-build.in#L225

'with import <nixpkgs> { }; runCommand "shell" { buildInputs = [ '
. (join " ", map { "($_)" } @exprs) . ']; } ""');

@fkz thanks! Basically the same as I wrote above. :+1:

Yes, so as an alternative to your suggestion, the following could be used instead:

nix-shell -p "(import ./.).foo"

This might still not be exactly what we want because we have to repeat this "import ./." for every single package we want to include. On the other hand, we can mix nixpkgs with our own, so things like the following are possible

nix-shell -p valgrind "import ./. {}"

The reason I ask my question is I wonder if nix-shell should by default just make an environment with the specified packages, and a CLI analogous to nix-env. There could be some function dependenciesOf that would pull the dependencies out of a derivation, maybe exposed as a flag too, that would recover the current behavior.

There is sort of a chicken-and-egg problem: "which is more fundamental to nix, setting up environments or building packages". I don't know what the answer is, but I think nix-shell should focus on exposing the more fundamental one whatever it is.

@fkz nice! I didn't realise that was possible. Means we can do things like:

nix-shell -p "haskellPackages.ghcWithPackages (p: [p.lens p.JuicyPixels])"

Thanks :+1:

bump

I just hit a wall with nix-shell -p as well until @copumpkin told me that I could use

nix-shell -p "(import ./. {}).foo"

which was what I needed in my scenario.

Closing since nix run (the replacement for nix-shell -p) has more consistent behaviour.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

taktoa picture taktoa  路  35Comments

lukego picture lukego  路  34Comments

copumpkin picture copumpkin  路  41Comments

edolstra picture edolstra  路  65Comments

vcunat picture vcunat  路  36Comments