diff --git a/.changeset/wet-snakes-sit.md b/.changeset/wet-snakes-sit.md new file mode 100644 index 00000000000..882d64da73f --- /dev/null +++ b/.changeset/wet-snakes-sit.md @@ -0,0 +1,7 @@ +--- +"@pnpm/license-scanner": patch +"@pnpm/plugin-commands-licenses": patch +"pnpm": patch +--- + +`pnpm license list` should not fail if a license file is an executable [#5740](https://github.com/pnpm/pnpm/pull/5740). diff --git a/reviewing/license-scanner/src/getPkgInfo.ts b/reviewing/license-scanner/src/getPkgInfo.ts index 9b635dc86e9..5d52dc17016 100644 --- a/reviewing/license-scanner/src/getPkgInfo.ts +++ b/reviewing/license-scanner/src/getPkgInfo.ts @@ -128,10 +128,7 @@ async function parseLicense ( if (pkg.files.local) { licenseContents = await readFile(licensePackageFileInfo as string) } else { - licenseContents = await readLicenseFileFromCafs( - opts.cafsDir, - (licensePackageFileInfo as PackageFileInfo).integrity - ) + licenseContents = await readLicenseFileFromCafs(opts.cafsDir, licensePackageFileInfo as PackageFileInfo) } return { @@ -150,8 +147,8 @@ async function parseLicense ( * @param opts the options for reading file * @returns Promise */ -async function readLicenseFileFromCafs (cafsDir: string, fileIntegrity: string) { - const fileName = getFilePathByModeInCafs(cafsDir, fileIntegrity, 0) +async function readLicenseFileFromCafs (cafsDir: string, { integrity, mode }: PackageFileInfo) { + const fileName = getFilePathByModeInCafs(cafsDir, integrity, mode) const fileContents = await readFile(fileName) return fileContents } diff --git a/reviewing/plugin-commands-licenses/test/__snapshots__/index.ts.snap b/reviewing/plugin-commands-licenses/test/__snapshots__/index.ts.snap index 4284e210bc7..41fed5eda11 100644 --- a/reviewing/plugin-commands-licenses/test/__snapshots__/index.ts.snap +++ b/reviewing/plugin-commands-licenses/test/__snapshots__/index.ts.snap @@ -6,6 +6,57 @@ exports[`pnpm licenses: output as json: found-license-types 1`] = ` ] `; +exports[`pnpm licenses: should correctly read LICENSE file with executable file mode: show-packages-details 1`] = ` +"┌──────────────────────────────┬─────────┬───────────────────────────────────────────────────────┐ +│ Package │ License │ Details │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ inherits │ ISC │ https://github.com/isaacs/inherits#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ sax │ ISC │ Isaac Z. Schlueter │ +│ │ │ https://github.com/isaacs/sax-js#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ commander │ MIT │ TJ Holowaychuk │ +│ │ │ https://github.com/tj/commander.js#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ core-util-is │ MIT │ Isaac Z. Schlueter │ +│ │ │ https://github.com/isaacs/core-util-is#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ isarray │ MIT │ Julian Gruber │ +│ │ │ https://github.com/juliangruber/isarray │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ neatequal │ MIT │ Nicolas Froidure │ +│ │ │ https://github.com/nfroidure/neatequal │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ process-nextick-args │ MIT │ https://github.com/calvinmetcalf/process-nextick-args │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ readable-stream │ MIT │ https://github.com/nodejs/readable-stream#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ safe-buffer │ MIT │ Feross Aboukhadijeh │ +│ │ │ https://github.com/feross/safe-buffer │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ string_decoder │ MIT │ https://github.com/nodejs/string_decoder │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ string.fromcodepoint │ MIT │ Mathias Bynens │ +│ │ │ http://mths.be/fromcodepoint │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ string.prototype.codepointat │ MIT │ Mathias Bynens │ +│ │ │ https://mths.be/codepointat │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ svg-pathdata │ MIT │ Nicolas Froidure │ +│ │ │ https://github.com/nfroidure/SVGPathData#readme │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ svgicons2svgfont │ MIT │ Nicolas Froidure │ +│ │ │ https://github.com/nfroidure/svgicons2svgfont │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ util-deprecate │ MIT │ Nathan Rajlich │ +│ │ │ https://github.com/TooTallNate/util-deprecate │ +├──────────────────────────────┼─────────┼───────────────────────────────────────────────────────┤ +│ varstream │ Unknown │ Nicolas Froidure │ +│ │ │ https://github.com/nfroidure/VarStream#readme │ +└──────────────────────────────┴─────────┴───────────────────────────────────────────────────────┘ +" +`; + exports[`pnpm licenses: show details: show-packages-details 1`] = ` "┌─────────────┬─────────┬─────────────────────────────────────────────┐ │ Package │ License │ Details │ diff --git a/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/package.json b/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/package.json new file mode 100644 index 00000000000..519cf3495e3 --- /dev/null +++ b/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/package.json @@ -0,0 +1,15 @@ +{ + "name": "pnpm-licenses-bug001", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "svgicons2svgfont": "5.0.2" + } +} diff --git a/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/pnpm-lock.yaml b/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/pnpm-lock.yaml new file mode 100644 index 00000000000..0777678bbee --- /dev/null +++ b/reviewing/plugin-commands-licenses/test/fixtures/file-mode-test/pnpm-lock.yaml @@ -0,0 +1,134 @@ +lockfileVersion: 5.4 + +specifiers: + svgicons2svgfont: 5.0.2 + +dependencies: + svgicons2svgfont: 5.0.2 + +packages: + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /core-util-is/1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /isarray/0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false + + /isarray/1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: false + + /neatequal/1.0.0: + resolution: {integrity: sha512-sVt5awO4a4w24QmAthdrCPiVRW3naB8FGLdyadin01BH+6BzNPEBwGrpwCczQvPlULS6uXTItTe1PJ5P0kYm7A==} + dependencies: + varstream: 0.3.2 + dev: false + + /process-nextick-args/1.0.7: + resolution: {integrity: sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==} + dev: false + + /process-nextick-args/2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false + + /readable-stream/1.1.14: + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: false + + /readable-stream/2.0.6: + resolution: {integrity: sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 1.0.7 + string_decoder: 0.10.31 + util-deprecate: 1.0.2 + dev: false + + /readable-stream/2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false + + /sax/1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: false + + /string.fromcodepoint/0.2.1: + resolution: {integrity: sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==} + dev: false + + /string.prototype.codepointat/0.2.1: + resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} + dev: false + + /string_decoder/0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: false + + /string_decoder/1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: false + + /svg-pathdata/1.0.4: + resolution: {integrity: sha512-afGVCE1xFbmI/uV6XiToTwnHZZtSiW9u8EBxZqRE25pPGk2Z9eEvT5nhAPRUnvUWs9FqwjdJeElkqoWKeW3JGA==} + engines: {node: '>= 0.10.0'} + dependencies: + readable-stream: 2.0.6 + dev: false + + /svgicons2svgfont/5.0.2: + resolution: {integrity: sha512-N9GG8atI7eKksJpLLDYXHzKcNy698FL+Bdu0sXgwURgVzNmeD35iSCnZhNuPMs4Ve2tg8vqHXI1ZNEWU6vhwjw==} + engines: {node: '>= 0.10.0'} + hasBin: true + dependencies: + commander: 2.20.3 + neatequal: 1.0.0 + readable-stream: 2.3.7 + sax: 1.2.4 + string.fromcodepoint: 0.2.1 + string.prototype.codepointat: 0.2.1 + svg-pathdata: 1.0.4 + dev: false + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /varstream/0.3.2: + resolution: {integrity: sha512-OpR3Usr9dGZZbDttlTxdviGdxiURI0prX68+DuaN/JfIDbK9ZOmREKM6PgmelsejMnhgjXmEEEgf+E4NbsSqMg==} + engines: {node: '>=0.10.*'} + hasBin: true + dependencies: + readable-stream: 1.1.14 + dev: false diff --git a/reviewing/plugin-commands-licenses/test/index.ts b/reviewing/plugin-commands-licenses/test/index.ts index 47fda9820e7..7d747c8fe05 100644 --- a/reviewing/plugin-commands-licenses/test/index.ts +++ b/reviewing/plugin-commands-licenses/test/index.ts @@ -134,3 +134,30 @@ test('pnpm licenses: fails when lockfile is missing', async () => { '"No pnpm-lock.yaml found: Cannot check a project without a lockfile"' ) }) + +test('pnpm licenses: should correctly read LICENSE file with executable file mode', async () => { + const workspaceDir = path.resolve('./test/fixtures/file-mode-test') + + const tmp = tempy.directory() + const storeDir = path.join(tmp, 'store') + await install.handler({ + ...DEFAULT_OPTS, + dir: workspaceDir, + pnpmHomeDir: '', + storeDir, + }) + + // Attempt to run the licenses command now + const { output, exitCode } = await licenses.handler({ + ...LICENSES_OPTIONS, + dir: workspaceDir, + pnpmHomeDir: '', + long: true, + // we need to prefix it with v3 otherwise licenses tool can't find anything + // in the content-addressable directory + storeDir: path.resolve(storeDir, 'v3'), + }, ['list']) + + expect(exitCode).toBe(0) + expect(stripAnsi(output)).toMatchSnapshot('show-packages-details') +})