volta icon indicating copy to clipboard operation
volta copied to clipboard

Installing package's man pages globally

Open TheKhanj opened this issue 11 months ago • 5 comments

I was looking for installing man pages using volta, I couldn't find anything, neither in github issues nor anywhere else. Is this feature implemented in volta? If not is there any plan for it to be implemented? It might be my fault not being able to find it, if that's the case pardon me for opening an issue for it 🙏

Here's the link to npm's implementation for it.

TheKhanj avatar Mar 13 '24 12:03 TheKhanj

Edit: converted to its own issue based on discussion below; see #1709.


Thanks for opening this, and you did not miss anything. We do not currently supply man pages! However, it would be relatively straightforward to implement using the clap_mangen crate, since we already use clap for our CLI parser. If someone wants to implement it, it should be a relatively easy first issue.

For a rough idea of how to implement it, you would want to do roughly what we do in src/command/completions.rs:

  • Add clap_mangen as a dependency for that crate.
  • Add a new man_pages module as a sibling to completions and the others.
  • Define a new clap argument with a pub(crate) struct ManPages.
  • Implement Volta’s Command trait for ManPages, including logging events the same basic way Completionts does (so you will also need to add a new ActivityKind etc.) for it.
  • Use the Man struct from clap_mangen to generate the man pages from the command (crate::cli::Volta::command()).
  • Emit the generated roff to the appropriate location. (You will have to see where that is on a per-OS basis!) One note that adds a small bit of complexity here: there is no “default” place to install it on Windows, as far as I know, but we should presumably still support it for someone who wants to read them there.

chriskrycho avatar Mar 13 '24 19:03 chriskrycho

Well I would like to work on that myself, it should be fun. But I believe you misunderstood what I was trying to say :).

The situation is I wanna install a package that has a man page using volta, let's say my own package convconv. I expect volta to install its man page to correct directory in a way that when I run man convconv the man page opens, similar to what npm does. The thing that npm does is it installs global packages in /usr/lib/node_modules directory and creates a symbolic link from /usr/share/man/man1/convconv.1 to /usr/lib/node_modules/convconv/man/convconv.1. So when man command looks for it in /usr/share/man/man1 folder it finds it. I wanted to know if volta has that feature or any plan for adding it.

That aside, having a man page for volta would be a nice thing to have as well. 👍

TheKhanj avatar Mar 13 '24 20:03 TheKhanj

Ahhhhh, I see. That is a separate very good feature request, and I should have clicked the links—I thought you were talking about npm’s implementation for itself rather than for packages. Whoops! We don’t have the feature explicitly… but you should test it? Because under the hood, volta install is using npm install, yarn install, etc., so if it works in the underlying package manager, it may (I will not say “should” here, but “may”!) work already. Perhaps you’re asking, though, because you see that it does not?

chriskrycho avatar Mar 13 '24 22:03 chriskrycho

Yeah, that didn't work for me. I should really check volta's source code to be sure I haven't missed anything though. But the way npm handles it is that it only symlinks man pages when the package is installed globally.

const binLinks = opts => {
  const { path, pkg, force, global, top } = opts
  // global top pkgs on windows get bins installed in {prefix}, and no mans
  //
  // unix global top pkgs get their bins installed in {prefix}/bin,
  // and mans in {prefix}/share/man
  //
  // non-top pkgs get their bins installed in {prefix}/node_modules/.bin,
  // and do not install mans
  //
  // non-global top pkgs don't have any bins or mans linked.  From here on
  // out, if it's top, we know that it's global, so no need to pass that
  // option further down the stack.
  if (top && !global) {
    return Promise.resolve()
  }

  return Promise.all([
    // allow clobbering within the local node_modules/.bin folder.
    // only global bins are protected in this way, or else it is
    // yet another vector for excessive dependency conflicts.
    linkBins({ path, pkg, top, force: force || !top }),
    linkMans({ path, pkg, top, force }),
  ])
}

TheKhanj avatar Mar 13 '24 22:03 TheKhanj

Intuitively, it is likely something about the way it does the final link actions—IIRC we do run npm install --global but provide it a specific installation path to treat as its global installation location—but you’d have to set up some kind of debugging in the Node-side code to confirm that. That might be a touch annoying, since you will need to make sure you have the relevant copy of Node on your system which the volta install will go through, and be sure it’s going through that one, and then patch the version in Volta’s cache to add logging or whatever. 😬

chriskrycho avatar Mar 14 '24 02:03 chriskrycho