snix/users/wpcarro/website/blog/posts/nix-shell-note.md
William Carroll ba22b09f71 feat(wpcarro/blog): nix-shell (note to self)
Publishing another "note to self"

Change-Id: If5d052f0360f3e1f371b0c1fdd3781e5bb846ea4
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6861
Tested-by: BuildkiteCI
Reviewed-by: wpcarro <wpcarro@gmail.com>
2022-10-07 18:15:54 +00:00

1.6 KiB

Background

I rarely use nix-shell for its originally intended purpose of "reproducing the environment of a derivation for development". Instead, I often use it to put some executable on my PATH for some ad hoc task.

What's nix-shell's "intended purpose"? Let's ask The Man (man nix-shell):

The command nix-shell will build the dependencies of the specified derivation, but not the derivation itself. It will then start an interactive shell in which all environment variables defined by the derivation path have been set to their corresponding values, and the script $stdenv/setup has been sourced. This is useful for reproducing the environment of a derivation for development.

Because I'm abusing nix-shell in this way, I'm liable to forget that nix-shell puts buildInputs on PATH and not the derivation itself. But I often only want the derivation!

Solution

Pass the Nix expression to nix-shell -p:

λ nix-shell -p '(import /depot {}).tvix.eval'

Explanation

This works because Nix forwards the arguments passed to -p (i.e. --packages) and interpolates them into this expression here: source

{ ... }@args:

with import <nixpkgs> args;

(pkgs.runCommandCC or pkgs.runCommand) "shell" {
  buildInputs = [
    # --packages go here
  ];
}

So really you can pass-in any valid Nix expression that produces a derivation and nix-shell will put their outputs on your PATH.

Enjoy!