Skip to content

Inconsistent output of pnpm licenses with multiple package versions #7224

@digilist

Description

@digilist

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

No response

Which area(s) of pnpm are affected? (leave empty if unsure)

CLI

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

Create a new project with the following monorepo setup:

Patch
diff --git a/package-a/package.json b/package-a/package.json
new file mode 100644
index 0000000..deecff5
--- /dev/null
+++ b/package-a/package.json
@@ -0,0 +1,9 @@
+{
+    "name": "package-a",
+    "private": true,
+    "version": "0.1.0",
+    "dependencies": {
+      "boxen": "7.0.2"
+    }
+  }
+  
\ No newline at end of file
diff --git a/package-b/package.json b/package-b/package.json
new file mode 100644
index 0000000..3d13dc3
--- /dev/null
+++ b/package-b/package.json
@@ -0,0 +1,9 @@
+{
+    "name": "package-b",
+    "private": true,
+    "version": "0.1.0",
+    "dependencies": {
+      "boxen": "5.1.2"
+    }
+  }
+  
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..99503d3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+    "name": "test-project",
+    "private": true,
+    "version": "0.1.0",
+    "workspaces": {
+      "packages": [
+        "package-a",
+        "package-b"
+      ]
+    },
+    "dependencies": {}
+  }
+  
\ No newline at end of file
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..e1648ce
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+packages:
+    - package-a
+    - package-b

Describe the Bug

In case of multiple package versions, pnpm licenses only shows the info for one package and version.

When using the example given in the reproduction steps above, you get the following output with pnpm licenses list --json:

Licenses JSON
{
  "ISC": [
    {
      "name": "ansi-align",
      "version": "3.0.1",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/ansi-align@3.0.1/node_modules/ansi-align",
      "license": "ISC",
      "author": "nexdrew",
      "homepage": "https://github.com/nexdrew/ansi-align#readme",
      "description": "align-text with ANSI support for CLIs"
    }
  ],
  "MIT": [
    {
      "name": "ansi-regex",
      "version": "5.0.1",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/ansi-regex@5.0.1/node_modules/ansi-regex",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/chalk/ansi-regex#readme",
      "description": "Regular expression for matching ANSI escape codes"
    },
    {
      "name": "ansi-styles",
      "version": "4.3.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/ansi-styles@4.3.0/node_modules/ansi-styles",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/chalk/ansi-styles#readme",
      "description": "ANSI escape codes for styling strings in the terminal"
    },
    {
      "name": "boxen",
      "version": "5.1.2",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/boxen@5.1.2/node_modules/boxen",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/boxen#readme",
      "description": "Create boxes in the terminal"
    },
    {
      "name": "camelcase",
      "version": "6.3.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/camelcase@6.3.0/node_modules/camelcase",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/camelcase#readme",
      "description": "Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: `foo-bar` → `fooBar`"
    },
    {
      "name": "chalk",
      "version": "4.1.2",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/chalk@4.1.2/node_modules/chalk",
      "license": "MIT",
      "homepage": "https://github.com/chalk/chalk#readme",
      "description": "Terminal string styling done right"
    },
    {
      "name": "cli-boxes",
      "version": "2.2.1",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/cli-boxes@2.2.1/node_modules/cli-boxes",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/cli-boxes#readme",
      "description": "Boxes for use in the terminal"
    },
    {
      "name": "color-convert",
      "version": "2.0.1",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/color-convert@2.0.1/node_modules/color-convert",
      "license": "MIT",
      "author": "Heather Arthur",
      "homepage": "https://github.com/Qix-/color-convert#readme",
      "description": "Plain color conversion functions"
    },
    {
      "name": "color-name",
      "version": "1.1.4",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/color-name@1.1.4/node_modules/color-name",
      "license": "MIT",
      "author": "DY",
      "homepage": "https://github.com/colorjs/color-name",
      "description": "A list of color names and its values"
    },
    {
      "name": "eastasianwidth",
      "version": "0.2.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/eastasianwidth@0.2.0/node_modules/eastasianwidth",
      "license": "MIT",
      "author": "Masaki Komagata",
      "homepage": "https://github.com/komagata/eastasianwidth#readme",
      "description": "Get East Asian Width from a character."
    },
    {
      "name": "emoji-regex",
      "version": "8.0.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/emoji-regex@8.0.0/node_modules/emoji-regex",
      "license": "MIT",
      "author": "Mathias Bynens",
      "homepage": "https://mths.be/emoji-regex",
      "description": "A regular expression to match all Emoji-only symbols as per the Unicode Standard."
    },
    {
      "name": "has-flag",
      "version": "4.0.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/has-flag@4.0.0/node_modules/has-flag",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/has-flag#readme",
      "description": "Check if argv has a specific flag"
    },
    {
      "name": "is-fullwidth-code-point",
      "version": "3.0.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/is-fullwidth-code-point@3.0.0/node_modules/is-fullwidth-code-point",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/is-fullwidth-code-point#readme",
      "description": "Check if the character represented by a given Unicode code point is fullwidth"
    },
    {
      "name": "string-width",
      "version": "4.2.3",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/string-width@4.2.3/node_modules/string-width",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/string-width#readme",
      "description": "Get the visual width of a string - the number of columns required to display it"
    },
    {
      "name": "strip-ansi",
      "version": "6.0.1",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/strip-ansi@6.0.1/node_modules/strip-ansi",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/chalk/strip-ansi#readme",
      "description": "Strip ANSI escape codes from a string"
    },
    {
      "name": "supports-color",
      "version": "7.2.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/chalk/supports-color#readme",
      "description": "Detect whether a terminal supports color"
    },
    {
      "name": "widest-line",
      "version": "3.1.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/widest-line@3.1.0/node_modules/widest-line",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/widest-line#readme",
      "description": "Get the visual width of the widest line in a string - the number of columns required to display it"
    },
    {
      "name": "wrap-ansi",
      "version": "7.0.0",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/wrap-ansi@7.0.0/node_modules/wrap-ansi",
      "license": "MIT",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/chalk/wrap-ansi#readme",
      "description": "Wordwrap a string with ANSI escape codes"
    }
  ],
  "(MIT OR CC0-1.0)": [
    {
      "name": "type-fest",
      "version": "0.20.2",
      "path": "/home/markus/Projects/urbyo/pnpm-licenses-bug-reproducer/node_modules/.pnpm/type-fest@0.20.2/node_modules/type-fest",
      "license": "(MIT OR CC0-1.0)",
      "author": "Sindre Sorhus",
      "homepage": "https://github.com/sindresorhus/type-fest#readme",
      "description": "A collection of essential TypeScript types"
    }
  ]
}

As you can see, the root dependency boxen is only listed with one version, even though there are two different versions. The same effect can be observed for sub-dependencies. For example, the camelcase package is installed with two different versions, but only one is listed in the license part.

In addition to this, I noticed that the pnpm licenses output is not entirely deterministic (even though we are using a pnpm-lock file). I wasn't able to create a reproducable example, but in our internal project the output is different after each pnpm install execution and one of the dependency versions is selected (kind of) randomly. This applies to the root dependencies as well as to sub dependencies. One time camelcase v6.3.0 is emitted in the license list / json, sometimes camelcase v7.0.1.

Expected Behavior

I would expect that all packages and versions are emitted in the license output, since licenses could change between package versions. I also would expect that the output is deterministic and does not change which version is emitted.

Which Node.js version are you using?

20.0.8

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

Arch Linux, Ubuntu, Alpine

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions