Skip to content

Commit 8461186

Browse files
committed
fix: update npx cache if possible when spec is a range
Closes: #7838
1 parent 247ee1d commit 8461186

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

lib/commands/cache.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ const jsonParse = require('json-parse-even-better-errors')
88
const localeCompare = require('@isaacs/string-locale-compare')('en')
99
const { log, output } = require('proc-log')
1010
const PkgJson = require('@npmcli/package-json')
11-
const BaseCommand = require('../base-cmd.js')
1211
const abbrev = require('abbrev')
12+
const BaseCommand = require('../base-cmd.js')
1313

1414
const searchCachePackage = async (path, parsed, cacheKeys) => {
1515
const searchMFH = new RegExp(`^make-fetch-happen:request-cache:.*(?<!/[@a-zA-Z]+)/${parsed.name}/-/(${parsed.name}[^/]+.tgz)$`)

workspaces/libnpmexec/lib/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow })
3838
// - In local or global mode go with anything in the tree that matches
3939
// - If looking in the npx cache check if a newer version is available
4040
const npxByNameOnly = isNpxTree && spec.name === spec.raw
41+
// If they gave a range and not a tag we still need to check if it's outdated.
4142
if (spec.registry && spec.type !== 'tag' && !npxByNameOnly) {
4243
// registry spec that is not a specific tag.
4344
const nodesBySpec = tree.inventory.query('packageName', spec.name)
@@ -54,7 +55,8 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow })
5455
return { node }
5556
}
5657
// package requested by version range, only remaining registry type
57-
if (semver.satisfies(node.package.version, spec.rawSpec)) {
58+
// the npx tree shouldn't be ok w/ an outdated version
59+
if (!isNpxTree && semver.satisfies(node.package.version, spec.rawSpec)) {
5860
return { node }
5961
}
6062
}

workspaces/libnpmexec/test/registry.js

+52
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { resolve } = require('node:path')
22
const t = require('tap')
33
const { setup, createPkg, merge } = require('./fixtures/setup.js')
4+
const crypto = require('node:crypto')
45

56
t.test('run from registry - no local packages', async t => {
67
const { fixtures, package } = createPkg({ versions: ['2.0.0'] })
@@ -245,3 +246,54 @@ t.test('run from registry - non existant global path', async t => {
245246
value: 'packages-2.0.0',
246247
})
247248
})
249+
250+
t.test('npx tree triggers manifest fetch when local version does satisfy range using real npx cache inventory', async t => {
251+
// The local installation is version 1.0.0, which does NOT satisfy the spec ^2.0.0.
252+
const pkgData = createPkg({
253+
localVersion: '1.0.0',
254+
versions: ['1.0.0', '2.0.0', '2.0.1'],
255+
name: '@npmcli/create-index',
256+
})
257+
const { fixtures, package: pkg } = pkgData
258+
259+
const hash = crypto.createHash('sha512')
260+
.update('@npmcli/create-index@^2.0.0')
261+
.digest('hex')
262+
.slice(0, 16)
263+
264+
const npxCacheFixture = {
265+
[hash]: {
266+
'package.json': {
267+
name: '@npmcli/create-index',
268+
version: '2.0.0',
269+
},
270+
},
271+
}
272+
273+
const { exec: execFn, path, registry, readOutput, binLinks } = setup(t, {
274+
pkg: [pkg],
275+
testdir: {
276+
...fixtures,
277+
npxCache: npxCacheFixture,
278+
},
279+
})
280+
281+
// Set up the registry package so that a manifest fetch returns version 2.0.1.
282+
await pkg({
283+
registry,
284+
path,
285+
tarballs: ['2.0.1'],
286+
})
287+
await binLinks()
288+
289+
// Execute in NPX mode with the spec ^2.0.0.
290+
// The local tree (version 1.0.0) does not satisfy ^2.0.0, so the system will find the cached package (version 2.0.0) in npxCache and then update from the registry to 2.0.1.
291+
await execFn({
292+
args: ['create-index'],
293+
packages: ['@npmcli/create-index@^2.0.0'],
294+
})
295+
296+
t.match(await readOutput('@npmcli-create-index'), {
297+
value: 'packages-2.0.1',
298+
})
299+
})

0 commit comments

Comments
 (0)