At work, we have a huge monorepo and a frozen version of
nixpkgs to build services and libraries. There’s a release.nix file containing all our packages and it’s very nice to know that if it can
nix-build , then all the services compile and pass unit tests.
I’ve been trying to make our helper scripts reproducible by using
nix-shell as a script interpreter. Unfortunately, there seems to be no way of pointing them to our frozen
nixpkgs in a nice way. Given the following folder structure:
- nix - nixpkgs - default.nix # frozen nixpkgs - bin - helper-script.py
I can write a
helper-script.py that looks like this:
#!/usr/bin/env nix-shell #! nix-shell -I "nixpkgs=." -i python -p "python.withPackages (pkgs: [ pkgs.foo ])" import foo foo.blah()
…but it will only work if invoked from the
nix directory as
./bin/helper-script.py . It would be really awesome if it was possible to specify pinned nixpkgs relative to the interpreted file if using
nix-shell as an interpreter. In this way, no matter how we run that script, it would always resolve
nixpkgs to what we have pinned right now.
I looked at the source code of nix-build (nix/nix-build.cc at master · NixOS/nix · GitHub), and there seems no way to make it work now. Do you think adding a feature like that would be useful? How would it look?
…one idea I had is to introduce a new builtin -
interpretedFile , that is only available when running
nix-shell as interpreter. Since the value of
<nixpkgs> is normally a path I want to import, I was wondering if I could make this work by putting a Nix expression in the
#! nix-shell -I "nixpkgs=\"with builtins; (dirOf interpretedFile) + ../nixpkgs/\"" -i python -p "python.withPackages (pkgs: [ pkgs.foo ])"
dirOf interpretedFile was aliased to something smaller, say
<.>, we would be able to write:
#! nix-shell -I "nixpkgs=<.>/../nixpkgs" -i python -p "python.withPackages (pkgs: [ pkgs.foo ])"