Skip to content

Commit

Permalink
Merge pull request #110 from ol-teuto/clarifications-semver
Browse files Browse the repository at this point in the history
allow specifying ranges in clarifications file and add strict usage checking for them
  • Loading branch information
RSeidelsohn authored Aug 30, 2024
2 parents 501244d + 140b7f9 commit 59cc778
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 8 deletions.
100 changes: 98 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<a name="custom_format"></a>
348

349

#
## <a id="a-message-from-the-maintainer"></a>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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -322,7 +395,30 @@ The `--clarificationsFile` option can be used to provide custom processing instr
}
```

## <a id="custom_format"></a>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.

<a name="custom_format"></a>

## 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.
Expand Down
3 changes: 2 additions & 1 deletion lib/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
45 changes: 40 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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.
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 59cc778

Please sign in to comment.