Skip to content

Commit

Permalink
feat: add license compliance check tool
Browse files Browse the repository at this point in the history
  • Loading branch information
pbredenberg committed Aug 24, 2023
1 parent fb589d9 commit 93f1035
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
12 changes: 12 additions & 0 deletions .license-checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

module.exports = {

permittedLicenses: [
'BSD-2-Clause',
'BSD-3-Clause',
'Python-2.0',
'BSD*',
]

};
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,42 @@ possible that some processes in some projects could fail when the wrong version
is enabled in the developer's environment. This helps eliminate one factor from the
equation when troubleshooting.

### License Compliance Checker Tool

This project contains a tool to verify that the licenses used by libraries in our
projects that contain NPM dependencies are among our list of accepted licenses. To
view the list of accepted licenses, see the `ALLOWED_LICENSES` list in:
[check-license-compliance.js](scripts/check-license-compliance.js)

To use this tool, `@silvermine/standardization` must be installed in your project:

`npm i -DE @silvermine/standardization`

You should then be able to run the tool in a NPM script:

```json
{
"scripts": {
"check-license-compliance": "check-license-compliance"
}
}
```

The tool also allows you to configure exceptions for license types using a configuration
file. To configure these exceptions, add a file called `.license-checker.js` to the root
of your project with the following contents:

```cjs
'use strict';

module.exports = {

permittedLicenses: [ 'My-Custom-License' ]

};

```

### Executing ESLint

When ESLint is needed for a project, add an `eslint` task to package.json, and execute it
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
"release:finalize": "node ./scripts/release.js finalize",
"markdownlint": "markdownlint-cli2",
"eslint": "eslint .",
"standards": "npm run commitlint && npm run eslint && npm run markdownlint"
"check-license-compliance": "node scripts/check-license-compliance.js",
"standards": "npm run commitlint && npm run check-license-compliance && npm run eslint && npm run markdownlint"
},
"bin": {
"check-license-compliance": "scripts/check-license-compliance.js"
},
"repository": {
"type": "git",
Expand Down
85 changes: 85 additions & 0 deletions scripts/check-license-compliance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#! /usr/bin/env node
'use strict';
/* eslint no-console: [ "error", { allow: [ "info", "warn", "error", "table" ] } ] */
const { init } = require('license-checker'),
process = require('process'),
util = require('util'),
initLicenseChecker = util.promisify(init),
packageDirectory = require('pkg-dir');

const DEFAULT_PERMITTED_LICENSES = [
'MIT',
'ISC',
'Apache-2.0',
'(MIT OR Apache-2.0)',
'Public Domain',
'CC-BY-3.0',
];

(async () => {
const projectDirectoryPath = await packageDirectory(),
projectConfigPath = `${projectDirectoryPath}/.license-checker.js`,
licenseRecord = {};

let configuredPermittedLicenses = [],
moduleInfoReport,
unsupportedLicenses;

console.info('Project package.json located at path:', projectDirectoryPath);

try {
// eslint-disable-next-line global-require
const config = require(projectConfigPath);

configuredPermittedLicenses = config.permittedLicenses;

console.info(`Using configured allow-list at path ${projectConfigPath}`);
console.info('Allowing additional licenses:', configuredPermittedLicenses.join(', '));
} catch(e) {
console.error(e);
console.info('A config for license checker was not provided or was not found.');
}

try {
moduleInfoReport = await initLicenseChecker({
start: process.cwd(),
});
} catch(e) {
console.error('Could not initialize license-checker', e);
process.exitCode = 1;
return;
}

Object
.keys(moduleInfoReport)
.forEach((moduleName) => {
const licenses = moduleInfoReport[moduleName].licenses;

licenseRecord[moduleName] = {
module: moduleName,
license: licenses || 'UNLICENSED',
...moduleInfoReport[moduleName],
};
});

console.info(`This project has ${Object.values(licenseRecord).length} licenses.`);

unsupportedLicenses = Object.values(licenseRecord).filter((record) => {
return !DEFAULT_PERMITTED_LICENSES.includes(record.license) && !configuredPermittedLicenses.includes(record.license);
});

if (unsupportedLicenses.length > 0) {
console.error(`${unsupportedLicenses.length} unsupported licenses found:`);

const errors = unsupportedLicenses
.map((record) => {
return {
'Module Name': record.module,
'Unsupported License': record.license,
};
});

console.table(errors);
process.exitCode = 1;
}
})();

0 comments on commit 93f1035

Please sign in to comment.