Coming from which
A which alternative with a drop-in path: import which from bellpull/node-which, graded 5 / 5 by node-which's own test suite — then zero dependencies, and a resolver that returns the PATH entry the binary came from.
bellpull is a which alternative — for npm's which package, node-which — that you
adopt by changing one import. bellpull/node-which is node-which 7's API, and node-which's
own test suite is the grade.
Migrate from which in one import
- import which from 'which';
+ import which from 'bellpull/node-which';Everything else stays: which(cmd, options?) returns a promise, which.sync(cmd, options?)
returns the answer, and the options are node-which's — all, nothrow, path, pathExt,
delimiter. A miss throws node-which's error, not found: <cmd> with code: 'ENOENT', or
returns null under nothrow. So do its search rules: a command with a slash is checked as
given, Windows searches the working directory first and tries PATHEXT's extensions, and a
quoted PATH part is unquoted.
Two things are not carried. node-which's which command-line binary is not shipped — this is
the library. And which() runs the same search as which.sync() and hands it back as a
promise, rather than walking the filesystem asynchronously.
Mind the neighbouring subpath: bellpull/which is not the drop-in. It is bellpull's own
resolver, with a different shape — see below.
Is bellpull compatible with which?
Graded, not claimed. node-which's own suite, vendored at 7.0.0 and unmodified apart from the
import specifier, runs against bellpull/node-which beside a control that runs it against
real node-which:
| passing | rate | |
|---|---|---|
bellpull/node-which | 5 / 5 | 100.0% |
| which itself (control) | 5 / 5 | 100.0% |
From Compatibility, which npm run compat:page generates from the
oracle's last run; that page is the authority, and its front-end column reads bellpull
because the row's import is composed onto the package root as bellpull/node-which. Five is
the suite's count of top-level tests; each runs its assertions under both posix and win32
and through both which() and which.sync(). The suite's test/bin.js, which spawns
node-which's CLI, is not graded, because the CLI is not shipped.
What you gain over which
- Zero dependencies. which 7.0.0 depends on
isexe. - The PATH entry that answered.
bellpull/whichreturns where the binary is and whichPATHentry found it — the fact every "twonodes on this machine" investigation starts by reconstructing withecho $PATH. - An empty
PATHentry is not the current directory. POSIX reads/usr/bin:as including.; bellpull's resolver skips empty and relative entries, andsearchPath()lists each one with the reason. The drop-in keeps node-which's behaviour here, so this is a reason to move to the resolver. - The answer is always absolute, and the resolver reads no global: the environment is an
argument, so a test hands it a
PATHrather than mutatingprocess.env.
import { whichSync, whichAllSync } from 'bellpull/which';
const runtime = { platform: process.platform, env: process.env, cwd: process.cwd() };
whichSync('node', { runtime });
// { path: '/opt/homebrew/bin/node', from: '/opt/homebrew/bin', ext: '' }
whichAllSync('node', { runtime }); // every match, best firstWhen to switch from which
- You want node-which's answers without its dependency.
- A build differs between two machines and you need to know which binary each one found.
The resolver, the run() it feeds and the resolvers plugin host are on bellpull.
Coming from cross-spawn
A cross-spawn alternative with a drop-in path: import spawn from bellpull/cross-spawn, graded 68 / 68 by cross-spawn's own test suite — then zero dependencies, and a run() whose result says which binary ran and treats a non-zero exit as a value.
Which binary ran?
Diagnose a build that differs between machines: list every install of a tool on PATH, best first, and report which one a run actually used.