Skip to content

Flakes UX: make it easy to evaluate an arbitrary expression in a context of a flake #5567

Description

@balsoft

This is a design discussion issue, so feel free to give as much feedback and criticism as you like.

Preamble

In ye olde days of nix-shell, it was possible to easily evaluate expressions in the context of nixpkgs. Something like this:

nix-shell -p 'python3.withPackages (ps: with ps; [ numpy scipy ])'

Drops you into a shell in which there's a python3 executable with numpy and scipy available. This is really useful for ad-hoc scripting. You could also do something like

nix-shell -p 'hello.overrideAttrs (_: { src = ./.; })'

It was also possible to add alias p='nix-shell -p' to save some typing.

The flexibility is endless -- and all just a few keystrokes away!

Current situation

It is possible to do something similar with new, flaky interface:

nix shell --impure --expr 'with builtins.getFlake "nixpkgs"; with legacyPackages.${builtins.currentPlatform}; python3.withPackages (ps: with ps; [ numpy scipy ])'

However, this is a chore to do, and I'd much rather just run pip install numpy scipy and deal with all the usual stateful package management issues than type this monstrosity every time I need to try a python package.

Proposal

Add a way to easily evaluate expressions "in the context of" a flake, meaning with the top-level attributes and {packages,legacyPackages}.${currentPlatform} of that flake available in scope.

Possible implementations

I came up with three different ideas, all of which have some advantages and drawbacks.

(my current favourite) Allow flake fragments to be arbitrary expressions

Example: nix shell 'nixpkgs#(python3.withPackages (ps: with ps; [ numpy scipy ]))'

This feels like a natural extension of the already-existing flake-fragment-as-attrpath interpretation. It shouldn't be too difficult to implement, and doesn't break compatibility. It does however introduce some potential complexity to newcomers.

With alias p='nix shell' it is possible to do p 'nixpkgs#python3.withPackages (...)' , and some more keystrokes could be saved with a registry entry n -> nixpkgs: p 'n#python3.withPackages (...)'

Add a new flag, like --with

Example: nix shell --with nixpkgs 'python3.withPackages (ps: with ps; [ numpy scipy ])'

This plays nicely with Nix' with keyword. It implies that some expression will be evaluated with some additional context.

Aliasing p='nix shell --with nixpkgs' can give experience identical to the status quo -- p 'python3.withPackages (...)'

Change the behaviour of --expr

Example: nix shell --expr nixpkgs 'python3.withPackages (ps: with ps; [ numpy scipy ])'

This breaks compatibility, but may be nicer than --with since --expr was not very usable with flakes anyways and it's not nice to have a lot of useless flags around.

Metadata

Metadata

Assignees

Labels

UXThe way in which users interact with Nix. Higher level than UI.flakes

Fields

No fields configured for issues without a type.

Projects

Status
Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions