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

nix-shell: set MANPATH when --packages is used #4642

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sternenseemann
Copy link
Member

Setting MANPATH allows man viewers to reliably find man pages which are
contained in the store paths of the packages passed to nix-shell -p.
Running nix-shell -p package --run "man package" is something that
one generally would assume should work which this change allows for.

Currently nix-shell -p package --run "man somepage" only works
occasionally and only due to a behavior of GNU's man-db that is not
documented: It tries to guess the man directory corresponding to every
entry in PATH which only works if the packages added to nix-shell have a
bin directory that gets added to PATH and is not supported by other
man page viewers like mandoc.

The simplest way to achieve this is setting MANPATH in the derivation
and utilizing lib.makeSearchPath and lib.getOutput to construct the
actual MANPATH. For outputs, we consider the man and devman outputs
and fall back to out if they are missing (the current code results in
a duplicate entries for many packages in MANPATH for the sake of
simplicity).


I'm also interested in implementing this for nix shell, however since Installables are always just the default output (i. e. drv."${drv.outputName}") this is trickier since we'd also need the man or even devman output to implement this correctly.

Setting MANPATH allows man viewers to reliably find man pages which are
contained in the store paths of the packages passed to nix-shell -p.
Running nix-shell -p package --run "man package" is something that
one generally would assume should work which this change allows for.

Currently nix-shell -p package --run "man somepage" only works
occasionally and only due to a behavior of GNU's man-db that is not
documented: It tries to guess the man directory corresponding to every
entry in PATH which only works if the packages added to nix-shell have a
`bin` directory that gets added to PATH and is not supported by other
man page viewers like mandoc.

The simplest way to achieve this is setting MANPATH in the derivation
and utilizing lib.makeSearchPath and lib.getOutput to construct the
actual MANPATH. For outputs, we consider the `man` and `devman` outputs
and fall back to `out` if they are missing (the current code results in
a duplicate entries for many packages in MANPATH for the sake of
simplicity).
Fixes syntax error introduced in 54ced90.
@sternenseemann sternenseemann marked this pull request as draft March 16, 2021 11:31
@roberth
Copy link
Member

roberth commented Mar 30, 2021

I'd prefer to change this from runCommand to mkShell and implement it there, in Nixpkgs. That way, you can have the same behavior in shell.nix-based shells. It also decreases maintenance pressure on the nix project.

@sternenseemann
Copy link
Member Author

Sounds like a good idea. I've drafted this for now anyways since it probably makes little sense to add this to nix-shell if we don't have it for nix shell (or at least I am inferring that given that new features from nix-command are rarely added to the stable commands, so I'd suspect nobody has interest in feature just for the stable commands).

However with how Installables currently work it is hard to implement this since the man and devman outputs are filtered out pretty early.

I'll see when I have time to have a look at mkShell in nixpkgs.

@edolstra
Copy link
Member

Running nix-shell -p package --run "man package" is something that
one generally would assume should work which this change allows for.

Not sure I agree with that. If we pull in documentation outputs (which could be large) by default, it negates the advantage of separate outputs. Also, I feel nix-shell should provide what the user asked for, and nothing more. So the user should do nix-shell -p foo.man. Unfortunately, that doesn't initialize MANPATH properly at the moment, but that can probably be addressed via a setup hook in stdenv.

@sternenseemann
Copy link
Member Author

Not sure I agree with that. If we pull in documentation outputs (which could be large) by default, it negates the advantage of separate outputs.

This is a fair point, but I find it a bit difficult to judge the impact of this. I've briefly checked all top-level attributes of nixpkgs which have either a man or devman output (of which there are only 335 in total). Only 29 of those are bigger than 1MB extracted and all of them are smaller than 20MB extracted.

On the other hand the intention of the man output is to split out man pages if their size is significant so they don't need to be downloaded unnecessarily. For setting the MANPATH we have the choice of either accepting a not insignificant number of edge cases where the man pages wouldn't be available with nix-shell -p package or downloading extra store paths in a lot of cases.

Also, I feel nix-shell should provide what the user asked for, and nothing more. So the user should do nix-shell -p foo.man. Unfortunately, that doesn't initialize MANPATH properly at the moment, but that can probably be addressed via a setup hook in stdenv.

I am generally inclined to agree and a setup hook would be useful for the current nix-shell, but I don't think this works with the direction the nix-command CLI has taken. nix shell doesn't run any setup hooks as far as I am aware and the environment setup consists of setting up PATH completely independently from any nix expression or stdenv.

As a side note, I'd say nix-shell already violates the user's wishes in a way: Any nix-shell always already contains stdenv including a C compiler, make etc. even if the user specifies --pure.

A solution I could imagine which would work for nix-shell and would also be possible to implement for nix shell is to only set MANPATH to include man pages that are in out/bin. This would of course mean that users have to explicitly request the man output if they want man pages which I could imagine is surprising, but also avoid downloading 16MB for nix-shell -p openssl. What do you think about that?

@sternenseemann
Copy link
Member Author

To follow up on this: I've implemented the equivalent feature for the nix-command interface in #4702 with the main upshot being that we don't rely on man-db specific, undocumented behavior anymore. This was done in a way that doesn't download any extra store paths unless explicitly requested (this is borderline impossible with the Installables interface anyways).

As for nix-shell I'm still a bit unsure if a setup hook in nixpkgs is really the way to go: We don't need MANPATH in build systems, so why should bother to set it at all. Doing this as a hack just for nix-shell seems a little extreme.

@stale
Copy link

stale bot commented Oct 11, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Oct 11, 2021
@fricklerhandwerk fricklerhandwerk added the UX The way in which users interact with Nix. Higher level than UI. label Sep 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale UX The way in which users interact with Nix. Higher level than UI.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants