Best way to augment a nix-shell for dev utilities?

Given a Nixified project, what’s the best way to create an augmented environment for specific dev tasks? I have some docs I want to generate and send with rsync. I don’t want to clutter the default.nix or shell.nix with a usually-unnecessary dependency on rsync, so I think I’d like to somehow create a nix-shell that includes both the package’s regular env, plus rsync. Ideally I could do this by passing args to nix-shell when using it as a script interpreter.

I suppose the question is, how do I create a dummy derivation that includes my package’s env as a buildInput, alongside other packages? With that, I could use the mechanism listed at the bottom of the section on Using nix-shell as a #! interpreter to get what I want.

Would it be enough to pass -p to your nix-shell invocation?

I’ll double check, but I doubt it, since -p is incompatible with specifying a file to evaluate. I.e., I think -p rsync will cause shell.nix to be ignored. I’ll update this if I’m wrong.

If that’s the case, it’s not well documented at all. man nix-shell doesn’t at all suggest that -p overrides a shell.nix

I double checked, and -p does, in fact, ignore shell.nix.

The man page does suggest this, somewhat abstractly. The synopsis says

nix-shell ... {[--packages | -p]packages | [path]}

which shows you can either specify packages, or specify a path to a nix file. It just happens that specifying a path is the default, with shell.nix and default.nix the defaults to the default.

1 Like

mkShell is like stdenv.mkDerivationto dedicated for shell.nix. It adds one more feature where multiple package build inputs can all be merged together. This is useful when developing in a repo that has multiple packages (micro-services).

shell.nix:

let pkgs = import <nixpkgs> {};
pkgs.mkShell {
  # this adds all the build inputs of your project package
  inputsFrom = [ (import ./default.nix { inherit pkgs; };) ];
  # now add your other dependencies
  buildInputs = with pkgs; [ rsync ];
}
5 Likes