@atomist/sdm
Version:
Atomist Software Delivery Machine SDK
183 lines (173 loc) • 6.78 kB
JavaScript
;
/*
* Copyright © 2020 Atomist, Inc.
*
* Licensed 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.addThirdPartyLicenseTransform = exports.addThirdPartyLicense = exports.AddThirdPartyLicenseAutofix = void 0;
const fs = require("fs-extra");
const lc = require("license-checker");
const _ = require("lodash");
const path = require("path");
const spdx = require("spdx-license-list");
const util_1 = require("util");
const StringCapturingProgressLog_1 = require("../../../api-helper/log/StringCapturingProgressLog");
const child_process_1 = require("../../../api-helper/misc/child_process");
const commonPushTests_1 = require("../../../api/mapping/support/commonPushTests");
const pushTestUtils_1 = require("../../../api/mapping/support/pushTestUtils");
const nodePushTests_1 = require("../pushtest/nodePushTests");
const LicenseMapping = {
"Apache 2.0": "Apache-2.0",
};
const LicenseFileName = "legal/THIRD_PARTY.md";
const GitattributesFileName = ".gitattributes";
const LicenseTableHeader = `| Name | Version | Publisher | Repository |
|------|---------|-----------|------------|`;
const SummaryTableHadler = `| License | Count |
|---------|-------|`;
exports.AddThirdPartyLicenseAutofix = addThirdPartyLicense(pushTestUtils_1.allSatisfied(nodePushTests_1.IsNode, commonPushTests_1.ToDefaultBranch));
function addThirdPartyLicense(pushTest) {
return {
name: "Third party licenses",
pushTest,
transform: addThirdPartyLicenseTransform(),
};
}
exports.addThirdPartyLicense = addThirdPartyLicense;
function addThirdPartyLicenseTransform() {
return async (p) => {
const cwd = p.baseDir;
const pj = JSON.parse((await fs.readFile(path.join(cwd, "package.json"))).toString());
const ownModule = `${pj.name}@${pj.version}`;
if (!(await p.hasDirectory("node_modules"))) {
const result = await child_process_1.spawnLog("npm", ["ci"], {
cwd,
log: new StringCapturingProgressLog_1.StringCapturingProgressLog(),
});
if (result && result.code !== 0) {
return p;
}
}
const json = await util_1.promisify(lc.init)({
start: cwd,
production: true,
});
const grouped = {};
_.forEach(json, (v, k) => {
if (k === ownModule) {
return;
}
let licenses = v.licenses;
if (!Array.isArray(licenses)) {
if (licenses.endsWith("*")) {
licenses = licenses.slice(0, -1);
}
if (licenses.startsWith("(") && licenses.endsWith(")")) {
licenses = licenses.slice(1, -1);
}
licenses = [...licenses.split(" OR ")];
}
licenses.forEach(l => {
let license = l;
if (LicenseMapping.hasOwnProperty(license)) {
license = LicenseMapping[license];
}
if (grouped.hasOwnProperty(license)) {
grouped[license] = [
...grouped[license],
Object.assign(Object.assign({}, v), { name: k }),
];
}
else {
grouped[license] = [
Object.assign(Object.assign({}, v), { name: k }),
];
}
});
});
const summary = [];
const counts = _.mapValues(grouped, l => l.length);
for (const l in counts) {
if (counts.hasOwnProperty(l)) {
const anchor = l
.toLocaleLowerCase()
.replace(/ /g, "-")
.replace(/\./g, "")
.replace(/:/g, "")
.replace(/\//g, "");
summary.push(`|[${l}](#${anchor})|${counts[l]}|`);
}
}
const details = [];
// tslint:disable-next-line:no-inferred-empty-object-type
_.forEach(grouped, (v, k) => {
const deps = v.map(dep => {
const ix = dep.name.lastIndexOf("@");
const name = dep.name.slice(0, ix);
const version = dep.name.slice(ix + 1);
return `|\`${name}\`|\`${version}\`|${dep.publisher ? dep.publisher : ""}|${dep.repository ? `[${dep.repository}](${dep.repository})` : ""}|`;
});
let ld = "";
if (spdx[k]) {
ld = `${spdx[k].name} - [${spdx[k].url}](${spdx[k].url})\n`;
}
details.push(`
#### ${k}
${ld}
${LicenseTableHeader}
${deps.join("\n")}`);
});
const lic = spdx[pj.license]
? `
\`${pj.name}\` is licensed under ${spdx[pj.license].name} - [${spdx[pj.license].url}](${spdx[pj.license].url}).`
: "";
const content = `# \`${pj.name}\`${lic}
This page details all runtime OSS dependencies of \`${pj.name}\`.
## Licenses
### Summary
${SummaryTableHadler}
${summary.sort((s1, s2) => s1.localeCompare(s2)).join("\n")}
${details.sort((s1, s2) => s1.localeCompare(s2)).join("\n")}
## Contact
Please send any questions or inquires to [oss@atomist.com](mailto:oss@atomist.com).
---
Created by [Atomist][atomist].
Need Help? [Join our Slack team][slack].
[atomist]: https://atomist.com/ (Atomist - Development Automation)
[slack]: https://join.atomist.com/ (Atomist Community Slack)
`;
await addGitattribute(p);
await p.deleteDirectory("node_modules");
await p.addFile(LicenseFileName, content);
return p;
};
}
exports.addThirdPartyLicenseTransform = addThirdPartyLicenseTransform;
async function addGitattribute(p) {
const attribute = `${LicenseFileName} linguist-generated=true
`;
const ga = await p.getFile(GitattributesFileName);
if (ga) {
let c = await ga.getContent();
if (!c.includes(LicenseFileName)) {
c += `
${attribute}`;
await ga.setContent(c);
}
}
else {
await p.addFile(GitattributesFileName, attribute);
}
}
//# sourceMappingURL=thirdPartyLicense.js.map