-
Notifications
You must be signed in to change notification settings - Fork 12k
/
Copy pathvalidate-licenses.ts
126 lines (111 loc) · 4.15 KB
/
validate-licenses.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { JsonObject, logging } from '@angular-devkit/core';
import * as path from 'path';
import { packages } from '../lib/packages';
// eslint-disable-next-line import/no-unassigned-import
require('../lib/bootstrap-local');
const checker = require('license-checker');
const spdxSatisfies = require('spdx-satisfies');
/**
* A general note on some black listed specific licenses:
* - CC0
* This is not a valid license. It does not grant copyright of the code/asset, and does not
* resolve patents or other licensed work. The different claims also have no standing in court
* and do not provide protection to or from Google and/or third parties.
* We cannot use nor contribute to CC0 licenses.
* - Public Domain
* Same as CC0, it is not a valid license.
*/
const allowedLicenses = [
// Regular valid open source licenses supported by Google.
'MIT',
'ISC',
'Apache-2.0',
'Python-2.0',
'Artistic-2.0',
'BlueOak-1.0.0',
'BSD-2-Clause',
'BSD-3-Clause',
'BSD-4-Clause',
// All CC-BY licenses have a full copyright grant and attribution section.
'CC-BY-3.0',
'CC-BY-4.0',
// Have a full copyright grant. Validated by opensource team.
'Unlicense',
'CC0-1.0',
'0BSD',
];
// Name variations of SPDX licenses that some packages have.
// Licenses not included in SPDX but accepted will be converted to MIT.
const licenseReplacements: { [key: string]: string } = {
// Official SPDX identifier has a dash
'Apache 2.0': 'Apache-2.0',
// BSD is BSD-2-clause by default.
'BSD': 'BSD-2-Clause',
};
// Specific packages to ignore, add a reason in a comment. Format: package-name@version.
const ignoredPackages = [
// * Broken license fields
'pako@1.0.11', // MIT but broken license in package.json
];
// Ignore own packages (all MIT)
for (const packageName of Object.keys(packages)) {
const version = packages[packageName].experimental
? '0.0.0-EXPERIMENTAL-PLACEHOLDER'
: '0.0.0-PLACEHOLDER';
ignoredPackages.push(`${packageName}@${version}`);
}
// Find all folders directly under a `node_modules` that have a package.json.
// Check if a license is accepted by an array of accepted licenses
function _passesSpdx(licenses: string[], accepted: string[]) {
try {
return spdxSatisfies(licenses.join(' AND '), accepted.join(' OR '));
} catch {
return false;
}
}
export default function (_options: {}, logger: logging.Logger): Promise<number> {
return new Promise((resolve) => {
checker.init(
{ start: path.join(__dirname, '..'), excludePrivatePackages: true },
(err: Error, json: JsonObject) => {
if (err) {
logger.fatal(`Something happened:\n${err.message}`);
resolve(1);
} else {
logger.info(`Testing ${Object.keys(json).length} packages.\n`);
// Packages with bad licenses are those that neither pass SPDX nor are ignored.
const badLicensePackages = Object.keys(json)
.map((key) => ({
id: key,
licenses: ([] as string[])
.concat((json[key] as JsonObject).licenses as string[])
// `*` is used when the license is guessed.
.map((x) => x.replace(/\*$/, ''))
.map((x) => (x in licenseReplacements ? licenseReplacements[x] : x)),
}))
.filter((pkg) => !_passesSpdx(pkg.licenses, allowedLicenses))
.filter((pkg) => !ignoredPackages.find((ignored) => ignored === pkg.id));
// Report packages with bad licenses
if (badLicensePackages.length > 0) {
logger.error('Invalid package licences found:');
badLicensePackages.forEach((pkg) => {
logger.error(`${pkg.id}: ${JSON.stringify(pkg.licenses)}`);
});
logger.fatal(`\n${badLicensePackages.length} total packages with invalid licenses.`);
resolve(2);
} else {
logger.info('All package licenses are valid.');
resolve(0);
}
}
},
);
});
}