Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mkShell alternative that doesn't include stdenv, for use with direnv or impure nix develop #147060

Open
lilyball opened this issue Nov 22, 2021 · 6 comments
Labels
0.kind: enhancement Add something new 6.topic: stdenv Standard environment

Comments

@lilyball
Copy link
Member

Problem you want to solve

I want to use direnv (using nix print-dev-env) or nix develop (or nix-shell even) to give me an environment with a set of packages but I don't want to pull in anything from stdenv (unless I requested it). As it is, using mkShellNoCC on my system includes bashInteractive, coreutils, findutils, diffutils, gnused, gnugrep, gawk, gnutar, gzip, bzip2, gnumake, bash, patch, and xz, all in addition to the packages I requested.

Using a shell to reproduce the build environment of an existing package should include all this, but when I'm using mkShell it's because I want to add specific dependencies to my existing environment. A pure shell probably needs stdenv, but it just gets in the way with my impure shell.

The fundamental problem here is that mkShell/mkShellNoCC depends on stdenv, and so tools like nix print-dev-env pull in all of the stdenv packages too.

Proposed solution

Add a new library function that acts like mkShell except it produces a derivation that itself does not depend on stdenv. nix develop should only add the packages that are listed explicitly.

If possible, it should consider doing this only for "impure" shells, and still pull in stdenv for "pure" shells.

@lilyball lilyball added the 0.kind: enhancement Add something new label Nov 22, 2021
@veprbl
Copy link
Member

veprbl commented Nov 23, 2021

You still want to run the setup hooks though? Those do rely on stdenv.

@lilyball
Copy link
Member Author

I'm not certain which packages rely on them and which don't. I'm not pulling in compilers. I am doing things like autoconf, jq, etc. One project does use pkg-config and openssl, which really just needs a particular env var set, and I'm not sure if that's constructed with a setup hook or some other mechanism.

I suppose what I really care about here is just ensuring the PATH var in my shell contains only what I requested. In theory that means "save PATH before doing anything, run setup, then reset PATH and rebuild it using just the declared dependencies without stdenv". This approach also provides a convenient spot to say "don't do this last part if it's a pure shell".

@veprbl
Copy link
Member

veprbl commented Nov 23, 2021

If you can work without the shell hooks, there is already nix shell:

# env -i $(which nix) shell nixpkgs#hello -c /usr/bin/env | grep PATH
PATH=/nix/store/lj6qjfzhk25ynvyk7d6i6a2v5k9aa5gp-hello-2.10/bin

Otherwise, unsetting of unwanted paths can be done in the shellHook.

@lilyball
Copy link
Member Author

Using nix shell to provide a whole set of dependencies at once seems rather awkward. And of course if I need anything else like PKG_CONFIG_PATH then this doesn't work (presumably this var is populated via a shell hook).

I actually do have a cleanStdenv wrapper I wrote that basically uses a preHook to record the initial PATH provided by stdenv, then a shellHook that removes this from the new resulting PATH, but it feels a bit fragile and I'm unsure whether it will work if I explicitly request any of the stdenv packages. I'm also unsure if there's anything else from stdenv that I accidentally inherit from this (I haven't done a detailed inspection of all resulting env vars yet).

Having something in nixpkgs that did this officially would feel a lot more reliable. And this also feels like something that should be generally useful for others.

@legendofmiracles
Copy link
Contributor

#132617 this PR adds a shell that only relies on bash.

@lilyball
Copy link
Member Author

Interesting. That looks like it does something very similar to what I want. It does mean I can't trivially pull in openssl + pkg-config without managing PKG_CONFIG_PATH myself unfortunately, and I'd prefer to not even have bash in my path, but it still does most of what I want.

The openssl + pkg-config thing though is something that would be very helpful to be able to solve properly. I don't know if that's "do another mkShell variant that runs setup like normal and then fixes up PATH to omit stdenv packages" like what my local cleanStdenv wrapper attempts, or maybe something like a wrapper that runs a mkShell variant that records all the resulting env vars, and then pulls in the non-PATH vars into the shell and reconstructs PATH based on the selected packages. There's no immediately obvious answer here.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 19, 2022
@tomodachi94 tomodachi94 added the 6.topic: stdenv Standard environment label Nov 6, 2024
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: enhancement Add something new 6.topic: stdenv Standard environment
Projects
None yet
Development

No branches or pull requests

4 participants