fix(license-scanner): use deterministic version for each dependency (#7500)

This commit is contained in:
Eric Higgins
2024-01-09 14:40:13 -08:00
committed by GitHub
parent 27a96a8a8d
commit 03417eeefb
6 changed files with 128 additions and 4 deletions

View 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
View File

@@ -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'

View File

@@ -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": {

View File

@@ -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)
}
})
}

View File

@@ -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[])
})
})

View File

@@ -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. │