diff --git a/README.md b/README.md
index fa63ce4..648e560 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,79 @@
- [Debugging](#debugging)
- [How Licenses are Found](#how-licenses-are-found)
- [Related information sources on the internet](#related-information-sources-on-the-internet)
-
+<<< clarifications-semver
+326
+
+`version` can either be an exact version or a semver range, multiple ranges are supported for a single package, for example:
+327
+
+
+328
+
+```json5
+329
+
+{
+330
+
+ "package_name@^1": {
+331
+
+ // Any field available in customFormat can be clarified
+332
+
+ "licenses": "GPL",
+333
+
+ // ... other fields, see above
+334
+
+ },
+335
+
+ "package_name@^2": {
+336
+
+ // Any field available in customFormat can be clarified
+337
+
+ "licenses": "MIT",
+338
+
+ // ... other fields, see above
+339
+
+ },
+340
+
+}
+341
+
+```
+342
+
+
+343
+
+For overlapping ranges, the first matching entry is used.
+344
+
+
+345
+
+The `--clarificationsMatchAll` option, when enabled, raises an error if not all specified clarifications were used, it is off by default.
+346
+
+
+347
+
+
+348
+
+
+349
+
+#
## A message from the maintainer
Folks, I love and honor open software (the latter not as much as I should), and therefore I am a little ashamed of the lack of regular care I give to this project. My family (two still young kids and a wife working full-time just as me) plus my hobbies (reading - currently I read the great book "Coders at work" and plan to work my way through "Structure and interpretation of computer programs", a book many great and experienced coders say is kind of a must-read - and homebrewing) take their toll. And then there's the time I need for procrastination as well. You get the picture.
@@ -249,6 +321,7 @@ before.
- `--angularCli` is just a synonym for `--plainVertical`
- `--clarificationsFile [filepath]` A file that describe the license clarifications for each package, see clarificationExample.json, any field available to the customFormat option can be clarified. The clarifications file can also be used to specify a subregion of a package's license file (instead reading the entire file)
+- `--clarificationsMatchAll [boolean]` This optional new feature is still lacking a description - to be done
- `--csv` output in csv format
- `--csvComponentPrefix` prefix column for component in csv format
- `--customPath` to add a custom Format file in JSON
@@ -322,7 +395,30 @@ The `--clarificationsFile` option can be used to provide custom processing instr
}
```
-## Custom format
+`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
The `--customPath` option can be used with CSV to specify the columns. Note that
the first column, `module_name`, will always be used.
diff --git a/lib/args.js b/lib/args.js
index bc90219..e9b696e 100644
--- a/lib/args.js
+++ b/lib/args.js
@@ -10,7 +10,8 @@ import path from 'node:path';
const knownOptions = {
angularCli: Boolean,
- clarificationsFile: path,
+ clarificationsFile: path,clarificationsMatchAll
+ clarificationsMatchAll: Boolean,
color: Boolean,
csv: Boolean,
csvComponentPrefix: String,
diff --git a/lib/index.js b/lib/index.js
index 33ccb50..51cf51f 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -20,6 +20,7 @@ import spdxCorrect from 'spdx-correct';
import spdxSatisfies from 'spdx-satisfies';
import treeify from 'treeify';
import { createHash } from 'crypto';
+import semver from 'semver';
import * as licenseCheckerHelpers from './licenseCheckerHelpers.js';
import { getLicenseTitle } from './getLicenseTitle.js';
@@ -45,8 +46,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.
@@ -133,7 +139,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) => {
@@ -393,10 +399,21 @@ const 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 = parseJson(args.clarificationsFile);
+ const clarificationsFromFile = 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) {
@@ -432,7 +449,25 @@ const 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