mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-28 00:17:17 -04:00
fix(license-scanner): use deterministic version for each dependency (#7500)
This commit is contained in:
5
.changeset/silent-berries-cry.md
Normal file
5
.changeset/silent-berries-cry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/license-scanner": patch
|
||||
---
|
||||
|
||||
Output license information for a deterministic version when multiple versions of a single package are depended on
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -5203,6 +5203,9 @@ importers:
|
||||
ramda:
|
||||
specifier: npm:@pnpm/ramda@0.28.1
|
||||
version: /@pnpm/ramda@0.28.1
|
||||
semver:
|
||||
specifier: ^7.5.4
|
||||
version: 7.5.4
|
||||
devDependencies:
|
||||
'@pnpm/constants':
|
||||
specifier: workspace:*
|
||||
@@ -5213,6 +5216,9 @@ importers:
|
||||
'@types/ramda':
|
||||
specifier: 0.28.20
|
||||
version: 0.28.20
|
||||
'@types/semver':
|
||||
specifier: ^7.5.3
|
||||
version: 7.5.3
|
||||
|
||||
reviewing/list:
|
||||
dependencies:
|
||||
@@ -11385,6 +11391,7 @@ packages:
|
||||
|
||||
/err-code@2.0.3:
|
||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/error-ex@1.3.2:
|
||||
@@ -17899,6 +17906,7 @@ time:
|
||||
/@pnpm/which@3.0.1: '2023-05-14T22:08:27.551Z'
|
||||
/@reflink/reflink@0.1.16: '2024-01-02T17:41:22.200Z'
|
||||
/@types/byline@4.2.36: '2023-11-07T00:13:37.410Z'
|
||||
/@types/semver@7.5.3: '2023-09-25T14:19:37.089Z'
|
||||
/@types/table@6.0.0: '2020-09-17T17:56:44.787Z'
|
||||
/@yarnpkg/core@4.0.2: '2023-11-14T09:21:22.875Z'
|
||||
/@yarnpkg/extensions@2.0.0: '2023-10-22T16:50:53.141Z'
|
||||
@@ -17911,3 +17919,4 @@ time:
|
||||
/fuse-native@2.2.6: '2020-06-03T19:26:36.838Z'
|
||||
/node-gyp@9.4.1: '2023-10-27T17:30:56.146Z'
|
||||
/safe-execa@0.1.2: '2022-07-18T01:09:17.517Z'
|
||||
/semver@7.5.4: '2023-07-07T21:10:32.589Z'
|
||||
|
||||
@@ -47,12 +47,14 @@
|
||||
"load-json-file": "^6.2.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"path-absolute": "^1.0.1",
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1"
|
||||
"ramda": "npm:@pnpm/ramda@0.28.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pnpm/constants": "workspace:*",
|
||||
"@pnpm/license-scanner": "workspace:*",
|
||||
"@types/ramda": "0.28.20"
|
||||
"@types/ramda": "0.28.20",
|
||||
"@types/semver": "^7.5.3"
|
||||
},
|
||||
"funding": "https://opencollective.com/pnpm",
|
||||
"exports": {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
type LicenseNode,
|
||||
lockfileToLicenseNodeTree,
|
||||
} from './lockfileToLicenseNodeTree'
|
||||
import { gt } from 'semver'
|
||||
|
||||
export interface LicensePackage {
|
||||
belongsTo: DependenciesField
|
||||
@@ -101,7 +102,15 @@ export async function findDependencyLicenses (opts: {
|
||||
const dependenciesOfNode = getDependenciesFromLicenseNode(licenseNode)
|
||||
|
||||
dependenciesOfNode.forEach((dependencyNode) => {
|
||||
licensePackages.set(dependencyNode.name, dependencyNode)
|
||||
const existingVersion = licensePackages.get(dependencyNode.name)?.version
|
||||
// This just ensures that we use a deterministic version of each dependency,
|
||||
// in the event that multiple versions are depended on.
|
||||
if (
|
||||
existingVersion === undefined ||
|
||||
gt(dependencyNode.version, existingVersion)
|
||||
) {
|
||||
licensePackages.set(dependencyNode.name, dependencyNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -174,4 +174,103 @@ describe('licences', () => {
|
||||
},
|
||||
] as LicensePackage[])
|
||||
})
|
||||
|
||||
test('findDependencyLicenses uses most updated version of each package', async () => {
|
||||
const lockfile: Lockfile = {
|
||||
importers: {
|
||||
'.': {
|
||||
dependencies: {
|
||||
foo: '1.0.0',
|
||||
bar: '1.0.1',
|
||||
baz: '2.0.0',
|
||||
},
|
||||
specifiers: {
|
||||
foo: '^1.0.0',
|
||||
bar: '^1.0.1',
|
||||
baz: '^2.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
lockfileVersion: LOCKFILE_VERSION,
|
||||
packages: {
|
||||
'/bar@1.0.1': {
|
||||
resolution: {
|
||||
integrity: 'bar1-integrity',
|
||||
},
|
||||
},
|
||||
'/bar@1.0.0': {
|
||||
resolution: {
|
||||
integrity: 'bar2-integrity',
|
||||
},
|
||||
},
|
||||
'/baz@2.0.1': {
|
||||
resolution: {
|
||||
integrity: 'baz1-integrity',
|
||||
},
|
||||
},
|
||||
'/baz@2.0.0': {
|
||||
resolution: {
|
||||
integrity: 'baz2-integrity',
|
||||
},
|
||||
},
|
||||
'/foo@1.0.0': {
|
||||
dependencies: {
|
||||
bar: '1.0.0',
|
||||
baz: '2.0.1',
|
||||
},
|
||||
resolution: {
|
||||
integrity: 'foo-integrity',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const licensePackages = await findDependencyLicenses({
|
||||
lockfileDir: '/opt/pnpm',
|
||||
manifest: {} as ProjectManifest,
|
||||
virtualStoreDir: '/.pnpm',
|
||||
registries: {} as Registries,
|
||||
wantedLockfile: lockfile,
|
||||
storeDir: '/opt/.pnpm',
|
||||
})
|
||||
|
||||
expect(licensePackages).toEqual([
|
||||
{
|
||||
belongsTo: 'dependencies',
|
||||
description: 'Package Description',
|
||||
version: '1.0.1',
|
||||
name: 'bar',
|
||||
license: 'MIT',
|
||||
licenseContents: undefined,
|
||||
author: 'Package Author',
|
||||
homepage: 'Homepage',
|
||||
repository: 'Repository',
|
||||
path: '/path/to/package/bar@1.0.1/node_modules',
|
||||
},
|
||||
{
|
||||
belongsTo: 'dependencies',
|
||||
description: 'Package Description',
|
||||
version: '2.0.1',
|
||||
name: 'baz',
|
||||
license: 'Unknown',
|
||||
licenseContents: 'The MIT License',
|
||||
author: 'Package Author',
|
||||
homepage: 'Homepage',
|
||||
repository: 'Repository',
|
||||
path: '/path/to/package/baz@2.0.1/node_modules',
|
||||
},
|
||||
{
|
||||
belongsTo: 'dependencies',
|
||||
description: 'Package Description',
|
||||
version: '1.0.0',
|
||||
name: 'foo',
|
||||
license: 'Unknown',
|
||||
licenseContents: 'The MIT License',
|
||||
author: 'Package Author',
|
||||
homepage: 'Homepage',
|
||||
repository: 'Repository',
|
||||
path: '/path/to/package/foo@1.0.0/node_modules',
|
||||
},
|
||||
] as LicensePackage[])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -64,7 +64,7 @@ exports[`pnpm licenses: should correctly read LICENSE file with executable file
|
||||
│ │ │ https://github.com/feross/safe-buffer │
|
||||
├──────────────────────────────┼─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ string_decoder │ MIT │ The string_decoder module from Node core │
|
||||
│ │ │ https://github.com/rvagg/string_decoder │
|
||||
│ │ │ https://github.com/nodejs/string_decoder │
|
||||
├──────────────────────────────┼─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||
│ string.fromcodepoint │ MIT │ Mathias Bynens │
|
||||
│ │ │ A robust & optimized \`String.fromCodePoint\` polyfill, based on the ECMAScript 6 specification. │
|
||||
|
||||
Reference in New Issue
Block a user