How to build packages in `nix develop` / `nix-shell` with zsh?

I’ve been closely following the many github issues and dicourse posts regarding the new cli and nix develop / nix-shell / nix shell etc, but I understand that for now nix develop aims to replace the two functionalities of nix-shell for debugging derivations and development shells. My question is solely about the “debugging derivations” usecase of nix develop and nix-shell; i.e. stepping through the stdenv build process manually in a close-to-pure environment. I understand that a consequence of that purity constraint is that bash is used by default, but, if I’m spending a lot of time in that environment, I may want to do it in my much more comfortable zsh instead.

However, there seems to be hard blockers preventing one from running through a nix build process in nix develop / nix-shell in zsh:

  • genericBuild / runPhase / other important stuff from $stdenv/setup isn’t available by default with --command zsh
  • as far as I can tell, $stdenv/setup is entirely incompatible with zsh (uses bashisms etc). source $stdenv/setup returns “shopt: command not found”

With this being said, the other usecases of nix-shell (development shells and gaining temporary access to binaries) obviously necessitate --command zsh working. (you don’t want a close-to-pure bash shell just for nix-shell -p hello)

So, would it be safe to say that the “debugging derivations” usecase of nix-shell / nix develop is incompatible with --command <insert shell here> ? Or is there something I’m missing that could make this work?

Thanks for any help.

Yeah, that’s safe to say. Debugging derivations requires stdenv’s shell code to actually run and work, which doesn’t happen when you run a different shell.

2 Likes

I will add, the main reason this question came up is because I was disappointed after setting up nix-any-shell (which hooks nix develop and nix-shell to use zsh/whatever) that while it works great for the development shell usecase of the two commands and for the quick binary access usecase of nix-shell, it broke the derivation debugging usecase by putting me in zsh for that too. It doesn’t seem to have an option like “only use zsh for devshells or for quick binary access”, which now that I think of it would probably be pretty difficult to implement (another consequence of having the same command do two or three very different things :melting_face:).

One way to make that distinction would be to use direnv for the development case and leave nix-shell to run bash like it normally does so you can use it to debug builds.

One way to make that distinction would be to use direnv for the development case and leave nix-shell to run bash like it normally does so you can use it to debug builds.

True, however that doesn’t fix the nix-shell -p usecase of quick access to some binaries, as I would be back to bash for that. I also really just don’t like using direnv everywhere I want to use a development shell, because while it has the best behavior (no subshell, super fast, automatic based on pwd, etc) it’s a lot of overhead and boilerplate to think about.

I’m mostly just complaining now, but yeah I wish the cli supported this better. I’m personally extremely in favor of splitting up nix develop into two cli subcommands for its two use cases, which would cleanly solve the problem by letting me stay in zsh for dev shells but not for build environment debugging. I’ll write about it in github soon. (The dev shell subcommand could then also be improved in many ways, de-necessitating things like any-nix-shell altogether.)

If you’ve enabled the new cli, which it sounds like you have, then nix shell fixes that usecase…

I personally have found the nix shell interface to be more cumbersome than nix-shell and thus tend to avoid it, but maybe that’s just a skill issue. eg. specifying nixpkgs# in front of everything, only --expr instead of -E, having to add with import <nixpkgs> {}; ... in front of more complex expressions that just work with nix-shell -p and then having to add --impure to that because is impure… it also has the problem of not giving us any way to detect whether you’re currently in a nix shell, which there is for nix-shell. but yes in a perfect / future world I will be able to ditch nix-shell [-p] entirely for the new cli instead. Just doesn’t feel there yet to me

4 Likes