From 56d55fb1dc4cbf28b0d321fd30fe08e56ed68eec Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Fri, 4 Jan 2019 12:41:22 +0100
Subject: [PATCH] feat: node versioning

Very basic at first. A slim wrapper around npm semver that normalizes versions.
---
 lib/config/definitions.js                     |  3 +++
 lib/manager/npm/extract/index.js              |  3 ++-
 lib/manager/nvm/extract.js                    |  2 +-
 lib/manager/travis/package.js                 |  2 +-
 lib/versioning/node/index.js                  | 20 +++++++++++++++++++
 .../extract/__snapshots__/index.spec.js.snap  |  3 ++-
 .../nvm/__snapshots__/extract.spec.js.snap    |  4 ++--
 test/versioning/node.spec.js                  | 14 +++++++++++++
 8 files changed, 45 insertions(+), 6 deletions(-)
 create mode 100644 lib/versioning/node/index.js
 create mode 100644 test/versioning/node.spec.js

diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 5c38c47993..f440730e70 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -366,6 +366,7 @@ const options = [
       'docker',
       'hashicorp',
       'loose',
+      'node',
       'pep440',
       'ruby',
       'semver',
@@ -1148,6 +1149,7 @@ const options = [
     default: {
       enabled: false,
       fileMatch: ['^.travis.yml$'],
+      versionScheme: 'node',
     },
     mergeable: true,
     cli: false,
@@ -1159,6 +1161,7 @@ const options = [
     type: 'json',
     default: {
       fileMatch: ['^.nvmrc$'],
+      versionScheme: 'node',
     },
     mergeable: true,
     cli: false,
diff --git a/lib/manager/npm/extract/index.js b/lib/manager/npm/extract/index.js
index e37029c879..273729d521 100644
--- a/lib/manager/npm/extract/index.js
+++ b/lib/manager/npm/extract/index.js
@@ -141,7 +141,8 @@ async function extractPackageFile(content, fileName, config) {
     dep.currentValue = input.trim();
     if (depType === 'engines') {
       if (depName === 'node') {
-        dep.purl = 'pkg:github/nodejs/node?normalize=true';
+        dep.purl = 'pkg:github/nodejs/node';
+        dep.versionScheme = 'node';
       } else if (depName === 'yarn') {
         dep.purl = 'pkg:npm/yarn';
         dep.commitMessageTopic = 'Yarn';
diff --git a/lib/manager/nvm/extract.js b/lib/manager/nvm/extract.js
index 5c50835ccb..f3951782c8 100644
--- a/lib/manager/nvm/extract.js
+++ b/lib/manager/nvm/extract.js
@@ -8,7 +8,7 @@ function extractPackageFile(content) {
   const dep = {
     depName: 'node',
     currentValue: content.trim(),
-    purl: 'pkg:github/nodejs/node?normalize=true',
+    purl: 'pkg:github/nodejs/node',
   };
   if (!semver.isVersion(dep.currentValue)) {
     dep.skipReason = 'unsupported-version';
diff --git a/lib/manager/travis/package.js b/lib/manager/travis/package.js
index 17c1e5dea8..4d304d02f1 100644
--- a/lib/manager/travis/package.js
+++ b/lib/manager/travis/package.js
@@ -36,7 +36,7 @@ async function getPackageUpdates(config) {
   const newMajor = newValue[newValue.length - 1];
   if (config.rangeStrategy === 'pin' || isVersion(config.currentValue[0])) {
     const versions = (await getPkgReleases(
-      'pkg:github/nodejs/node?normalize=true',
+      'pkg:github/nodejs/node',
       config
     )).releases.map(release => release.version);
     newValue = newValue.map(value =>
diff --git a/lib/versioning/node/index.js b/lib/versioning/node/index.js
new file mode 100644
index 0000000000..547c0dc76a
--- /dev/null
+++ b/lib/versioning/node/index.js
@@ -0,0 +1,20 @@
+const semver = require('../semver');
+
+function getNewValue(currentValue, rangeStrategy, fromVersion, toVersion) {
+  const res = semver.getNewValue(
+    currentValue,
+    rangeStrategy,
+    fromVersion,
+    toVersion
+  );
+  if (semver.isVersion(res)) {
+    // normalize out any 'v' prefix
+    return semver.isVersion(res);
+  }
+  return res;
+}
+
+module.exports = {
+  ...semver,
+  getNewValue,
+};
diff --git a/test/manager/npm/extract/__snapshots__/index.spec.js.snap b/test/manager/npm/extract/__snapshots__/index.spec.js.snap
index 2c2b698ba8..d9dd4ba44f 100644
--- a/test/manager/npm/extract/__snapshots__/index.spec.js.snap
+++ b/test/manager/npm/extract/__snapshots__/index.spec.js.snap
@@ -63,7 +63,8 @@ Object {
         "enabled": false,
       },
       "prettyDepType": "engine",
-      "purl": "pkg:github/nodejs/node?normalize=true",
+      "purl": "pkg:github/nodejs/node",
+      "versionScheme": "node",
     },
     Object {
       "commitMessageTopic": "npm",
diff --git a/test/manager/nvm/__snapshots__/extract.spec.js.snap b/test/manager/nvm/__snapshots__/extract.spec.js.snap
index edd93f6ede..332a6ef5a3 100644
--- a/test/manager/nvm/__snapshots__/extract.spec.js.snap
+++ b/test/manager/nvm/__snapshots__/extract.spec.js.snap
@@ -5,7 +5,7 @@ Array [
   Object {
     "currentValue": "8.4.0",
     "depName": "node",
-    "purl": "pkg:github/nodejs/node?normalize=true",
+    "purl": "pkg:github/nodejs/node",
   },
 ]
 `;
@@ -15,7 +15,7 @@ Array [
   Object {
     "currentValue": "8.4",
     "depName": "node",
-    "purl": "pkg:github/nodejs/node?normalize=true",
+    "purl": "pkg:github/nodejs/node",
     "skipReason": "unsupported-version",
   },
 ]
diff --git a/test/versioning/node.spec.js b/test/versioning/node.spec.js
new file mode 100644
index 0000000000..e5ca0930a0
--- /dev/null
+++ b/test/versioning/node.spec.js
@@ -0,0 +1,14 @@
+const nodever = require('../../lib/versioning/node');
+
+describe('semver.getNewValue()', () => {
+  it('returns normalized toVersion', () => {
+    expect(nodever.getNewValue('1.0.0', 'replace', '1.0.0', 'v1.1.0')).toEqual(
+      '1.1.0'
+    );
+  });
+  it('returns range', () => {
+    expect(nodever.getNewValue('~8.0.0', 'replace', '8.0.2', 'v8.2.0')).toEqual(
+      '~8.2.0'
+    );
+  });
+});
-- 
GitLab