Skip to content

Allow to get rid of nix develop "shell" logic #7501

@roberth

Description

@roberth

Is your feature request related to a problem? Please describe.

Remove the tight coupling with stdenv by defining a small interface

We have a number of bugs and feature requests related to nix-shell and nix develop.

"Shells" appear to be built on derivations, but they are not a derivation feature. A derivation has a builder, which is a self-contained, non-interactive process that's written for a single purpose.

Currently, to create a shell, Nix has to intrude on stdenv's domain and make assumptions about how the builder is implemented in order to modify the derivation to support some specific code it needs to run.

This creates a situation where nix develop and stdenv are tightly coupled, which holds back both components' development and does not allow alternative derivation builders to support shells.

To break this tight coupling, I propose a new interface between nix develop and the expression language. Instead of taking apart a derivation, we can ask the expression nicely to produce a command that launches a shell for us.

Concretely, this means nix develop will perform the following pseudocode

nix develop () {
  if pkg?devShell {
    nix run pkg.devShell
  } else {
    nixDevelopLegacy(pkg)
  }
}

EDIT: additionally, see below for isDevShell

By delegating the construction of a shell process to stdenv, we empower Nixpkgs to solve its own problems. This has the additional benefit that Nixpkgs allows easier collaboration, breaking changes and more risk taking in general. After all nix has a much stronger expectation of compatibility, because nix can not be pinned to projects.

Other benefits include

Out of scope for this change (but relevant)

  • Producing an accurate sandbox-like environment for debugging builds. This has traditionally been a task of nix-shell, but it just doesn't produce a sandbox environment, leading to questions, typically: "why does this work in nix-shell, but not in my build?". This should be solved by a different command that is capable of producing an actual sandbox environment. This is a significantly different task that needs its own solution. It does also need to interface with user code, but in this case it's the derivation, not the expression that should be asked. This slightly special sandbox may be differentiated by only the existence of a tty on stdin, or perhaps also a single special environment variable. It will be up to the builder process to read these clues and kick into a debugging mode; typically an interactive shell.

Describe the solution you'd like

See pseudocode above.

Similarly:

nix print-dev-env() {
  if drv.isDevShell or false {
    nix run drv -- --print-dev-env
  } else if drv?devShell {
    nix run drv.devShell -- --print-dev-env
  } else {
    nixPrintDevEnvLegacy(drv)
  }
}

Describe alternatives you've considered

Keep status quo, expend Nix team effort on shell features that the community can more easily fix themselves, and leave more important Nix issues and improvements behind.

Additional context

Solution to

Possible nixpkgs-side devShell implementation stub

Pushes nix develop toward the dev side of

Priorities

Add 👍 to issues you find important.

Metadata

Metadata

Assignees

Labels

cliThe old and/or new command line interfacefeatureFeature request or proposalidea approvedThe given proposal has been discussed and approved by the Nix team. An implementation is welcome.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions