From b9c0fded59d9437e2f59f900f5e357d3d84557a9 Mon Sep 17 00:00:00 2001 From: Masafumi Koba <473530+ybiquitous@users.noreply.github.com> Date: Mon, 10 May 2021 21:13:38 +0900 Subject: [PATCH] fix: `npm ls` parsing --- dist/index.js | 10 +++++++--- .../fixtures/empty_package.json/package.json | 1 + .../noversion_package.json/package.json | 3 +++ lib/__tests__/listPackages.test.js | 18 ++++++++++++++++++ lib/listPackages.js | 10 +++++++--- 5 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 lib/__tests__/fixtures/empty_package.json/package.json create mode 100644 lib/__tests__/fixtures/noversion_package.json/package.json diff --git a/dist/index.js b/dist/index.js index 8c9b0e13..0a69093f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4055,9 +4055,10 @@ const { exec } = __webpack_require__(986); const npmArgs = __webpack_require__(510); /** + * @param {import("@actions/exec").ExecOptions?} options * @returns {Promise>} */ -module.exports = async function listPackages({ silent } = { silent: false }) { +module.exports = async function listPackages(options = {}) { let lines = ""; let stderr = ""; const returnCode = await exec("npm", npmArgs("ls", "--parseable", "--long", "--all"), { @@ -4069,8 +4070,8 @@ module.exports = async function listPackages({ silent } = { silent: false }) { stderr += data.toString(); }, }, - silent, ignoreReturnCode: true, + ...options, }); // NOTE: Ignore missing peer deps error. @@ -4090,15 +4091,18 @@ module.exports = async function listPackages({ silent } = { silent: false }) { const match = /^(?@?\S+)@(?\S+)$/u.exec(pkg); if (match == null || match.groups == null) { - throw new Error(`Invalid line: "${line}"`); + return; // skip } + /* eslint-disable dot-notation, prefer-destructuring -- Prevent TS4111 */ const name = match.groups["name"]; const version = match.groups["version"]; /* eslint-enable */ + if (name == null || version == null) { throw new Error(`Invalid name and version: "${line}"`); } + packages.set(name.trim(), version.trim()); }); return packages; diff --git a/lib/__tests__/fixtures/empty_package.json/package.json b/lib/__tests__/fixtures/empty_package.json/package.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/lib/__tests__/fixtures/empty_package.json/package.json @@ -0,0 +1 @@ +{} diff --git a/lib/__tests__/fixtures/noversion_package.json/package.json b/lib/__tests__/fixtures/noversion_package.json/package.json new file mode 100644 index 00000000..bde99de9 --- /dev/null +++ b/lib/__tests__/fixtures/noversion_package.json/package.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} diff --git a/lib/__tests__/listPackages.test.js b/lib/__tests__/listPackages.test.js index 44b3af56..21a3ebf9 100644 --- a/lib/__tests__/listPackages.test.js +++ b/lib/__tests__/listPackages.test.js @@ -1,3 +1,5 @@ +const path = require("path"); + const listPackages = require("../listPackages"); test("listPackages()", async () => { @@ -6,3 +8,19 @@ test("listPackages()", async () => { expect(packages.get("jest")).toMatch(/^\d+\.\d+\.\d+$/u); expect(packages.get("@actions/core")).toMatch(/^\d+\.\d+\.\d+$/u); }); + +test("listPackages() with an empty package.json", async () => { + const packages = await listPackages({ + silent: true, + cwd: path.join(__dirname, "fixtures", "empty_package.json"), + }); + expect(packages.size).toEqual(0); +}); + +test("listPackages() with a package.json having no version", async () => { + const packages = await listPackages({ + silent: true, + cwd: path.join(__dirname, "fixtures", "noversion_package.json"), + }); + expect(packages.size).toEqual(0); +}); diff --git a/lib/listPackages.js b/lib/listPackages.js index 75ca0355..8073c82b 100644 --- a/lib/listPackages.js +++ b/lib/listPackages.js @@ -2,9 +2,10 @@ const { exec } = require("@actions/exec"); const npmArgs = require("./npmArgs"); /** + * @param {import("@actions/exec").ExecOptions?} options * @returns {Promise>} */ -module.exports = async function listPackages({ silent } = { silent: false }) { +module.exports = async function listPackages(options = {}) { let lines = ""; let stderr = ""; const returnCode = await exec("npm", npmArgs("ls", "--parseable", "--long", "--all"), { @@ -16,8 +17,8 @@ module.exports = async function listPackages({ silent } = { silent: false }) { stderr += data.toString(); }, }, - silent, ignoreReturnCode: true, + ...options, }); // NOTE: Ignore missing peer deps error. @@ -37,15 +38,18 @@ module.exports = async function listPackages({ silent } = { silent: false }) { const match = /^(?@?\S+)@(?\S+)$/u.exec(pkg); if (match == null || match.groups == null) { - throw new Error(`Invalid line: "${line}"`); + return; // skip } + /* eslint-disable dot-notation, prefer-destructuring -- Prevent TS4111 */ const name = match.groups["name"]; const version = match.groups["version"]; /* eslint-enable */ + if (name == null || version == null) { throw new Error(`Invalid name and version: "${line}"`); } + packages.set(name.trim(), version.trim()); }); return packages;