mirror of https://github.com/mifi/lossless-cut
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { execa } from 'execa';
|
|
|
|
const { stdout } = await execa('yarn', ['licenses', 'list', '-R', '--json'], { encoding: 'utf8' });
|
|
|
|
const licensesJson: { value: string; children: Record<string, unknown> }[] = JSON.parse(`[${stdout.split('\n').join(',')}]`);
|
|
|
|
const safeLicenses: Record<string, true | string[]> = {
|
|
// These aim to remove almost all restrictions
|
|
'CC0-1.0': true,
|
|
Unlicense: true,
|
|
WTFPL: true,
|
|
'0BSD': true,
|
|
|
|
// Permissive licenses: These impose minimal requirements (mostly attribution + license notice). You can generally use them interchangeably in commercial and proprietary software.
|
|
MIT: true,
|
|
'BSD-2-Clause': true,
|
|
'BSD-3-Clause': true,
|
|
ISC: true,
|
|
Zlib: true,
|
|
'Python-2.0': true,
|
|
'BlueOak-1.0.0': true,
|
|
'MIT/X11': true,
|
|
|
|
// Permissive licenses with some conditions
|
|
'Apache-2.0': true,
|
|
|
|
// Copyleft licenses: These require that derivative works be distributed under the same license terms. They ensure that modifications remain open source.
|
|
// which is OK because LosslessCut is also GPL-2.0-only
|
|
'GPL-2.0-only': ['lossless-cut'],
|
|
// Weak copyleft licenses: These allow linking with proprietary software under certain conditions, making them more flexible than strong copyleft licenses.
|
|
'LGPL-3.0-only': true,
|
|
'LGPL-3.0-or-later': true,
|
|
'MPL-2.0': true,
|
|
|
|
// Special purpose licenses
|
|
'Hippocratic-2.1': ['@react-leaflet/core', 'react-leaflet'],
|
|
|
|
// not software licenses
|
|
'CC-BY-3.0': ['spdx-exceptions'], // eslint-plugin-unicorn
|
|
'CC-BY-4.0': ['caniuse-lite'],
|
|
|
|
// Font licenses
|
|
'OFL-1.1': true, // permissive
|
|
|
|
UNKNOWN: ['fast-shallow-equal', 'react-universal-interface', 'buffers'],
|
|
};
|
|
|
|
const unsafeLicenses = licensesJson.flatMap((l) => {
|
|
const checkLicense = (license: string) => {
|
|
const safeLicense = safeLicenses[license];
|
|
if (safeLicense === true) {
|
|
return true;
|
|
}
|
|
if (safeLicense == null) {
|
|
return false;
|
|
}
|
|
return Object.keys(l.children).every((pkg) => (
|
|
safeLicense.some((safeLicensePackage) => pkg.startsWith(safeLicensePackage))
|
|
));
|
|
};
|
|
|
|
// e.g. "(BSD-2-Clause OR MIT OR Apache-2.0)"
|
|
// e.g. "(LGPL-3.0-only AND MIT)"
|
|
const trimmed = l.value.replace(/^\(/, '').replace(/\)$/, '');
|
|
|
|
const isOr = l.value.includes(' OR ');
|
|
const isAnd = l.value.includes(' AND ');
|
|
|
|
if (isOr || isAnd) {
|
|
const licenses = trimmed.split(isOr ? ' OR ' : ' AND ').map((s) => s.trim());
|
|
|
|
if (isOr) {
|
|
return licenses.some((license) => checkLicense(license)) ? [] : [l];
|
|
}
|
|
if (isAnd) {
|
|
return licenses.every((license) => checkLicense(license)) ? [] : [l];
|
|
}
|
|
}
|
|
|
|
return checkLicense(trimmed) ? [] : [l];
|
|
});
|
|
|
|
|
|
if (unsafeLicenses.length > 0) {
|
|
console.error('Found unsafe licenses:');
|
|
console.error();
|
|
|
|
for (const l of unsafeLicenses) {
|
|
console.error(l.value);
|
|
console.error(`${Object.keys(l.children).map((v) => `- ${v}`).join('\n')}`);
|
|
console.error();
|
|
}
|
|
process.exitCode = 1;
|
|
} else {
|
|
console.log('All licenses are safe.');
|
|
}
|