Hi everyone!
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 -I
:
#! nix-shell -I "nixpkgs=\"with builtins; (dirOf interpretedFile) + ../nixpkgs/\"" -i python -p "python.withPackages (pkgs: [ pkgs.foo ])"
If 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 ])"