libnpmexec 4.0.3 → 4.0.6

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/lib/index.js CHANGED
@@ -9,15 +9,14 @@ const npmlog = require('npmlog')
9
9
  const mkdirp = require('mkdirp-infer-owner')
10
10
  const npa = require('npm-package-arg')
11
11
  const pacote = require('pacote')
12
- const readPackageJson = require('read-package-json-fast')
13
12
 
14
13
  const cacheInstallDir = require('./cache-install-dir.js')
15
14
  const { fileExists, localFileExists } = require('./file-exists.js')
16
15
  const getBinFromManifest = require('./get-bin-from-manifest.js')
17
- const manifestMissing = require('./manifest-missing.js')
18
16
  const noTTY = require('./no-tty.js')
19
17
  const runScript = require('./run-script.js')
20
18
  const isWindows = require('./is-windows.js')
19
+ const _localManifest = Symbol('localManifest')
21
20
 
22
21
  /* istanbul ignore next */
23
22
  const PATH = (
@@ -86,20 +85,42 @@ const exec = async (opts) => {
86
85
  packages.push(args[0])
87
86
  }
88
87
 
88
+ // figure out whether we need to install stuff, or if local is fine
89
+ const localArb = new Arborist({
90
+ ...flatOptions,
91
+ path,
92
+ })
93
+ const localTree = await localArb.loadActual()
94
+
95
+ const getLocalManifest = ({ tree, name }) => {
96
+ // look up the package name in the current tree inventory,
97
+ // if it's found then return that normalized pkg data
98
+ const [node] = tree.inventory.query('packageName', name)
99
+
100
+ if (node) {
101
+ return {
102
+ _id: node.pkgid,
103
+ ...node.package,
104
+ [_localManifest]: true,
105
+ }
106
+ }
107
+ }
108
+
89
109
  // If we do `npm exec foo`, and have a `foo` locally, then we'll
90
110
  // always use that, so we don't really need to fetch the manifest.
91
111
  // So: run npa on each packages entry, and if it is a name with a
92
- // rawSpec==='', then try to readPackageJson at
93
- // node_modules/${name}/package.json, and only pacote fetch if
94
- // that fails.
112
+ // rawSpec==='', then try to find that node name in the tree inventory
113
+ // and only pacote fetch if that fails.
95
114
  const manis = await Promise.all(packages.map(async p => {
96
115
  const spec = npa(p, path)
97
116
  if (spec.type === 'tag' && spec.rawSpec === '') {
98
- // fall through to the pacote.manifest() approach
99
- try {
100
- const pj = resolve(path, 'node_modules', spec.name, 'package.json')
101
- return await readPackageJson(pj)
102
- } catch (er) {}
117
+ const localManifest = getLocalManifest({
118
+ tree: localTree,
119
+ name: spec.name,
120
+ })
121
+ if (localManifest) {
122
+ return localManifest
123
+ }
103
124
  }
104
125
  // Force preferOnline to true so we are making sure to pull in the latest
105
126
  // This is especially useful if the user didn't give us a version, and
@@ -114,16 +135,9 @@ const exec = async (opts) => {
114
135
  args[0] = getBinFromManifest(manis[0])
115
136
  }
116
137
 
117
- // figure out whether we need to install stuff, or if local is fine
118
- const localArb = new Arborist({
119
- ...flatOptions,
120
- path,
121
- })
122
- const localTree = await localArb.loadActual()
123
-
124
- // do we have all the packages in manifest list?
138
+ // are all packages from the manifest list installed?
125
139
  const needInstall =
126
- manis.some(manifest => manifestMissing({ tree: localTree, manifest }))
140
+ manis.some(manifest => !manifest[_localManifest])
127
141
 
128
142
  if (needInstall) {
129
143
  const { npxCache } = flatOptions
@@ -135,17 +149,24 @@ const exec = async (opts) => {
135
149
  })
136
150
  const tree = await arb.loadActual()
137
151
 
152
+ // inspect the npx-space installed tree to check if the package is already
153
+ // there, if that's the case also check that it's version matches the same
154
+ // version expected by the user requested pkg returned by pacote.manifest
155
+ const filterMissingPackagesFromInstallDir = (mani) => {
156
+ const localManifest = getLocalManifest({ tree, name: mani.name })
157
+ if (localManifest) {
158
+ return localManifest.version !== mani.version
159
+ }
160
+ return true
161
+ }
162
+
138
163
  // at this point, we have to ensure that we get the exact same
139
164
  // version, because it's something that has only ever been installed
140
165
  // by npm exec in the cache install directory
141
- const add = manis.filter(mani => manifestMissing({
142
- tree,
143
- manifest: {
144
- ...mani,
145
- _from: `${mani.name}@${mani.version}`,
146
- },
147
- }))
148
- .map(mani => mani._from)
166
+ const add = manis
167
+ .filter(mani => !mani[_localManifest])
168
+ .filter(filterMissingPackagesFromInstallDir)
169
+ .map(mani => mani._id || mani._from)
149
170
  .sort((a, b) => a.localeCompare(b, 'en'))
150
171
 
151
172
  // no need to install if already present
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libnpmexec",
3
- "version": "4.0.3",
3
+ "version": "4.0.6",
4
4
  "files": [
5
5
  "bin/",
6
6
  "lib/"
@@ -46,12 +46,11 @@
46
46
  },
47
47
  "tap": {
48
48
  "color": true,
49
- "check-coverage": true,
50
49
  "files": "test/*.js"
51
50
  },
52
51
  "devDependencies": {
53
52
  "@npmcli/eslint-config": "^3.0.1",
54
- "@npmcli/template-oss": "3.3.2",
53
+ "@npmcli/template-oss": "3.5.0",
55
54
  "bin-links": "^3.0.0",
56
55
  "tap": "^16.0.1"
57
56
  },
@@ -62,7 +61,7 @@
62
61
  "chalk": "^4.1.0",
63
62
  "mkdirp-infer-owner": "^2.0.0",
64
63
  "npm-package-arg": "^9.0.1",
65
- "npmlog": "^6.0.1",
64
+ "npmlog": "^6.0.2",
66
65
  "pacote": "^13.0.5",
67
66
  "proc-log": "^2.0.0",
68
67
  "read": "^1.0.7",
@@ -71,6 +70,6 @@
71
70
  },
72
71
  "templateOSS": {
73
72
  "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
74
- "version": "3.3.2"
73
+ "version": "3.5.0"
75
74
  }
76
75
  }
@@ -1,19 +0,0 @@
1
- const manifestMissing = ({ tree, manifest }) => {
2
- // if the tree doesn't have a child by that name/version, return true
3
- // true means we need to install it
4
- const child = tree.children.get(manifest.name)
5
- // if no child, we have to load it
6
- if (!child) {
7
- return true
8
- }
9
-
10
- // if no version/tag specified, allow whatever's there
11
- if (manifest._from === `${manifest.name}@`) {
12
- return false
13
- }
14
-
15
- // otherwise the version has to match what we WOULD get
16
- return child.version !== manifest.version
17
- }
18
-
19
- module.exports = manifestMissing