From b3ad425b530c8051df67605d2c840afbe210a42d Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Tue, 23 Apr 2019 10:48:09 +0200 Subject: [PATCH] feat(npm): support package aliases (#3577) Closes #3575 --- lib/manager/npm/extract/index.js | 13 ++++++ lib/manager/npm/update.js | 3 ++ .../npm/__snapshots__/update.spec.js.snap | 2 + .../extract/__snapshots__/index.spec.js.snap | 46 +++++++++++++++++++ test/manager/npm/extract/index.spec.js | 16 +++++++ test/manager/npm/update.spec.js | 17 +++++++ 6 files changed, 97 insertions(+) diff --git a/lib/manager/npm/extract/index.js b/lib/manager/npm/extract/index.js index 4c1f5f6db0..cc132f9fb2 100644 --- a/lib/manager/npm/extract/index.js +++ b/lib/manager/npm/extract/index.js @@ -169,6 +169,19 @@ async function extractPackageFile(content, fileName, config) { } return dep; } + if (dep.currentValue.startsWith('npm:')) { + dep.npmPackageAlias = true; + const valSplit = dep.currentValue.replace('npm:', '').split('@'); + if (valSplit.length === 2) { + dep.lookupName = valSplit[0]; + dep.currentValue = valSplit[1]; + } else if (valSplit.length === 3) { + dep.lookupName = valSplit[0] + '@' + valSplit[1]; + dep.currentValue = valSplit[2]; + } else { + logger.info('Invalid npm package alias: ' + dep.currentValue); + } + } if (dep.currentValue.startsWith('file:')) { dep.skipReason = 'file'; hasFileRefs = true; diff --git a/lib/manager/npm/update.js b/lib/manager/npm/update.js index 31f824b100..bf81a6914b 100644 --- a/lib/manager/npm/update.js +++ b/lib/manager/npm/update.js @@ -24,6 +24,9 @@ function updateDependency(fileContent, upgrade) { ); } } + if (upgrade.npmPackageAlias) { + newValue = `npm:${upgrade.lookupName}@${newValue}`; + } logger.debug(`npm.updateDependency(): ${depType}.${depName} = ${newValue}`); try { const parsedContents = JSON.parse(fileContent); diff --git a/test/manager/npm/__snapshots__/update.spec.js.snap b/test/manager/npm/__snapshots__/update.spec.js.snap index 21bae26179..a3b4198523 100644 --- a/test/manager/npm/__snapshots__/update.spec.js.snap +++ b/test/manager/npm/__snapshots__/update.spec.js.snap @@ -11,3 +11,5 @@ exports[`workers/branch/package-json .updateDependency(fileContent, depType, dep exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a github fully specified version 1`] = `"{\\"dependencies\\":{\\"n\\":\\"git+https://github.com/owner/n#v1.1.0\\"}}"`; exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a github short hash 1`] = `"{\\"dependencies\\":{\\"gulp\\":\\"gulpjs/gulp#0000000\\"}}"`; + +exports[`workers/branch/package-json .updateDependency(fileContent, depType, depName, newValue) replaces a npm package alias 1`] = `"{\\"dependencies\\":{\\"hapi\\":\\"npm:@hapi/hapi@18.3.1\\"}}"`; diff --git a/test/manager/npm/extract/__snapshots__/index.spec.js.snap b/test/manager/npm/extract/__snapshots__/index.spec.js.snap index 4af3f2c25a..1161e93147 100644 --- a/test/manager/npm/extract/__snapshots__/index.spec.js.snap +++ b/test/manager/npm/extract/__snapshots__/index.spec.js.snap @@ -287,6 +287,52 @@ Object { } `; +exports[`manager/npm/extract .extractPackageFile() extracts npm package alias 1`] = ` +Object { + "deps": Array [ + Object { + "currentValue": "1", + "datasource": "npm", + "depName": "a", + "depType": "dependencies", + "lookupName": "foo", + "npmPackageAlias": true, + "prettyDepType": "dependency", + }, + Object { + "currentValue": "1.2.3", + "datasource": "npm", + "depName": "b", + "depType": "dependencies", + "lookupName": "@foo/bar", + "npmPackageAlias": true, + "prettyDepType": "dependency", + }, + Object { + "currentValue": "npm:foo", + "depName": "c", + "depType": "dependencies", + "npmPackageAlias": true, + "prettyDepType": "dependency", + "skipReason": "unknown-version", + }, + ], + "lernaClient": undefined, + "lernaDir": undefined, + "lernaPackages": undefined, + "npmLock": undefined, + "npmrc": undefined, + "packageJsonName": undefined, + "packageJsonType": "app", + "packageJsonVersion": undefined, + "pnpmShrinkwrap": undefined, + "skipInstalls": true, + "yarnLock": undefined, + "yarnWorkspacesPackages": undefined, + "yarnrc": undefined, +} +`; + exports[`manager/npm/extract .extractPackageFile() finds a lock file 1`] = ` Object { "deps": Array [ diff --git a/test/manager/npm/extract/index.spec.js b/test/manager/npm/extract/index.spec.js index a59e8053c5..a8f15aa49a 100644 --- a/test/manager/npm/extract/index.spec.js +++ b/test/manager/npm/extract/index.spec.js @@ -202,6 +202,22 @@ describe('manager/npm/extract', () => { ); expect(res).toMatchSnapshot(); }); + it('extracts npm package alias', async () => { + const pJson = { + dependencies: { + a: 'npm:foo@1', + b: 'npm:@foo/bar@1.2.3', + c: 'npm:foo', + }, + }; + const pJsonStr = JSON.stringify(pJson); + const res = await npmExtract.extractPackageFile( + pJsonStr, + 'package.json', + defaultConfig + ); + expect(res).toMatchSnapshot(); + }); }); describe('.postExtract()', () => { it('runs', async () => { diff --git a/test/manager/npm/update.spec.js b/test/manager/npm/update.spec.js index f9a7da5c69..5f124f9de2 100644 --- a/test/manager/npm/update.spec.js +++ b/test/manager/npm/update.spec.js @@ -41,6 +41,23 @@ describe('workers/branch/package-json', () => { const res = npmUpdater.updateDependency(input, upgrade); expect(res).toMatchSnapshot(); }); + it('replaces a npm package alias', () => { + const upgrade = { + depType: 'dependencies', + depName: 'hapi', + npmPackageAlias: true, + lookupName: '@hapi/hapi', + currentValue: '18.3.0', + newValue: '18.3.1', + }; + const input = JSON.stringify({ + dependencies: { + hapi: 'npm:@hapi/hapi@18.3.0', + }, + }); + const res = npmUpdater.updateDependency(input, upgrade); + expect(res).toMatchSnapshot(); + }); it('replaces a github short hash', () => { const upgrade = { depType: 'dependencies', -- GitLab