Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuy Adorno <ruyadorno@hotmail.com>2022-01-27 02:32:34 +0300
committerRuy Adorno <ruyadorno@hotmail.com>2022-01-27 18:56:07 +0300
commitb51b29c563fa97aa4fbf38250d1f04e879a8d961 (patch)
treed0fd183ae83518dc5e901650d022640f4f5db920
parent8558527c7158b2c1c353f8ab9c31de2a66ab470e (diff)
fix(arborist): update save exact
When updating dependencies we need an extra check when filtering nodes to be updated that ensures we do not override semver ranges that are pointing to an exact version. e.g: =1.0.0, 1.0.0 Fixes: https://github.com/npm/cli/issues/4329
-rw-r--r--workspaces/arborist/lib/arborist/reify.js18
-rw-r--r--workspaces/arborist/test/arborist/reify.js29
-rw-r--r--workspaces/arborist/test/fixtures/reify-cases/update-exact-version.js54
-rw-r--r--workspaces/arborist/test/fixtures/update-exact-version/node_modules/abbrev/package.json15
-rw-r--r--workspaces/arborist/test/fixtures/update-exact-version/package-lock.json24
-rw-r--r--workspaces/arborist/test/fixtures/update-exact-version/package.json5
6 files changed, 145 insertions, 0 deletions
diff --git a/workspaces/arborist/lib/arborist/reify.js b/workspaces/arborist/lib/arborist/reify.js
index d5e703238..45ef93985 100644
--- a/workspaces/arborist/lib/arborist/reify.js
+++ b/workspaces/arborist/lib/arborist/reify.js
@@ -5,6 +5,7 @@ const pacote = require('pacote')
const AuditReport = require('../audit-report.js')
const { subset, intersects } = require('semver')
const npa = require('npm-package-arg')
+const semver = require('semver')
const debug = require('../debug.js')
const walkUp = require('walk-up-path')
@@ -1273,6 +1274,21 @@ module.exports = cls => class Reifier extends cls {
}
}
+ // Returns true if any of the edges from this node has a semver
+ // range definition that is an exact match to the version installed
+ // e.g: should return true if for a given an installed version 1.0.0,
+ // range is either =1.0.0 or 1.0.0
+ const exactVersion = node => {
+ for (const edge of node.edgesIn) {
+ try {
+ if (semver.subset(edge.spec, node.version)) {
+ return false
+ }
+ } catch {}
+ }
+ return true
+ }
+
// helper that retrieves an array of nodes that were
// potentially updated during the reify process, in order
// to limit the number of nodes to check and update, only
@@ -1284,6 +1300,8 @@ module.exports = cls => class Reifier extends cls {
const filterDirectDependencies = node =>
!node.isRoot && node.resolveParent.isRoot
&& (!names || names.includes(node.name))
+ && exactVersion(node) // skip update for exact ranges
+
const directDeps = this.idealTree.inventory
.filter(filterDirectDependencies)
diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js
index d5fc166a5..caa15f59f 100644
--- a/workspaces/arborist/test/arborist/reify.js
+++ b/workspaces/arborist/test/arborist/reify.js
@@ -2572,5 +2572,34 @@ t.test('save package.json on update', t => {
)
})
+ t.test('should preserve exact ranges', async t => {
+ const path = fixture(t, 'update-exact-version')
+
+ await reify(path, { update: true, save: true })
+
+ t.equal(
+ require(resolve(path, 'package.json')).dependencies.abbrev,
+ '1.0.4',
+ 'should save no top level dep update to root package.json'
+ )
+ })
+
+ t.test('should preserve exact ranges, missing actual tree', async t => {
+ const path = t.testdir({
+ 'package.json': JSON.stringify({
+ dependencies: {
+ abbrev: '1.0.4',
+ },
+ }),
+ })
+
+ await reify(path, { update: true, save: true })
+
+ t.equal(
+ require(resolve(path, 'package.json')).dependencies.abbrev,
+ '1.0.4',
+ 'should save no top level dep update to root package.json'
+ )
+ })
t.end()
})
diff --git a/workspaces/arborist/test/fixtures/reify-cases/update-exact-version.js b/workspaces/arborist/test/fixtures/reify-cases/update-exact-version.js
new file mode 100644
index 000000000..d766d3bc9
--- /dev/null
+++ b/workspaces/arborist/test/fixtures/reify-cases/update-exact-version.js
@@ -0,0 +1,54 @@
+// generated from test/fixtures/update-exact-version
+module.exports = t => {
+ const path = t.testdir({
+ "node_modules": {
+ "abbrev": {
+ "package.json": JSON.stringify({
+ "name": "abbrev",
+ "version": "1.0.4",
+ "description": "Like ruby's abbrev module, but in js",
+ "author": "Isaac Z. Schlueter <i@izs.me>",
+ "main": "./lib/abbrev.js",
+ "scripts": {
+ "test": "node lib/abbrev.js"
+ },
+ "repository": "http://github.com/isaacs/abbrev-js",
+ "license": {
+ "type": "MIT",
+ "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE"
+ }
+ })
+ }
+ },
+ "package-lock.json": JSON.stringify({
+ "name": "update-exact-version",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "abbrev": "1.0.4"
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz",
+ "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0="
+ }
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz",
+ "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0="
+ }
+ }
+ }),
+ "package.json": JSON.stringify({
+ "dependencies": {
+ "abbrev": "1.0.4"
+ }
+ })
+})
+ return path
+}
diff --git a/workspaces/arborist/test/fixtures/update-exact-version/node_modules/abbrev/package.json b/workspaces/arborist/test/fixtures/update-exact-version/node_modules/abbrev/package.json
new file mode 100644
index 000000000..72042a5b9
--- /dev/null
+++ b/workspaces/arborist/test/fixtures/update-exact-version/node_modules/abbrev/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "abbrev",
+ "version": "1.0.4",
+ "description": "Like ruby's abbrev module, but in js",
+ "author": "Isaac Z. Schlueter <i@izs.me>",
+ "main": "./lib/abbrev.js",
+ "scripts": {
+ "test": "node lib/abbrev.js"
+ },
+ "repository": "http://github.com/isaacs/abbrev-js",
+ "license": {
+ "type": "MIT",
+ "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE"
+ }
+}
diff --git a/workspaces/arborist/test/fixtures/update-exact-version/package-lock.json b/workspaces/arborist/test/fixtures/update-exact-version/package-lock.json
new file mode 100644
index 000000000..0d7b5f647
--- /dev/null
+++ b/workspaces/arborist/test/fixtures/update-exact-version/package-lock.json
@@ -0,0 +1,24 @@
+{
+ "name": "update-exact-version",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "abbrev": "1.0.4"
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz",
+ "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0="
+ }
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz",
+ "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0="
+ }
+ }
+}
diff --git a/workspaces/arborist/test/fixtures/update-exact-version/package.json b/workspaces/arborist/test/fixtures/update-exact-version/package.json
new file mode 100644
index 000000000..4fa414793
--- /dev/null
+++ b/workspaces/arborist/test/fixtures/update-exact-version/package.json
@@ -0,0 +1,5 @@
+{
+ "dependencies": {
+ "abbrev": "1.0.4"
+ }
+}