libnpmexec 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -2
- package/README.md +2 -2
- package/lib/cache-install-dir.js +1 -1
- package/lib/file-exists.js +29 -0
- package/lib/index.js +11 -12
- package/lib/is-windows.js +1 -0
- package/lib/run-script.js +3 -3
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## v1.1.0
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- Add add walk up dir lookup logic to satisfy local bins,
|
|
6
|
+
similar to `@npmcli/run-script`
|
|
7
|
+
|
|
8
|
+
## v1.0.1
|
|
9
|
+
|
|
10
|
+
- Fix `scriptShell` option name.
|
|
11
|
+
|
|
12
|
+
## v1.0.0
|
|
13
|
+
|
|
14
|
+
- Initial implementation, moves the code that used to live in the **npm cli**,
|
|
15
|
+
ref: https://github.com/npm/cli/blob/release/v7.10.0/lib/exec.js into this
|
|
16
|
+
separate module, providing a programmatic API to the **npm exec** functionality.
|
|
6
17
|
|
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ await libexec({
|
|
|
31
31
|
- `call`: An alternative command to run when using `packages` option **String**, defaults to empty string.
|
|
32
32
|
- `cache`: The path location to where the npm cache folder is placed **String**
|
|
33
33
|
- `color`: Output should use color? **Boolean**, defaults to `false`
|
|
34
|
-
- `localBin`: Location to the `node_modules/.bin` folder of the local project **String**, defaults to
|
|
34
|
+
- `localBin`: Location to the `node_modules/.bin` folder of the local project to start scanning for bin files **String**, defaults to `./node_modules/.bin`. **libexec** will walk up the directory structure looking for `node_modules/.bin` folders in parent folders that might satisfy the current `arg` and will use that bin if found.
|
|
35
35
|
- `locationMsg`: Overrides "at location" message when entering interactive mode **String**
|
|
36
36
|
- `log`: Sets an optional logger **Object**, defaults to `proc-log` module usage.
|
|
37
37
|
- `globalBin`: Location to the global space bin folder, same as: `$(npm bin -g)` **String**, defaults to empty string.
|
|
@@ -39,7 +39,7 @@ await libexec({
|
|
|
39
39
|
- `packages`: A list of packages to be used (possibly fetch from the registry) **Array<String>**, defaults to `[]`
|
|
40
40
|
- `path`: Location to where to read local project info (`package.json`) **String**, defaults to `.`
|
|
41
41
|
- `runPath`: Location to where to execute the script **String**, defaults to `.`
|
|
42
|
-
- `
|
|
42
|
+
- `scriptShell`: Default shell to be used **String**, defaults to `sh` on POSIX systems, `process.env.ComSpec` OR `cmd` on Windows
|
|
43
43
|
- `yes`: Should skip download confirmation prompt when fetching missing packages from the registry? **Boolean**
|
|
44
44
|
- `registry`, `cache`, and more options that are forwarded to [@npmcli/arborist](https://github.com/npm/arborist/) and [pacote](https://github.com/npm/pacote/#options) **Object**
|
|
45
45
|
|
package/lib/cache-install-dir.js
CHANGED
|
@@ -12,7 +12,7 @@ const cacheInstallDir = ({ cache, packages }) => {
|
|
|
12
12
|
|
|
13
13
|
const getHash = (packages) =>
|
|
14
14
|
crypto.createHash('sha512')
|
|
15
|
-
.update(packages.sort((a, b) => a.localeCompare(b)).join('\n'))
|
|
15
|
+
.update(packages.sort((a, b) => a.localeCompare(b, 'en')).join('\n'))
|
|
16
16
|
.digest('hex')
|
|
17
17
|
.slice(0, 16)
|
|
18
18
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const { resolve } = require('path')
|
|
2
|
+
const { promisify } = require('util')
|
|
3
|
+
const stat = promisify(require('fs').stat)
|
|
4
|
+
const walkUp = require('walk-up-path')
|
|
5
|
+
|
|
6
|
+
const fileExists = (file) => stat(file)
|
|
7
|
+
.then((stat) => stat.isFile())
|
|
8
|
+
.catch(() => false)
|
|
9
|
+
|
|
10
|
+
const localFileExists = async (dir, binName, root = '/') => {
|
|
11
|
+
root = resolve(root).toLowerCase()
|
|
12
|
+
|
|
13
|
+
for (const path of walkUp(resolve(dir))) {
|
|
14
|
+
const binDir = resolve(path, 'node_modules', '.bin')
|
|
15
|
+
|
|
16
|
+
if (await fileExists(resolve(binDir, binName)))
|
|
17
|
+
return binDir
|
|
18
|
+
|
|
19
|
+
if (path.toLowerCase() === root)
|
|
20
|
+
return false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
fileExists,
|
|
28
|
+
localFileExists,
|
|
29
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const { delimiter, resolve } = require('path')
|
|
1
|
+
const { delimiter, dirname, resolve } = require('path')
|
|
2
2
|
const { promisify } = require('util')
|
|
3
3
|
const read = promisify(require('read'))
|
|
4
|
-
const stat = promisify(require('fs').stat)
|
|
5
4
|
|
|
6
5
|
const Arborist = require('@npmcli/arborist')
|
|
7
6
|
const ciDetect = require('@npmcli/ci-detect')
|
|
@@ -12,14 +11,12 @@ const pacote = require('pacote')
|
|
|
12
11
|
const readPackageJson = require('read-package-json-fast')
|
|
13
12
|
|
|
14
13
|
const cacheInstallDir = require('./cache-install-dir.js')
|
|
14
|
+
const { fileExists, localFileExists } = require('./file-exists.js')
|
|
15
15
|
const getBinFromManifest = require('./get-bin-from-manifest.js')
|
|
16
16
|
const manifestMissing = require('./manifest-missing.js')
|
|
17
17
|
const noTTY = require('./no-tty.js')
|
|
18
18
|
const runScript = require('./run-script.js')
|
|
19
|
-
|
|
20
|
-
const fileExists = (file) => stat(file)
|
|
21
|
-
.then((stat) => stat.isFile())
|
|
22
|
-
.catch(() => false)
|
|
19
|
+
const isWindows = require('./is-windows.js')
|
|
23
20
|
|
|
24
21
|
/* istanbul ignore next */
|
|
25
22
|
const PATH = (
|
|
@@ -31,14 +28,14 @@ const exec = async (opts) => {
|
|
|
31
28
|
args = [],
|
|
32
29
|
call = '',
|
|
33
30
|
color = false,
|
|
34
|
-
localBin = '',
|
|
31
|
+
localBin = resolve('./node_modules/.bin'),
|
|
35
32
|
locationMsg = undefined,
|
|
36
33
|
globalBin = '',
|
|
37
34
|
output,
|
|
38
35
|
packages: _packages = [],
|
|
39
36
|
path = '.',
|
|
40
37
|
runPath = '.',
|
|
41
|
-
|
|
38
|
+
scriptShell = isWindows ? process.env.ComSpec || 'cmd' : 'sh',
|
|
42
39
|
yes = undefined,
|
|
43
40
|
...flatOptions
|
|
44
41
|
} = opts
|
|
@@ -58,7 +55,7 @@ const exec = async (opts) => {
|
|
|
58
55
|
path,
|
|
59
56
|
pathArr,
|
|
60
57
|
runPath,
|
|
61
|
-
|
|
58
|
+
scriptShell,
|
|
62
59
|
})
|
|
63
60
|
|
|
64
61
|
// nothing to maybe install, skip the arborist dance
|
|
@@ -72,8 +69,10 @@ const exec = async (opts) => {
|
|
|
72
69
|
// the behavior of treating the single argument as a package name
|
|
73
70
|
if (needPackageCommandSwap) {
|
|
74
71
|
let binExists = false
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
const dir = dirname(dirname(localBin))
|
|
73
|
+
const localBinPath = await localFileExists(dir, args[0])
|
|
74
|
+
if (localBinPath) {
|
|
75
|
+
pathArr.unshift(localBinPath)
|
|
77
76
|
binExists = true
|
|
78
77
|
} else if (await fileExists(`${globalBin}/${args[0]}`)) {
|
|
79
78
|
pathArr.unshift(globalBin)
|
|
@@ -145,7 +144,7 @@ const exec = async (opts) => {
|
|
|
145
144
|
},
|
|
146
145
|
}))
|
|
147
146
|
.map(mani => mani._from)
|
|
148
|
-
.sort((a, b) => a.localeCompare(b))
|
|
147
|
+
.sort((a, b) => a.localeCompare(b, 'en'))
|
|
149
148
|
|
|
150
149
|
// no need to install if already present
|
|
151
150
|
if (add.length) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = process.platform === 'win32'
|
package/lib/run-script.js
CHANGED
|
@@ -23,10 +23,10 @@ const run = async ({
|
|
|
23
23
|
path,
|
|
24
24
|
pathArr,
|
|
25
25
|
runPath,
|
|
26
|
-
|
|
26
|
+
scriptShell,
|
|
27
27
|
}) => {
|
|
28
28
|
// turn list of args into command string
|
|
29
|
-
const script = call || args.shift() ||
|
|
29
|
+
const script = call || args.shift() || scriptShell
|
|
30
30
|
const colorize = color ? chalk : nocolor
|
|
31
31
|
|
|
32
32
|
// do the fakey runScript dance
|
|
@@ -45,7 +45,7 @@ const run = async ({
|
|
|
45
45
|
log.disableProgress()
|
|
46
46
|
|
|
47
47
|
try {
|
|
48
|
-
if (script ===
|
|
48
|
+
if (script === scriptShell) {
|
|
49
49
|
const isTTY = !noTTY()
|
|
50
50
|
|
|
51
51
|
if (isTTY) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libnpmexec",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"lib"
|
|
6
6
|
],
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"eslint-plugin-node": "^11.1.0",
|
|
47
47
|
"eslint-plugin-promise": "^5.1.0",
|
|
48
48
|
"eslint-plugin-standard": "^5.0.0",
|
|
49
|
-
"tap": "^15.0.
|
|
49
|
+
"tap": "^15.0.6"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@npmcli/arborist": "^2.3.0",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"pacote": "^11.3.1",
|
|
59
59
|
"proc-log": "^1.0.0",
|
|
60
60
|
"read": "^1.0.7",
|
|
61
|
-
"read-package-json-fast": "^2.0.2"
|
|
61
|
+
"read-package-json-fast": "^2.0.2",
|
|
62
|
+
"walk-up-path": "^1.0.0"
|
|
62
63
|
}
|
|
63
64
|
}
|