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

[LIC] Allows the simplified header for new files #936

Merged
merged 2 commits into from
Nov 17, 2021
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
27 changes: 20 additions & 7 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,20 @@
* GitHub history for details.
*/

const NEW_OSS_HEADER = `
/**
* For new files created by OpenSearch Contributers
*/
const OSD_HEADER = `
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
`;

/**
* For files that modify or use code with an exsting OSS header
*/
const OSS_HEADER = `
/*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -151,7 +164,7 @@ module.exports = {
'@osd/eslint/require-license-header': [
'error',
{
license: NEW_OSS_HEADER,
licenses: [OSD_HEADER, OSS_HEADER],
},
],
'@osd/eslint/disallow-license-headers': [
Expand Down Expand Up @@ -187,7 +200,7 @@ module.exports = {
'@osd/eslint/require-license-header': [
'error',
{
license: SAFER_LODASH_SET_LODASH_HEADER,
licenses: [SAFER_LODASH_SET_LODASH_HEADER],
},
],
'@osd/eslint/disallow-license-headers': [
Expand All @@ -209,14 +222,14 @@ module.exports = {
'@osd/eslint/require-license-header': [
'error',
{
license: SAFER_LODASH_SET_HEADER,
licenses: [SAFER_LODASH_SET_HEADER],
},
],
'@osd/eslint/disallow-license-headers': [
'error',
{
licenses: [
NEW_OSS_HEADER,
OSS_HEADER,
ELASTIC_LICENSE_HEADER,
APACHE_2_0_LICENSE_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
Expand All @@ -233,14 +246,14 @@ module.exports = {
'@osd/eslint/require-license-header': [
'error',
{
license: SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
licenses: [SAFER_LODASH_SET_DEFINITELYTYPED_HEADER],
},
],
'@osd/eslint/disallow-license-headers': [
'error',
{
licenses: [
NEW_OSS_HEADER,
OSS_HEADER,
ELASTIC_LICENSE_HEADER,
APACHE_2_0_LICENSE_HEADER,
SAFER_LODASH_SET_HEADER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '/* license */' }],
options: [{ licenses: ['/* license */'] }],
},
{
code: dedent`
Expand All @@ -59,7 +59,17 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '// license' }],
options: [{ licenses: ['// license'] }],
},
// multiple valid licenses
{
code: dedent`
/* license 2 */

console.log('foo')
`,

options: [{ licenses: ['/* license 1 */', '/* license 2 */'] }],
},
],

Expand All @@ -73,7 +83,7 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
options: [],
errors: [
{
message: '"license" option is required',
message: '"licenses" option is required',
},
],
},
Expand All @@ -84,10 +94,10 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '/* one *//* two */' }],
options: [{ licenses: ['/* one *//* two */'] }],
errors: [
{
message: '"license" option must only include a single comment',
message: '"licenses[0]" option must only include a single comment',
},
],
},
Expand All @@ -98,10 +108,10 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: `// one\n// two` }],
options: [{ licenses: [`// one\n// two`] }],
errors: [
{
message: '"license" option must only include a single comment',
message: '"licenses[0]" option must only include a single comment',
},
],
},
Expand All @@ -114,15 +124,17 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {

options: [
{
license: dedent`
licenses: [
dedent`
/* license */
console.log('hello world');
`,
],
},
],
errors: [
{
message: '"license" option must only include a single comment',
message: '"licenses[0]" option must only include a single comment',
},
],
},
Expand All @@ -133,10 +145,10 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: `console.log('hello world');` }],
options: [{ licenses: [`console.log('hello world');`] }],
errors: [
{
message: '"license" option must only include a single comment',
message: '"licenses[0]" option must only include a single comment',
},
],
},
Expand All @@ -147,7 +159,7 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '/* license */' }],
options: [{ licenses: ['/* license */'] }],
errors: [
{
message: 'File must start with a license header',
Expand All @@ -171,7 +183,7 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '/* license */' }],
options: [{ licenses: ['/* license */'] }],
errors: [
{
message: 'License header must be at the very beginning of the file',
Expand All @@ -193,7 +205,7 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,

options: [{ license: '/* license */' }],
options: [{ licenses: ['/* license */'] }],
errors: [
{
message: 'License header must be at the very beginning of the file',
Expand All @@ -208,5 +220,53 @@ ruleTester.run('@osd/eslint/require-license-header', rule, {
console.log('foo')
`,
},

// atleast one of multiple licenses must be present
{
code: dedent`
/* not license */
/* also not license */
console.log('foo')
`,

options: [{ licenses: ['/* license 1 */', '/* license 2 */'] }],
errors: [
{
message: 'File must start with a license header',
},
],

output: dedent`
/* license 1 */

/* not license */
/* also not license */
console.log('foo')
`,
},

// atleast one of multiple licenses must be present at the top of the file
{
code: dedent`
/* not license */
/* license 2 */
console.log('foo')
`,

options: [{ licenses: ['/* license 1 */', '/* license 2 */'] }],
errors: [
{
message: 'License header must be at the very beginning of the file',
},
],

output: dedent`
/* license 2 */

/* not license */

console.log('foo')
`,
},
],
});
53 changes: 32 additions & 21 deletions packages/osd-eslint-plugin-eslint/rules/require_license_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ module.exports = {
{
type: 'object',
properties: {
license: {
type: 'string',
licenses: {
type: 'array',
items: {
type: 'string',
},
},
},
additionalProperties: false,
Expand All @@ -56,33 +59,38 @@ module.exports = {
create: (context) => {
return {
Program(program) {
const license = init(context, program, function () {
const licenses = init(context, program, function () {
const options = context.options[0] || {};
const license = options.license;
const licenses = options.licenses;

assert(!!license, '"license" option is required');
assert(!!licenses, '"licenses" option is required');

const parsed = babelEslint.parse(license);
assert(!parsed.body.length, '"license" option must only include a single comment');
assert(
parsed.comments.length === 1,
'"license" option must only include a single comment'
);
return licenses.map((license, i) => {
const parsed = babelEslint.parse(license);
assert(
!parsed.body.length,
`"licenses[${i}]" option must only include a single comment`
);
assert(
parsed.comments.length === 1,
`"licenses[${i}]" option must only include a single comment`
);

return {
source: license,
nodeValue: normalizeWhitespace(parsed.comments[0].value),
};
return {
source: license,
nodeValue: normalizeWhitespace(parsed.comments[0].value),
};
});
});

if (!license) {
return;
}
if (!licenses || !licenses.length) return;

const sourceCode = context.getSourceCode();
const comment = sourceCode
.getAllComments()
.find((node) => normalizeWhitespace(node.value) === license.nodeValue);
.find((node) =>
licenses.map((license) => license.nodeValue).includes(normalizeWhitespace(node.value))
);

// no licence comment
if (!comment) {
Expand All @@ -97,13 +105,16 @@ module.exports = {
return undefined;
}

return fixer.replaceTextRange([0, 0], license.source + '\n\n');
return fixer.replaceTextRange([0, 0], licenses[0].source + '\n\n');
},
});
return;
}

// ensure there is nothing before the comment
const currentLicense = licenses.find(
(license) => normalizeWhitespace(comment.value) === license.nodeValue
);
const sourceBeforeNode = sourceCode
.getText()
.slice(0, sourceCode.getIndexFromLoc(comment.loc.start));
Expand All @@ -121,7 +132,7 @@ module.exports = {
// if removing whitespace is not possible
return [
fixer.remove(comment),
fixer.replaceTextRange([0, 0], license.source + '\n\n'),
fixer.replaceTextRange([0, 0], currentLicense.source + '\n\n'),
];
},
});
Expand Down