Combining personal and project-provided `shell.nix`

I’m wondering a little about best practices for combining with both in-project-tree and personal shell.nix files.

Let’s assume I have a project which includes a shell.nix committed to the repository, which is already distinct from the default.nix and provides an appropriate build environment for all developers.

In addition to this, when working on this project, I want to include my personal tooling preferences (e.g. ide/editor integrations) when I work on the project. Obviously this belongs out-of-tree, as I don’t want to impose my preferences on my fellow developers.

What is the usual idiom for including both? One option would be to enter nested shells, although that can be awkward (although direnv can help), and it makes it difficult for my personal preference tooling to e.g. depend on the specific compiler version.

For personal projects I’ve started including the following in the buildInputs shell.nix, so that I can include general preferences for a range of projects in the parent directory, whilst still ending up with versions appropriate to the project I’m working on (i.e. correct nixpkgs pin).

(if pkgs.lib.pathExists ../shell.nix
        then (pkgs.callPackage ../shell.nix {}).buildInputs
        else []);

Are there any particular downsides/any particular fragility to this (e.g. spurious rebuilds - I understand that this behaves differently if entered from a symlink, for example, but that could be thought of as a feature)

5 Likes