Where can I learn about how nix develop / nix shell work? For instance, how does the nix CLI know what environment variables to set, which hooks to run and which packages to provide?
I know that the mkshell package has a bash script inside its output when built, but that file specifically says that it shouldn’t be relied on.
nix-shell and its 2.0 successors put you “in” the (bash) environment that the derivation’s builder would receive, and it executes a specfic additional command. mkShell just creates a derivation whose entire purpose it is to feed the correct things into the build environment to create the shell you design with it, instead of a real derivation. That’s why it’s “special” - it’s kind of a hack that abuses nix’ native feature to create “build” shells to make something that isn’t a build shell at all.
Come to Nixcon and find out! (assuming my talk is accepted :))
In brief though, have a look at nix/src/nix/get-env.sh at d967870cc6036660629db67852e225bbbef34aef · NixOS/nix · GitHub. nix develop replaces a derivation’s arguments to bash with that script, which outputs a JSON object of the stdenv environment with all its vars and functions, and then writes an RC script from it and runs that to enter the dev shell.
That’s really cool! So this is the script which extracts the environment, and there’s another script somewhere which it uses to setup the shell? I’m interested in emulating the steps that nix shell does, but doing it without the nix cli.
Sadly I won’t be at nixcon but the talk sounds really fun!
Also have a look at https://github.com/NixOS/nixpkgs/pull/509697, which re-implements all of the nix develop logic directly in stdenv. Once this gets in, there will be no need for nix develop to do anything really.