Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an optional whitelist parameter #4

Merged
merged 1 commit into from
Aug 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ export default [

#### Options

- none, yet
- whitelist: an array or Set of SPDX license identifiers that are allowed in the
list. If provided and a non-whitelisted dependency is encountered, the transform
will reject.
22 changes: 21 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ function equalityMap() {
};
}

function flattenLicense(root) {
if (root.left) {
return [...flattenLicense(root.left), ...flattenLicense(root.right)];
} else if (root.license) {
return [root.license];
}
}

function arrayToSentence(arr) {
const separator = ", ";
const lastSeparator = " and ";
Expand Down Expand Up @@ -102,9 +110,10 @@ function groupByAuthor(modules) {
}));
}

module.exports = (options = {}) => {
module.exports = ({ whitelist } = {}) => {
const cache = new Map();
const dependencies = new Map();
const whitelistSet = new Set(whitelist);
const cwd = process.cwd();

return {
Expand Down Expand Up @@ -160,6 +169,15 @@ module.exports = (options = {}) => {
continue;
}
let parsedLicense = licenseObjects(parseSPDX(dependency.license));
if (whitelist) {
for (let license of flattenLicense(parsedLicense)) {
if (!whitelistSet.has(license)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this being conservative in the sense that every mentioned license has to be whitelisted? I suppose we could have a more complex logical evaluator that handles the “MIT or GPL” case? (Doesn’t seem necessary to do that, just want to understand the intent…)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the intent is for this to be very conservative - I think there could be a more complex evaluator, but MIT or GPL is sufficiently rare, and the cases where there are 'viral or non-viral' clauses might have extra conditions that we'd want to manually review.

throw new Error(
`Non-whitelisted license detected in ${name}: ${license}`
);
}
}
}

let existing = licenseGroups.get(parsedLicense);
licenseGroups.set(
Expand All @@ -179,3 +197,5 @@ module.exports = (options = {}) => {
}
};
};

module.exports.flattenLicense = flattenLicense;
53 changes: 53 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ const commonjs = require("rollup-plugin-commonjs");
const nodeResolve = require("rollup-plugin-node-resolve");
const credits = require("../");

test("flattenLicense", t => {
t.deepEqual(
credits.flattenLicense({
left: { license: "LGPL-2.1" },
conjunction: "or",
right: {
left: { license: "BSD-3-Clause" },
conjunction: "and",
right: { license: "MIT" }
}
}),
["LGPL-2.1", "BSD-3-Clause", "MIT"]
);
t.deepEqual(
credits.flattenLicense({
left: { license: "BSD-3-Clause" },
conjunction: "and",
right: { license: "MIT" }
}),
["BSD-3-Clause", "MIT"]
);
t.deepEqual(credits.flattenLicense({ license: "LGPL-2.1" }), ["LGPL-2.1"]);
t.end();
});

test("rollup-plugin-credits", t => {
t.ok("required");

Expand Down Expand Up @@ -64,3 +89,31 @@ test("rollup-plugin-credits", t => {
t.end();
});
});

test("rollup-plugin-credits whitelist", t => {
const rollupConfig = {
input: path.join(__dirname, "example.js"),
output: {
format: "es"
},
plugins: [
nodeResolve(),
commonjs(),
credits({ debug: true, whitelist: ["MIT"] })
]
};

rollup.rollup(rollupConfig).then(async bundle => {
try {
const { code, map } = await bundle.generate({ format: "es" });
t.fail();
} catch (e) {
t.ok(
e.message.includes("Non-whitelisted license detected in inherits: ISC"),
"Got infringment"
);
}

t.end();
});
});