2019-07-16 12:22:12 -04:00
|
|
|
#!/usr/bin/env node
|
|
|
|
/*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
* or more contributor license agreements. See the NOTICE file
|
|
|
|
* distributed with this work for additional information
|
|
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
|
|
* to you under the Apache License, Version 2.0 (the
|
|
|
|
* "License"); you may not use this file except in compliance
|
|
|
|
* with the License. You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
const checker = require('license-checker');
|
|
|
|
|
|
|
|
const LICENSES_FILE = '../licenses.yaml';
|
|
|
|
const START_MARKER_LINE = '# Web console modules start';
|
|
|
|
const END_MARKER_LINE = '# Web console modules end';
|
|
|
|
const SEPARATOR = '\n\n---\n\n';
|
|
|
|
|
2021-04-16 23:15:19 -04:00
|
|
|
const extraLinesForLib = {};
|
2019-11-15 22:45:14 -05:00
|
|
|
|
2020-10-21 01:11:29 -04:00
|
|
|
const extraPackages = {
|
|
|
|
// This is a OSS font so it is not listed by the npm scraper but we still want to attribute it so pretend to inject it
|
|
|
|
// as a phantom package
|
|
|
|
'opensans@1.101.0': {
|
|
|
|
licenses: 'Apache-2.0',
|
|
|
|
repository: 'https://github.com/google/fonts/tree/master/apache/opensans',
|
|
|
|
publisher: 'Google',
|
|
|
|
url: 'https://fonts.google.com/specimen/Open+Sans',
|
2021-04-16 23:15:19 -04:00
|
|
|
},
|
|
|
|
};
|
2020-10-21 01:11:29 -04:00
|
|
|
|
2019-07-16 12:22:12 -04:00
|
|
|
function injectConsoleLicenses(consoleLicenses) {
|
|
|
|
const text = fs.readFileSync(LICENSES_FILE, 'utf-8');
|
|
|
|
const textLines = text.split('\n');
|
|
|
|
|
|
|
|
// Extract the license for the file itself
|
|
|
|
let beforeLines = [];
|
|
|
|
let afterLines = [];
|
|
|
|
let state = 'before';
|
|
|
|
for (let textLine of textLines) {
|
|
|
|
switch (state) {
|
|
|
|
case 'before':
|
|
|
|
beforeLines.push(textLine);
|
|
|
|
if (textLine === START_MARKER_LINE) {
|
|
|
|
state = 'main';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'main':
|
|
|
|
if (textLine === END_MARKER_LINE) {
|
|
|
|
state = 'after';
|
|
|
|
afterLines.push(textLine);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'after':
|
|
|
|
afterLines.push(textLine);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (state === 'before') throw new Error(`missing starter marker '${START_MARKER_LINE}'`);
|
|
|
|
if (state === 'main') throw new Error(`missing ending marker '${END_MARKER_LINE}'`);
|
|
|
|
|
|
|
|
// Write out the new file
|
|
|
|
fs.writeFileSync(
|
|
|
|
LICENSES_FILE,
|
2019-08-20 23:40:47 -04:00
|
|
|
[beforeLines.join('\n'), consoleLicenses.join(SEPARATOR), afterLines.join('\n')].join('\n'),
|
2019-07-16 12:22:12 -04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
checker.init(
|
|
|
|
{
|
|
|
|
start: '.',
|
|
|
|
production: true,
|
|
|
|
},
|
2021-04-16 23:15:19 -04:00
|
|
|
function (err, packages) {
|
2019-08-20 23:40:47 -04:00
|
|
|
if (err) {
|
|
|
|
console.log('err', err);
|
|
|
|
return;
|
2019-07-16 12:22:12 -04:00
|
|
|
}
|
|
|
|
|
2020-10-21 01:11:29 -04:00
|
|
|
Object.assign(packages, extraPackages);
|
|
|
|
|
2019-11-15 22:45:14 -05:00
|
|
|
const seen = {};
|
2019-08-20 23:40:47 -04:00
|
|
|
const mapped = Object.keys(packages)
|
|
|
|
.sort()
|
|
|
|
.map(p => {
|
|
|
|
const m = p.match(/^(.+)@(\d+\.\d+\.\d+.*)$/);
|
|
|
|
if (!m) throw new Error(`Malformed name@version`);
|
|
|
|
const name = m[1];
|
2019-11-15 22:45:14 -05:00
|
|
|
if (name === 'web-console') return; // This is me!
|
|
|
|
if (seen[name]) return; // Dedupe
|
|
|
|
seen[name] = true;
|
2019-08-20 23:40:47 -04:00
|
|
|
|
|
|
|
const version = m[2];
|
|
|
|
const meta = packages[p];
|
|
|
|
let { publisher, licenses, licenseFile } = meta;
|
|
|
|
if (!licenses) throw new Error(`Package '${p} does not have a licenses`);
|
|
|
|
|
|
|
|
let properLicenseName; // Map the licenses to their proper name
|
|
|
|
let licenseExt; // Map the licenses to the right extension
|
|
|
|
switch (licenses) {
|
|
|
|
case 'MIT':
|
|
|
|
properLicenseName = 'MIT License';
|
|
|
|
licenseExt = 'MIT';
|
|
|
|
break;
|
|
|
|
|
2021-12-22 19:31:17 -05:00
|
|
|
case 'ISC':
|
|
|
|
properLicenseName = 'ISC License';
|
|
|
|
licenseExt = 'ISC';
|
|
|
|
break;
|
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
case 'Apache-2.0':
|
|
|
|
properLicenseName = 'Apache License version 2.0';
|
|
|
|
licenseExt = 'A2';
|
|
|
|
break;
|
|
|
|
|
2021-12-22 19:31:17 -05:00
|
|
|
case 'BSD-2-Clause':
|
|
|
|
properLicenseName = 'BSD-2-Clause License';
|
|
|
|
licenseExt = 'BSD2';
|
|
|
|
break;
|
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
case 'BSD-3-Clause':
|
|
|
|
properLicenseName = 'BSD-3-Clause License';
|
|
|
|
licenseExt = 'BSD3';
|
|
|
|
break;
|
|
|
|
|
2021-04-16 23:15:19 -04:00
|
|
|
case '0BSD':
|
|
|
|
properLicenseName = 'Zero-Clause BSD';
|
|
|
|
licenseExt = '0BSD';
|
|
|
|
break;
|
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
default:
|
|
|
|
throw new Error(`Unknown license '${licenses}' in ${p}`);
|
2019-07-16 12:22:12 -04:00
|
|
|
}
|
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
const simpleName = name.replace('/', '-');
|
|
|
|
const licenseDest = `licenses/bin/${simpleName}.${licenseExt}`;
|
|
|
|
|
|
|
|
let hasLicense = false;
|
|
|
|
if (licenseExt !== 'A2') {
|
|
|
|
if (licenseFile && licenseFile.match(/\/license(?:\.\w+)?/i)) {
|
|
|
|
// If the file ends with license.ext? then copy it over
|
|
|
|
try {
|
|
|
|
fs.copyFileSync(licenseFile, `../${licenseDest}`);
|
|
|
|
hasLicense = true;
|
|
|
|
} catch (e) {
|
|
|
|
console.log(`Could not copy license for '${p}': ${JSON.stringify(meta)}`);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// See if the license is already there (manually) keep it
|
|
|
|
try {
|
|
|
|
fs.statSync(`../${licenseDest}`);
|
|
|
|
hasLicense = true;
|
|
|
|
} catch (e) {
|
|
|
|
console.log(`Could not find license for '${p}': ${JSON.stringify(meta)}`);
|
2022-04-04 13:34:22 -04:00
|
|
|
console.log(`Find and copy the package's license file to '../${licenseDest}'`);
|
2019-08-20 23:40:47 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-16 12:22:12 -04:00
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
if (!publisher && hasLicense) {
|
|
|
|
// Extract copyright from license
|
|
|
|
const licenseText = fs.readFileSync(`../${licenseDest}`, 'utf-8');
|
|
|
|
const m = licenseText.match(
|
|
|
|
/(?:^|\n)\s*Copyright(?: (?:\(c\)|©))?(?: 2[0-9]{3}(?:-\w+)?,?)? ([^0-9][^\n]*)\n/m,
|
|
|
|
);
|
|
|
|
if (m) {
|
|
|
|
publisher = m[1]
|
|
|
|
.replace(/All rights reserved./i, '')
|
|
|
|
.replace(/[0-9-]{4,9}/, '')
|
|
|
|
.trim();
|
|
|
|
}
|
|
|
|
}
|
2019-07-16 12:22:12 -04:00
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
if (!publisher) {
|
|
|
|
// Hand coded copyrights
|
|
|
|
if (name === 'asap') publisher = 'Contributors';
|
|
|
|
if (name === 'diff-match-patch') publisher = 'Google';
|
2021-12-22 19:31:17 -05:00
|
|
|
if (name === 'esutils') publisher = 'Yusuke Suzuki'; // https://github.com/estools/esutils#license
|
2019-08-20 23:40:47 -04:00
|
|
|
}
|
2019-07-16 12:22:12 -04:00
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
if (!publisher) {
|
|
|
|
console.log(`No license for '${name}' ('${licenseDest}')`);
|
|
|
|
}
|
2019-07-16 12:22:12 -04:00
|
|
|
|
2019-08-20 23:40:47 -04:00
|
|
|
// Make our blob
|
|
|
|
const lines = [
|
|
|
|
`name: "${name}"`,
|
|
|
|
`license_category: binary`,
|
|
|
|
`module: web-console`,
|
|
|
|
`license_name: ${properLicenseName}`,
|
2019-11-15 22:45:14 -05:00
|
|
|
publisher ? `copyright: ${publisher}` : undefined,
|
2019-08-20 23:40:47 -04:00
|
|
|
`version: ${version}`,
|
2019-11-15 22:45:14 -05:00
|
|
|
hasLicense ? `license_file_path: ${licenseDest}` : undefined,
|
|
|
|
extraLinesForLib[name],
|
2019-08-20 23:40:47 -04:00
|
|
|
];
|
|
|
|
|
|
|
|
return lines.filter(Boolean).join('\n');
|
|
|
|
})
|
|
|
|
.filter(Boolean);
|
|
|
|
|
|
|
|
injectConsoleLicenses(mapped);
|
|
|
|
},
|
|
|
|
);
|