From 87863f165ecfee691a938bafedc590898c16f279 Mon Sep 17 00:00:00 2001
From: Nihal <nihal9ns@gmail.com>
Date: Wed, 25 Sep 2019 14:31:35 +0530
Subject: [PATCH] feat: support for volta (#4512)

---
 lib/manager/npm/extract/index.ts              |  21 ++++
 .../extract/__snapshots__/index.spec.ts.snap  | 118 ++++++++++++++++++
 test/manager/npm/extract/index.spec.ts        |  40 ++++++
 3 files changed, 179 insertions(+)

diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts
index a483e68579..5ef5a11d77 100644
--- a/lib/manager/npm/extract/index.ts
+++ b/lib/manager/npm/extract/index.ts
@@ -149,6 +149,7 @@ export async function extractPackageFile(
     optionalDependencies: 'optionalDependency',
     peerDependencies: 'peerDependency',
     engines: 'engine',
+    volta: 'volta',
   };
 
   function extractDependency(depType: string, depName: string, input: string) {
@@ -181,6 +182,25 @@ export async function extractPackageFile(
       }
       return dep;
     }
+
+    // support for volta
+    if (depType === 'volta') {
+      if (depName === 'node') {
+        dep.datasource = 'github';
+        dep.lookupName = 'nodejs/node';
+        dep.versionScheme = 'node';
+      } else if (depName === 'yarn') {
+        dep.datasource = 'npm';
+        dep.commitMessageTopic = 'Yarn';
+      } else {
+        dep.skipReason = 'unknown-volta';
+      }
+      if (!isValid(dep.currentValue)) {
+        dep.skipReason = 'unknown-version';
+      }
+      return dep;
+    }
+
     if (dep.currentValue.startsWith('npm:')) {
       dep.npmPackageAlias = true;
       const valSplit = dep.currentValue.replace('npm:', '').split('@');
@@ -312,6 +332,7 @@ export async function extractPackageFile(
       skipInstalls = true;
     }
   }
+
   return {
     deps,
     packageJsonName,
diff --git a/test/manager/npm/extract/__snapshots__/index.spec.ts.snap b/test/manager/npm/extract/__snapshots__/index.spec.ts.snap
index 0029c6f67f..887d0b5311 100644
--- a/test/manager/npm/extract/__snapshots__/index.spec.ts.snap
+++ b/test/manager/npm/extract/__snapshots__/index.spec.ts.snap
@@ -337,6 +337,124 @@ Object {
 }
 `;
 
+exports[`manager/npm/extract .extractPackageFile() extracts volta 1`] = `
+Object {
+  "deps": Array [
+    Object {
+      "commitMessageTopic": "Node.js",
+      "currentValue": "8.9.2",
+      "datasource": "github",
+      "depName": "node",
+      "depType": "engines",
+      "lookupName": "nodejs/node",
+      "major": Object {
+        "enabled": false,
+      },
+      "prettyDepType": "engine",
+      "versionScheme": "node",
+    },
+    Object {
+      "commitMessageTopic": "Node.js",
+      "currentValue": "8.9.2",
+      "datasource": "github",
+      "depName": "node",
+      "depType": "volta",
+      "lookupName": "nodejs/node",
+      "major": Object {
+        "enabled": false,
+      },
+      "prettyDepType": "volta",
+      "versionScheme": "node",
+    },
+    Object {
+      "commitMessageTopic": "Yarn",
+      "currentValue": "1.12.3",
+      "datasource": "npm",
+      "depName": "yarn",
+      "depType": "volta",
+      "prettyDepType": "volta",
+    },
+    Object {
+      "currentValue": "5.9.0",
+      "depName": "npm",
+      "depType": "volta",
+      "prettyDepType": "volta",
+      "skipReason": "unknown-volta",
+    },
+  ],
+  "ignoreNpmrcFile": undefined,
+  "lernaClient": undefined,
+  "lernaDir": undefined,
+  "lernaPackages": undefined,
+  "npmLock": undefined,
+  "npmrc": undefined,
+  "packageJsonName": undefined,
+  "packageJsonType": "library",
+  "packageJsonVersion": undefined,
+  "pnpmShrinkwrap": undefined,
+  "skipInstalls": true,
+  "yarnLock": undefined,
+  "yarnWorkspacesPackages": undefined,
+  "yarnrc": undefined,
+}
+`;
+
+exports[`manager/npm/extract .extractPackageFile() extracts volta yarn unknown-version 1`] = `
+Object {
+  "deps": Array [
+    Object {
+      "commitMessageTopic": "Node.js",
+      "currentValue": "8.9.2",
+      "datasource": "github",
+      "depName": "node",
+      "depType": "engines",
+      "lookupName": "nodejs/node",
+      "major": Object {
+        "enabled": false,
+      },
+      "prettyDepType": "engine",
+      "versionScheme": "node",
+    },
+    Object {
+      "commitMessageTopic": "Node.js",
+      "currentValue": "8.9.2",
+      "datasource": "github",
+      "depName": "node",
+      "depType": "volta",
+      "lookupName": "nodejs/node",
+      "major": Object {
+        "enabled": false,
+      },
+      "prettyDepType": "volta",
+      "versionScheme": "node",
+    },
+    Object {
+      "commitMessageTopic": "Yarn",
+      "currentValue": "unknown",
+      "datasource": "npm",
+      "depName": "yarn",
+      "depType": "volta",
+      "prettyDepType": "volta",
+      "skipReason": "unknown-version",
+    },
+  ],
+  "ignoreNpmrcFile": undefined,
+  "lernaClient": undefined,
+  "lernaDir": undefined,
+  "lernaPackages": undefined,
+  "npmLock": undefined,
+  "npmrc": undefined,
+  "packageJsonName": undefined,
+  "packageJsonType": "library",
+  "packageJsonVersion": undefined,
+  "pnpmShrinkwrap": undefined,
+  "skipInstalls": true,
+  "yarnLock": undefined,
+  "yarnWorkspacesPackages": undefined,
+  "yarnrc": undefined,
+}
+`;
+
 exports[`manager/npm/extract .extractPackageFile() finds "npmClient":"npm" in lerna.json 1`] = `
 Object {
   "deps": Array [
diff --git a/test/manager/npm/extract/index.spec.ts b/test/manager/npm/extract/index.spec.ts
index 0802f62dbf..fa0154a8f5 100644
--- a/test/manager/npm/extract/index.spec.ts
+++ b/test/manager/npm/extract/index.spec.ts
@@ -209,6 +209,46 @@ describe('manager/npm/extract', () => {
       );
       expect(res).toMatchSnapshot();
     });
+    it('extracts volta', async () => {
+      const pJson = {
+        main: 'index.js',
+        engines: {
+          node: '8.9.2',
+        },
+        volta: {
+          node: '8.9.2',
+          yarn: '1.12.3',
+          npm: '5.9.0',
+        },
+      };
+      const pJsonStr = JSON.stringify(pJson);
+      const res = await npmExtract.extractPackageFile(
+        pJsonStr,
+        'package.json',
+        defaultConfig
+      );
+      expect(res).toMatchSnapshot();
+    });
+
+    it('extracts volta yarn unknown-version', async () => {
+      const pJson = {
+        main: 'index.js',
+        engines: {
+          node: '8.9.2',
+        },
+        volta: {
+          node: '8.9.2',
+          yarn: 'unknown',
+        },
+      };
+      const pJsonStr = JSON.stringify(pJson);
+      const res = await npmExtract.extractPackageFile(
+        pJsonStr,
+        'package.json',
+        defaultConfig
+      );
+      expect(res).toMatchSnapshot();
+    });
     it('extracts non-npmjs', async () => {
       const pJson = {
         dependencies: {
-- 
GitLab