Skip to content

Instantly share code, notes, and snippets.

@numericillustration
Created September 11, 2015 17:06
Show Gist options
  • Save numericillustration/73d9c7c7d6fa1ebe82cd to your computer and use it in GitHub Desktop.
Save numericillustration/73d9c7c7d6fa1ebe82cd to your computer and use it in GitHub Desktop.
npm module man pages and pkgsrc man pages have path issues
pkgsrc man pages get installed to /opt/pkg/man/ such as the one for the nmap package I just installed via
sudo pkgin install nmap
/opt/pkg/man/man1/nmap.1
The manpage for node itself in in the same path
/opt/pkg/man/man1/node.1
I have also installed some npm packages for working with Joyent stuff such as the manta tools. I am installing them globally as the
npm docs say "If you want to use it as a command line tool, something like the grunt CLI, then you can want (sic) to install it globally.”
src: https://docs.npmjs.com/getting-started/installing-npm-packages-globally
per the npm docs here
https://docs.npmjs.com/files/folders#man-pages
Man Pages
When in global mode, man pages are linked into {prefix}/share/man.
When in local mode, man pages are not installed.
Man pages are not installed on Windows systems.
thus with invoking
sudo npm install -g manta
npm module man pages end up linked in to /opt/pkg/share/man/ from the /opt/pkg/lib/node_modules/<modulename>/man dirs. e.g. npm links the manta man pages thusly:
♧ ls -al /opt/pkg/share/man/man1/
total 120
drwxr-xr-x 17 root wheel 578 Sep 11 00:09 .
drwxr-xr-x 3 root wheel 102 Sep 11 00:09 ..
lrwxr-xr-x 1 root wheel 50 Sep 11 00:09 mchattr.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mchattr.1
lrwxr-xr-x 1 root wheel 49 Sep 11 00:09 mchmod.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mchmod.1
lrwxr-xr-x 1 root wheel 48 Sep 11 00:09 mfind.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mfind.1
lrwxr-xr-x 1 root wheel 47 Sep 11 00:09 mget.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mget.1
lrwxr-xr-x 1 root wheel 48 Sep 11 00:09 minfo.1 -> /opt/pkg/lib/node_modules/manta/man/man1/minfo.1
lrwxr-xr-x 1 root wheel 47 Sep 11 00:09 mjob.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mjob.1
lrwxr-xr-x 1 root wheel 46 Sep 11 00:09 mln.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mln.1
lrwxr-xr-x 1 root wheel 49 Sep 11 00:09 mlogin.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mlogin.1
lrwxr-xr-x 1 root wheel 46 Sep 11 00:09 mls.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mls.1
lrwxr-xr-x 1 root wheel 49 Sep 11 00:09 mmkdir.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mmkdir.1
lrwxr-xr-x 1 root wheel 47 Sep 11 00:09 mput.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mput.1
lrwxr-xr-x 1 root wheel 46 Sep 11 00:09 mrm.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mrm.1
lrwxr-xr-x 1 root wheel 49 Sep 11 00:09 mrmdir.1 -> /opt/pkg/lib/node_modules/manta/man/man1/mrmdir.1
lrwxr-xr-x 1 root wheel 48 Sep 11 00:09 msign.1 -> /opt/pkg/lib/node_modules/manta/man/man1/msign.1
lrwxr-xr-x 1 root wheel 49 Sep 11 00:09 muntar.1 -> /opt/pkg/lib/node_modules/manta/man/man1/muntar.1
So I have /opt/pkg/bin and /opt/pkg/sbin in my path so I'm counting on the fact that if I man something in those paths that has manpages installed "nearby", it should work. Unfortunately it doesn't. This seemed to fly in the face of what man man says here:
If you don't specify an explicit path list with -M or MANPATH, man develops its own path list
based on the contents of the configuration file /private/etc/man.conf. The MANPATH statements in
the configuration file identify particular directories to include in the search path.
Furthermore, the MANPATH_MAP statements add to the search path depending on your command search
path (i.e. your PATH environment variable). For each directory that may be in the command search
path, a MANPATH_MAP statement specifies a directory that should be added to the search path for
manual page files. man looks at the PATH variable and adds the corresponding directories to the
manual page file search path. Thus, with the proper use of MANPATH_MAP, when you issue the com-
mand man xyz, you get a manual page for the program that would run if you issued the command xyz.
In addition, for each directory in the command search path (we'll call it a "command directory")
for which you do not have a MANPATH_MAP statement, man automatically looks for a manual page
directory "nearby" namely as a subdirectory in the command directory itself or in the parent
directory of the command directory.
Additionally in the /private/etc/man.conf file this comment seems to concur:
# If people ask for "man foo" and have "/dir/bin/foo" in their PATH
# and the docs are found in "/dir/man", then no mapping is required.
Running man with debug output turned on hints at the problem.
It will add /opt/pkg/share/man to the manpath and move on with life never looking in /opt/pkg/man
...
path directory /opt/pkg/bin is not in the config file
but there is a man directory nearby
adding /opt/pkg/share/man to manpath
path directory /opt/pkg/sbin is not in the config file
but there is a man directory nearby
...
full output was:
Reading config file /private/etc/man.conf
Looked whether there exists a message catalog man, but there is none
(and for English messages none is needed)
found man directory /usr/share/man
found man directory /usr/local/share/man
found man directory /usr/X11/man
found manpath map /bin --> /usr/share/man
found manpath map /sbin --> /usr/share/man
found manpath map /usr/bin --> /usr/share/man
found manpath map /usr/sbin --> /usr/share/man
found manpath map /usr/local/bin --> /usr/local/share/man
found manpath map /usr/local/sbin --> /usr/local/share/man
found manpath map /usr/X11/bin --> /usr/X11/man
found manpath map /usr/bin/X11 --> /usr/X11/man
found manpath map /usr/bin/mh --> /usr/share/man
using less --ignore-case --line-numbers --hilite-unread --squeeze-blank-lines --LONG-PROMPT --tabs=3 as pager
using /usr/bin/less -is as browser
using /bin/cat to dump HTML pages as text
path directory /usr/local/bin is in the config file
path directory /usr/bin is in the config file
adding /usr/share/man to manpath
path directory /bin is in the config file
path directory /usr/sbin is in the config file
path directory /sbin is in the config file
path directory /Users/mhicks/bin is not in the config file
and we found no man directory nearby
path directory /bin is in the config file
path directory /sbin is in the config file
path directory /usr/local/bin is in the config file
path directory /opt/pkg/bin is not in the config file
but there is a man directory nearby
adding /opt/pkg/share/man to manpath
path directory /opt/pkg/sbin is not in the config file
but there is a man directory nearby
path directory /usr/bin is in the config file
path directory /usr/sbin is in the config file
path directory /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin is not in the config file
but there is a man directory nearby
adding /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/man to manpath
adding mandatory man directories
adding /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/share/man to manpath
adding /Applications/Xcode.app/Contents/Developer/usr/share/man to manpath
adding /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man to manpath
No manual entry for nmap
So I looked into the code since Apple has OS darwin code browsable.
http://www.opensource.apple.com/source/man/man-16/man/src/manpath.c
/*
* For each directory in the user's path, see if it is one of the
* directories listed in the man.conf file. If so, and it is
* not already in the manpath, add it. If the directory is not listed
* in the man.conf file, see if there is a subdirectory `man' or
* `MAN'. If so, and it is not already in the manpath, add it.
*
* Example: user has <dir>/bin in his path and the directory
* <dir>/bin/man exists -- the directory <dir>/bin/man will be added
* to the manpath.
* Try also <dir>/man ?and <dir>?, and, if LANG is set, <dir>/$LANG/man.
* aeb - 940320
*/
But there is a codeblock inserted by this patch
http://www.opensource.apple.com/source/man/man-16/patches/src__manpath.c.diff
#if defined(__APPLE__)
/* Try to use share/man (3545105). */
strcpy (t + len, "/share/man");
if (is_directory (t) == 1)
return t;
#endif
that causes the path searching to check if <path minus bin or sbin>/share/man is a directory which comes before the check for <path minus bin or sbin>/man that gets executed first and so <path minus bin or sbin>/man never gets added to the man path.
A passable workaround is to uncomment a line in /private/etc/man.conf for “MANPATH /opt/*/man”
which will cause /opt/pkg/man to be in the manpath from the config and find /opt/pkg/share/man by $PATH discovery.
This will probably have to be repeated on any system upgrade that comes with a new man.conf
I'm not sure if this is something that can be worked out between pkgsrc and npm but its definitely a source of minor conflict on OSX.
Perhaps an option is to set the pkgsrc npm global install default base location to something other than /opt/pkg and use another place for NPM packages so that the npm man path doesn't clobber pkgsrc man paths since its npm modules in global installing man pages to /opt/pkg/share/man which prempts man's ability to find the man pages in /opt/pkg/man/
https://docs.npmjs.com/getting-started/fixing-npm-permissions
As a side note, the man pages for npm itself are not installed (linked in) to /opt/pkg/share/man or /opt/pkg/man but are on my system in /opt/pkg/lib/node_modules/npm/man
but the npm package manifest in /opt/pkg/lib/node_modules/npm/package.json seems to be correct. I'm guessing that npm isnt installed as an npm package but rather comes with pksrc node directly and thus its paths are controlled via pkgsrc and something is misconfigured in the node package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment