I basically want to create my own simple version of mkShell
, so now I’m trying to understand how it would even be possible to execute some code before the shell actually pops up. I googled for a bit, and came up with this:
let pkgs = import <nixpkgs> {}; in
derivation {
name = "hello";
shellHook = ''
echo "hello world!"
'';
system = builtins.currentSystem;
builder = "${pkgs.bash}/bin/bash";
args = [ ./setup.sh ];
}
From nix-shell documentation:
If the derivation defines the variable shellHook, it will be run after $stdenv/setup has been sourced. Since this hook is not executed by regular Nix builds, it allows you to perform initialisation specific to nix-shell. For example, the derivation attribute
shellHook =
''
echo "Hello shell"
export SOME_API_TOKEN="$(cat ~/.config/some-app/api-token)"
'';
But that doesn’t output anything, although if I replace derivation {}
with pkgs.mkShell {}
, then it does. How can I make this behaviour work without actually using pkgs.mkShell
?
This can’t work. Both nix-shell
and pkgs.mkShell
are magical in all of the bad ways, in my opinion. You’ll have to check the source code how exactly they are entangled; I recommend starting with mkShell
.
Would be interesting to read what you find out. ![:slight_smile: :slight_smile:](https://discourse.nixos.org/images/emoji/twitter/slight_smile.png?v=12)
As far as I discovered, mkShell it not so big and uses mkDerivation under the hood. But I just can’t understand how mkDerivation works. Does it run some underlying native code? I just don’t know any other reason, this can’t be possible, not even the simplest similar version ![:frowning: :frowning:](https://discourse.nixos.org/images/emoji/twitter/frowning.png?v=12)
It’s not that magical. nix-shell
runs shellHook
, but it can only do so if the stdenv
infrastructure for run hooks is in place. It’s the stdenv.mkDerivation
function that establishes that. So if you use plain derivation
, nix-shell
skips the step. Replacing it with stdenv.mkDerivation
works though.
If, uh, you really want to do so, you could probably roll some sort of minimal stdenv
that creates only the interface that nix-shell
expects, and pass that in to derivation
. Relevant code starts here.
Ooh, I start getting it now, thank you very much!
1 Like