From c019f8fffccfa9ac23ec2a903a94a86e7b72377b Mon Sep 17 00:00:00 2001 From: ol Date: Tue, 27 Feb 2024 11:44:58 +0100 Subject: [PATCH 1/2] allow specifying ranges in clarifications file and add strict usage checking for them --- lib/args.js | 1 + lib/index.js | 45 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/args.js b/lib/args.js index b07fde2..a9b3d04 100644 --- a/lib/args.js +++ b/lib/args.js @@ -9,6 +9,7 @@ const chalk = require('chalk'); const knownOptions = { angularCli: Boolean, clarificationsFile: require('path'), + clarificationsMatchAll: Boolean, color: Boolean, csv: Boolean, csvComponentPrefix: String, diff --git a/lib/index.js b/lib/index.js index 82dbd20..797d946 100644 --- a/lib/index.js +++ b/lib/index.js @@ -20,6 +20,7 @@ const spdxCorrect = require('spdx-correct'); const spdxSatisfies = require('spdx-satisfies'); const treeify = require('treeify'); const createHash = require('crypto').createHash; +const semver = require('semver'); const getLicenseTitle = require('./getLicenseTitle'); const licenseFiles = require('./license-files'); @@ -44,8 +45,13 @@ const recursivelyCollectAllDependencies = (options) => { let licenseData; let licenseFile; let noticeFiles = []; - let clarification = options.clarifications?.[currentPackageNameAndVersion]; + const clarification = options.clarifications[currentExtendedPackageJson.name]?.find((clarification) => + currentExtendedPackageJson.version == clarification.semverRange || semver.satisfies(currentExtendedPackageJson.version, clarification.semverRange) + ); let passedClarificationCheck = clarification?.checksum ? false : true; + if (clarification) { + clarification.used = true; + } if ( // If we have processed this currentPackageNameAndVersion already, just return the data object. @@ -132,7 +138,7 @@ const recursivelyCollectAllDependencies = (options) => { ); if (licenseData) { - // License information has been collected from either the clarifiation file or from the package.json file + // License information has been collected from either the clarification file or from the package.json file /*istanbul ignore else*/ if (Array.isArray(licenseData) && licenseData.length > 0) { moduleInfo.licenses = licenseData.map((moduleLicense) => { @@ -392,10 +398,21 @@ exports.init = function init(args, callback) { pusher = toCheckforFailOn; } - // An object mapping from Package name -> What contents it should have + // An object mapping from Package name -> list of what contents it should have, including a semver range for each entry let clarifications = {}; if (args.clarificationsFile) { - clarifications = exports.parseJson(args.clarificationsFile); + const clarificationsFromFile = exports.parseJson(args.clarificationsFile); + + for (const [versionString, clarification] of Object.entries(clarificationsFromFile)) { + const versionSplit = versionString.lastIndexOf('@'); + if (versionSplit !== -1) { + const name = versionString.slice(0, versionSplit); + const semverRange = versionString.slice(versionSplit + 1); + clarifications[name] ??= []; + // keep track for each clarification if it was used, optionally error when not + clarifications[name].push({...clarification, semverRange, used: false}); + } + } } if (checker && pusher) { @@ -431,7 +448,25 @@ exports.init = function init(args, callback) { unknown: args.unknown, currentRecursionDepth: 0, clarifications, - }); + }) + + if (args.clarificationsMatchAll) { + const unusedClarifications = [] + for (const [package, entries] of Object.entries(clarifications)) { + for (const clarification of entries) { + if (!clarification.used) { + unusedClarifications.push(`${package}@${clarification.semverRange}`); + } + } + } + if (unusedClarifications.length) { + console.error( + `Some clarifications (${unusedClarifications.join(', ')}) were unused and --clarificationsMatchAll was specified. Exiting.`, + ); + + process.exit(1); + } + } const colorize = args.color; const sorted = {}; // 'sorted' will store the same items as allWantedDepthDependenciesWithVersions, but sorted by package name and version From 4b6ac3637463b92f53a24fb33c24743392afba9a Mon Sep 17 00:00:00 2001 From: ol Date: Tue, 27 Feb 2024 13:11:57 +0100 Subject: [PATCH 2/2] document clarifications file semver ranges --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 1d0ad8c..8389682 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,27 @@ The `--clarificationsFile` option can be used to provide custom processing instr } ``` +`version` can either be an exact version or a semver range, multiple ranges are supported for a single package, for example: + +```json5 +{ + "package_name@^1": { + // Any field available in customFormat can be clarified + "licenses": "GPL", + // ... other fields, see above + }, + "package_name@^2": { + // Any field available in customFormat can be clarified + "licenses": "MIT", + // ... other fields, see above + }, +} +``` + +For overlapping ranges, the first matching entry is used. + +The `--clarificationsMatchAll` option, when enabled, raises an error if not all specified clarifications were used, it is off by default. + ## Custom format