tools: enforce use of trailing commas in tools/

PR-URL: https://github.com/nodejs/node/pull/45889
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Antoine du Hamel 2022-12-18 17:39:39 +01:00 committed by GitHub
parent 9d1d94819f
commit 3ce4cef4e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 128 additions and 121 deletions

View File

@ -68,7 +68,7 @@ module.exports = {
files: ['**/*.md/*.cjs', '**/*.md/*.js'], files: ['**/*.md/*.cjs', '**/*.md/*.js'],
parserOptions: { parserOptions: {
sourceType: 'script', sourceType: 'script',
ecmaFeatures: { impliedStrict: true } ecmaFeatures: { impliedStrict: true },
}, },
rules: { strict: 'off' }, rules: { strict: 'off' },
}, },
@ -103,11 +103,11 @@ module.exports = {
}, },
{ {
name: 'Buffer', name: 'Buffer',
message: 'Import Buffer instead of using the global' message: 'Import Buffer instead of using the global',
}, },
{ {
name: 'process', name: 'process',
message: 'Import process instead of using the global' message: 'Import process instead of using the global',
}, },
] }, ] },
}, },
@ -134,13 +134,7 @@ module.exports = {
ignorePattern: '.*', ignorePattern: '.*',
}, },
}], }],
'comma-dangle': ['error', { 'comma-dangle': ['error', 'always-multiline'],
arrays: 'always-multiline',
exports: 'only-multiline',
functions: 'only-multiline',
imports: 'only-multiline',
objects: 'only-multiline',
}],
'comma-spacing': 'error', 'comma-spacing': 'error',
'comma-style': 'error', 'comma-style': 'error',
'computed-property-spacing': 'error', 'computed-property-spacing': 'error',

View File

@ -5,4 +5,11 @@ env:
es6: true es6: true
rules: rules:
comma-dangle: [error, {
arrays: always-multiline,
exports: only-multiline,
functions: only-multiline,
imports: only-multiline,
objects: only-multiline,
}]
prefer-arrow-callback: error prefer-arrow-callback: error

View File

@ -15,4 +15,3 @@ rules:
# Stylistic Issues # Stylistic Issues
no-multiple-empty-lines: [error, {max: 1, maxEOF: 0, maxBOF: 0}] no-multiple-empty-lines: [error, {max: 1, maxEOF: 0, maxBOF: 0}]
comma-dangle: [error, always-multiline]

View File

@ -2,6 +2,13 @@ env:
es6: true es6: true
rules: rules:
comma-dangle: [error, {
arrays: always-multiline,
exports: only-multiline,
functions: only-multiline,
imports: only-multiline,
objects: only-multiline,
}]
prefer-object-spread: error prefer-object-spread: error
no-buffer-constructor: error no-buffer-constructor: error
no-mixed-operators: no-mixed-operators:

View File

@ -31,7 +31,7 @@ async function buildAddon(dir) {
await execFile(process.execPath, [nodeGyp, 'rebuild', `--directory=${dir}`], await execFile(process.execPath, [nodeGyp, 'rebuild', `--directory=${dir}`],
{ {
stdio: 'inherit', stdio: 'inherit',
env: { ...process.env, MAKEFLAGS: '-j1' } env: { ...process.env, MAKEFLAGS: '-j1' },
}); });
// We buffer the output and print it out once the process is done in order // We buffer the output and print it out once the process is done in order

View File

@ -38,7 +38,7 @@ tree.children.forEach((node) => {
await Promise.all( await Promise.all(
Object.keys(addons).flatMap( Object.keys(addons).flatMap(
(header) => verifyFiles(addons[header].files, header) (header) => verifyFiles(addons[header].files, header),
)); ));
function verifyFiles(files, blockName) { function verifyFiles(files, blockName) {
@ -82,8 +82,8 @@ ${files[name].replace(
sources: files.map(({ name }) => name), sources: files.map(({ name }) => name),
includes: ['../common.gypi'], includes: ['../common.gypi'],
}, },
] ],
}) }),
}); });
const dirCreation = mkdir(dir); const dirCreation = mkdir(dir);

View File

@ -96,8 +96,8 @@ all = all.slice(0, apiStart.index + apiStart[0].length)
'\n</head>', '\n</head>',
buildCSSForFlavoredJS(new Set(Array.from( buildCSSForFlavoredJS(new Set(Array.from(
apicontent.matchAll(/(?<=<pre class="with-)\d+(?=-chars">)/g), apicontent.matchAll(/(?<=<pre class="with-)\d+(?=-chars">)/g),
(x) => Number(x[0]) (x) => Number(x[0]),
))) + '\n</head>' ))) + '\n</head>',
) + ) +
apicontent + apicontent +
all.slice(apiEnd); all.slice(apiEnd);

View File

@ -18,7 +18,7 @@ const results = {
modules: [], modules: [],
classes: [], classes: [],
globals: [], globals: [],
methods: [] methods: [],
}; };
// Identify files that should be skipped. As files are processed, they // Identify files that should be skipped. As files are processed, they
@ -33,7 +33,7 @@ for (const link of toc.match(/<a.*?>/g)) {
if (!jsonFiles.includes(json) || seen.has(json)) continue; if (!jsonFiles.includes(json) || seen.has(json)) continue;
const data = JSON.parse( const data = JSON.parse(
fs.readFileSync(new URL(`./${json}`, source), 'utf8') fs.readFileSync(new URL(`./${json}`, source), 'utf8')
.replace(/<a href=\\"#/g, `<a href=\\"${href}#`) .replace(/<a href=\\"#/g, `<a href=\\"${href}#`),
); );
for (const property in data) { for (const property in data) {

View File

@ -27,7 +27,7 @@ function execSync(command) {
try { try {
return child_process.execSync( return child_process.execSync(
command, command,
{ stdio: ['ignore', null, 'ignore'] } { stdio: ['ignore', null, 'ignore'] },
).toString().trim(); ).toString().trim();
} catch { } catch {
return ''; return '';

View File

@ -27,7 +27,7 @@ const testHeading = (headingNode, expectedDeprecationCode) => {
assert.strictEqual( assert.strictEqual(
headingNode?.children[0]?.value.substring(0, 9), headingNode?.children[0]?.value.substring(0, 9),
`${expectedDeprecationCode}: `, `${expectedDeprecationCode}: `,
'Ill-formed or out-of-order deprecation code.' 'Ill-formed or out-of-order deprecation code.',
); );
} catch (e) { } catch (e) {
throw addMarkdownPathToErrorStack(e, headingNode); throw addMarkdownPathToErrorStack(e, headingNode);
@ -39,7 +39,7 @@ const testYAMLComment = (commentNode) => {
assert.match( assert.match(
commentNode?.value?.substring(0, 21), commentNode?.value?.substring(0, 21),
/^<!-- YAML\r?\nchanges:\r?\n/, /^<!-- YAML\r?\nchanges:\r?\n/,
'Missing or ill-formed YAML comment.' 'Missing or ill-formed YAML comment.',
); );
} catch (e) { } catch (e) {
throw addMarkdownPathToErrorStack(e, commentNode); throw addMarkdownPathToErrorStack(e, commentNode);
@ -51,7 +51,7 @@ const testDeprecationType = (paragraphNode) => {
assert.strictEqual( assert.strictEqual(
paragraphNode?.children[0]?.value?.substring(0, 6), paragraphNode?.children[0]?.value?.substring(0, 6),
'Type: ', 'Type: ',
'Missing deprecation type.' 'Missing deprecation type.',
); );
} catch (e) { } catch (e) {
throw addMarkdownPathToErrorStack(e, paragraphNode); throw addMarkdownPathToErrorStack(e, paragraphNode);
@ -74,7 +74,7 @@ for (let i = 0; i < tree.children.length; i++) {
assert.strictEqual( assert.strictEqual(
deprecationCodeAsText, deprecationCodeAsText,
expectedDeprecationCode, expectedDeprecationCode,
'Deprecation codes are not ordered correctly.' 'Deprecation codes are not ordered correctly.',
); );
} catch (e) { } catch (e) {
throw addMarkdownPathToErrorStack(e, node); throw addMarkdownPathToErrorStack(e, node);

View File

@ -220,7 +220,7 @@ export function preprocessElements({ filename }) {
} else if (node.type === 'code') { } else if (node.type === 'code') {
if (!node.lang) { if (!node.lang) {
console.warn( console.warn(
`No language set in ${filename}, line ${node.position.start.line}` `No language set in ${filename}, line ${node.position.start.line}`,
); );
} }
const className = isJSFlavorSnippet(node) ? const className = isJSFlavorSnippet(node) ?
@ -302,7 +302,7 @@ export function preprocessElements({ filename }) {
(noLinking ? '' : (noLinking ? '' :
'<a href="documentation.html#stability-index">') + '<a href="documentation.html#stability-index">') +
`${prefix} ${number}${noLinking ? '' : '</a>'}` `${prefix} ${number}${noLinking ? '' : '</a>'}`
.replace(/\n/g, ' ') .replace(/\n/g, ' '),
}); });
// Remove prefix and number from text // Remove prefix and number from text
@ -408,7 +408,7 @@ export function buildToc({ filename, apilinks }) {
if (node.depth - depth > 1) { if (node.depth - depth > 1) {
throw new Error( throw new Error(
`Inappropriate heading level:\n${JSON.stringify(node)}` `Inappropriate heading level:\n${JSON.stringify(node)}`,
); );
} }
@ -543,7 +543,7 @@ function gtocPicker(id) {
// Highlight the current module and add a link to the index // Highlight the current module and add a link to the index
const gtoc = gtocHTML.replace( const gtoc = gtocHTML.replace(
`class="nav-${id}"`, `class="nav-${id} active"` `class="nav-${id}"`, `class="nav-${id} active"`,
).replace('</ul>', ` ).replace('</ul>', `
<li> <li>
<a href="index.html">Index</a> <a href="index.html">Index</a>

View File

@ -349,7 +349,7 @@ function parseSignature(text, sig) {
throw new Error( throw new Error(
`Invalid param "${sigParam}"\n` + `Invalid param "${sigParam}"\n` +
` > ${JSON.stringify(listParam)}\n` + ` > ${JSON.stringify(listParam)}\n` +
` > ${text}` ` > ${text}`,
); );
} }
} }
@ -376,7 +376,7 @@ function parseListItem(item, file) {
current.textRaw = item.children.filter((node) => node.type !== 'list') current.textRaw = item.children.filter((node) => node.type !== 'list')
.map((node) => ( .map((node) => (
file.value.slice(node.position.start.offset, node.position.end.offset)) file.value.slice(node.position.start.offset, node.position.end.offset)),
) )
.join('').replace(/\s+/g, ' ').replace(/<!--.*?-->/sg, ''); .join('').replace(/\s+/g, ' ').replace(/<!--.*?-->/sg, '');
let text = current.textRaw; let text = current.textRaw;

View File

@ -10,7 +10,7 @@ export function replaceLinks({ filename, linksMapper }) {
if (node.url) { if (node.url) {
node.url = node.url.replace( node.url = node.url.replace(
referenceToLocalMdFile, referenceToLocalMdFile,
(_, filename, hash) => `${filename}.html${hash || ''}` (_, filename, hash) => `${filename}.html${hash || ''}`,
); );
} }
}); });

View File

@ -8,7 +8,7 @@ const jsPrimitives = {
number: 'Number', number: 'Number',
string: 'String', string: 'String',
symbol: 'Symbol', symbol: 'Symbol',
undefined: 'Undefined' undefined: 'Undefined',
}; };
const jsGlobalObjectsUrl = `${jsDocPrefix}Reference/Global_Objects/`; const jsGlobalObjectsUrl = `${jsDocPrefix}Reference/Global_Objects/`;
@ -301,7 +301,7 @@ export function toLink(typeInput) {
} else { } else {
throw new Error( throw new Error(
`Unrecognized type: '${typeTextFull}'.\n` + `Unrecognized type: '${typeTextFull}'.\n` +
`Please, edit the type or update '${import.meta.url}'.` `Please, edit the type or update '${import.meta.url}'.`,
); );
} }
} else { } else {

View File

@ -26,7 +26,7 @@ module.exports = {
const message = [prefix, prev, opStr, curr].join(''); const message = [prefix, prev, opStr, curr].join('');
context.report({ node, message }); context.report({ node, message });
} }
} },
}; };
} },
}; };

View File

@ -13,7 +13,7 @@ const message =
module.exports = { module.exports = {
meta: { meta: {
fixable: 'code' fixable: 'code',
}, },
create: function(context) { create: function(context) {
let hasCommonModule = false; let hasCommonModule = false;
@ -31,10 +31,10 @@ module.exports = {
fix: (fixer) => { fix: (fixer) => {
if (hasCommonModule) if (hasCommonModule)
return fixer.insertTextAfter(node, '.then(common.mustCall())'); return fixer.insertTextAfter(node, '.then(common.mustCall())');
} },
}); });
} }
} },
}; };
} },
}; };

View File

@ -80,7 +80,7 @@ function createUnsafeStringMethodReport(context, name, lookedUpProperty) {
node, node,
message: `${name} looks up the ${lookedUpProperty} property on the first argument`, message: `${name} looks up the ${lookedUpProperty} property on the first argument`,
}); });
} },
}; };
} }
@ -98,7 +98,7 @@ function createUnsafeStringMethodOnRegexReport(context, name, lookedUpProperty)
node, node,
message: `${name} looks up the ${lookedUpProperty} property of the passed regex, use ${safePrimordialName} directly`, message: `${name} looks up the ${lookedUpProperty} property of the passed regex, use ${safePrimordialName} directly`,
}); });
} },
}; };
} }
@ -155,7 +155,7 @@ module.exports = {
fixer.replaceTextRange(testRange, 'Exec'), fixer.replaceTextRange(testRange, 'Exec'),
fixer.insertTextAfter(node, ' !== null'), fixer.insertTextAfter(node, ' !== null'),
]; ];
} },
}], }],
}); });
}, },

View File

@ -78,7 +78,7 @@ module.exports = {
if (beforeAllChecks) { if (beforeAllChecks) {
context.report({ context.report({
node: requireNode, node: requireNode,
message: msg message: msg,
}); });
} }
}); });
@ -106,10 +106,10 @@ module.exports = {
commonModuleNode, commonModuleNode,
'\nif (!common.hasCrypto) {' + '\nif (!common.hasCrypto) {' +
' common.skip("missing crypto");' + ' common.skip("missing crypto");' +
'}' '}',
); );
} }
} },
}); });
}); });
} }
@ -118,7 +118,7 @@ module.exports = {
'CallExpression': (node) => testCryptoUsage(node), 'CallExpression': (node) => testCryptoUsage(node),
'IfStatement:exit': (node) => testIfStatement(node), 'IfStatement:exit': (node) => testIfStatement(node),
'MemberExpression:exit': (node) => testMemberExpression(node), 'MemberExpression:exit': (node) => testMemberExpression(node),
'Program:exit': () => reportIfMissingCheck() 'Program:exit': () => reportIfMissingCheck(),
}; };
} },
}; };

View File

@ -34,7 +34,7 @@ module.exports = {
`doc/api/errors.md does not have an anchor for "${code}"`; `doc/api/errors.md does not have an anchor for "${code}"`;
context.report({ node, message }); context.report({ node, message });
} }
} },
}; };
} },
}; };

View File

@ -47,10 +47,10 @@ module.exports = {
if (commonModuleNode) { if (commonModuleNode) {
return fixer.insertTextAfter( return fixer.insertTextAfter(
commonModuleNode, commonModuleNode,
'\ncommon.skipIfEslintMissing();' '\ncommon.skipIfEslintMissing();',
); );
} }
} },
}); });
}); });
} }
@ -59,7 +59,7 @@ module.exports = {
return { return {
'CallExpression': (node) => testEslintUsage(context, node), 'CallExpression': (node) => testEslintUsage(context, node),
'MemberExpression': (node) => checkMemberExpression(context, node), 'MemberExpression': (node) => checkMemberExpression(context, node),
'Program:exit': () => reportIfMissing(context) 'Program:exit': () => reportIfMissing(context),
}; };
} },
}; };

View File

@ -48,10 +48,10 @@ module.exports = {
if (commonModuleNode) { if (commonModuleNode) {
return fixer.insertTextAfter( return fixer.insertTextAfter(
commonModuleNode, commonModuleNode,
'\ncommon.skipIfInspectorDisabled();' '\ncommon.skipIfInspectorDisabled();',
); );
} }
} },
}); });
}); });
} }
@ -60,7 +60,7 @@ module.exports = {
return { return {
'CallExpression': (node) => testInspectorUsage(context, node), 'CallExpression': (node) => testInspectorUsage(context, node),
'MemberExpression': (node) => checkMemberExpression(context, node), 'MemberExpression': (node) => checkMemberExpression(context, node),
'Program:exit': () => reportIfMissing(context) 'Program:exit': () => reportIfMissing(context),
}; };
} },
}; };

View File

@ -41,19 +41,19 @@ module.exports = function(context) {
fix: (fixer) => { fix: (fixer) => {
return fixer.replaceText( return fixer.replaceText(
node, node,
`'${lowercaseName}'` `'${lowercaseName}'`,
); );
} },
}); });
} }
} }
return { return {
[astSelector]: (node) => checkNamesArgument(node) [astSelector]: (node) => checkNamesArgument(node),
}; };
}; };
module.exports.meta = { module.exports.meta = {
fixable: 'code' fixable: 'code',
}; };

View File

@ -30,7 +30,7 @@ const findComma = (sourceCode, elements, i, start) => {
element = elements[--i]; element = elements[--i];
} }
let token = sourceCode.getTokenAfter( let token = sourceCode.getTokenAfter(
element ?? sourceCode.getTokenByRangeStart(start) element ?? sourceCode.getTokenByRangeStart(start),
); );
for (; i < originalIndex; i++) { for (; i < originalIndex; i++) {
token = sourceCode.getTokenAfter(token); token = sourceCode.getTokenAfter(token);
@ -43,7 +43,7 @@ const createFix = (fixer, sourceCode, { range: [start, end], elements }) => [
...elements.map((node, i) => ...elements.map((node, i) =>
(node === null ? (node === null ?
fixer.remove(findComma(sourceCode, elements, i, start)) : fixer.remove(findComma(sourceCode, elements, i, start)) :
fixer.insertTextBefore(node, i + ':')) fixer.insertTextBefore(node, i + ':')),
), ),
]; ];
const arrayPatternContainsRestOperator = ({ elements }) => const arrayPatternContainsRestOperator = ({ elements }) =>

View File

@ -52,7 +52,7 @@ module.exports = (context) => {
context.report( context.report(
node, node,
'\'{{moduleName}}\' require is duplicated.', '\'{{moduleName}}\' require is duplicated.',
{ moduleName } { moduleName },
); );
} else { } else {
required.add(moduleName); required.add(moduleName);

View File

@ -20,7 +20,7 @@ module.exports = {
context.report({ context.report({
node, node,
loc: sourceCode.getLocFromIndex(indexOfDot), loc: sourceCode.getLocFromIndex(indexOfDot),
message: 'Unescaped dot character in regular expression' message: 'Unescaped dot character in regular expression',
}); });
} }
const allowedModifiers = ['+', '*', '?', '{']; const allowedModifiers = ['+', '*', '?', '{'];
@ -127,7 +127,7 @@ module.exports = {
'CallExpression': checkRegExpStart, 'CallExpression': checkRegExpStart,
'NewExpression': checkRegExpStart, 'NewExpression': checkRegExpStart,
'CallExpression:exit': checkRegExpEnd, 'CallExpression:exit': checkRegExpEnd,
'NewExpression:exit': checkRegExpEnd 'NewExpression:exit': checkRegExpEnd,
}; };
} },
}; };

View File

@ -21,7 +21,7 @@ const suggestions = {
'”': '"', '”': '"',
'«': '"', '«': '"',
'»': '"', '»': '"',
'—': '-' '—': '-',
}; };
module.exports = (context) => { module.exports = (context) => {
@ -50,6 +50,6 @@ module.exports = (context) => {
}; };
return { return {
Program: (node) => reportIfError(node, context.getSourceCode()) Program: (node) => reportIfError(node, context.getSourceCode()),
}; };
}; };

View File

@ -9,7 +9,7 @@ const utils = require('./rules-utils.js');
module.exports = { module.exports = {
meta: { meta: {
fixable: 'code' fixable: 'code',
}, },
create(context) { create(context) {
const sourceCode = context.getSourceCode(); const sourceCode = context.getSourceCode();
@ -52,13 +52,13 @@ module.exports = {
if (assertImported) { if (assertImported) {
return fixer.replaceText( return fixer.replaceText(
node, node,
`assert.ifError(${argument});` `assert.ifError(${argument});`,
); );
} }
} },
}); });
} }
} },
}; };
} },
}; };

View File

@ -16,7 +16,7 @@ const preferredAssertMethod = {
'===': 'strictEqual', '===': 'strictEqual',
'!==': 'notStrictEqual', '!==': 'notStrictEqual',
'==': 'equal', '==': 'equal',
'!=': 'notEqual' '!=': 'notEqual',
}; };
module.exports = function(context) { module.exports = function(context) {
@ -34,15 +34,15 @@ module.exports = function(context) {
const right = sourceCode.getText(arg.right); const right = sourceCode.getText(arg.right);
return fixer.replaceText( return fixer.replaceText(
node, node,
`assert.${assertMethod}(${left}, ${right});` `assert.${assertMethod}(${left}, ${right});`,
); );
} },
}); });
} }
} },
}; };
}; };
module.exports.meta = { module.exports.meta = {
fixable: 'code' fixable: 'code',
}; };

View File

@ -25,6 +25,6 @@ module.exports = function(context) {
[arg0Selector]: report, [arg0Selector]: report,
// Catch common.mustCall(fn, 0) // Catch common.mustCall(fn, 0)
[arg1Selector]: report [arg1Selector]: report,
}; };
}; };

View File

@ -61,6 +61,6 @@ module.exports = (context) => {
} }
} }
} }
} },
}; };
}; };

View File

@ -73,8 +73,8 @@ const identifierSelector = parentSelectors.map((selector) => `[type!=${selector}
module.exports = { module.exports = {
meta: { meta: {
messages: { messages: {
error: 'Use `const { {{name}} } = primordials;` instead of the global.' error: 'Use `const { {{name}} } = primordials;` instead of the global.',
} },
}, },
create(context) { create(context) {
const globalScope = context.getSourceCode().scopeManager.globalScope; const globalScope = context.getSourceCode().scopeManager.globalScope;
@ -86,7 +86,7 @@ module.exports = {
const names = option.ignore || []; const names = option.ignore || [];
nameMap.set( nameMap.set(
option.name, option.name,
new Map(names.map((name) => [name, { ignored: true }])) new Map(names.map((name) => [name, { ignored: true }])),
); );
if (option.into) { if (option.into) {
renameMap.set(option.name, option.into); renameMap.set(option.name, option.into);
@ -111,7 +111,7 @@ module.exports = {
const name = node.name; const name = node.name;
const parent = getDestructuringAssignmentParent( const parent = getDestructuringAssignmentParent(
context.getScope(), context.getScope(),
node node,
); );
const parentName = parent?.name; const parentName = parent?.name;
if (!isTarget(nameMap, name) && !isTarget(nameMap, parentName)) { if (!isTarget(nameMap, name) && !isTarget(nameMap, parentName)) {
@ -129,8 +129,8 @@ module.exports = {
node, node,
messageId: 'error', messageId: 'error',
data: { data: {
name: getReportName({ into, parentName, name }) name: getReportName({ into, parentName, name }),
} },
}); });
} }
return; return;
@ -142,8 +142,8 @@ module.exports = {
node, node,
messageId: 'error', messageId: 'error',
data: { data: {
name: getReportName({ into, parentName, name }) name: getReportName({ into, parentName, name }),
} },
}); });
} }
}, },
@ -162,7 +162,7 @@ module.exports = {
messageId: 'error', messageId: 'error',
data: { data: {
name: toPrimordialsName(obj, prop), name: toPrimordialsName(obj, prop),
} },
}); });
} }
}, },
@ -180,5 +180,5 @@ module.exports = {
} }
}, },
}; };
} },
}; };

View File

@ -33,7 +33,7 @@ module.exports = {
}); });
if (hasSequentialParams) if (hasSequentialParams)
context.report(msg, errMsg); context.report(msg, errMsg);
} },
}; };
} },
}; };

View File

@ -52,10 +52,10 @@ module.exports = function(context) {
node, node,
'Mandatory module "{{moduleName}}" must be loaded ' + 'Mandatory module "{{moduleName}}" must be loaded ' +
'before any other modules.', 'before any other modules.',
{ moduleName: requiredModule } { moduleName: requiredModule },
); );
} }
} },
}; };
if (isESM) { if (isESM) {

View File

@ -56,17 +56,17 @@ module.exports = function(context) {
'Program:exit'(node) { 'Program:exit'(node) {
if (foundModules.length < requiredModules.length) { if (foundModules.length < requiredModules.length) {
const missingModules = requiredModules.filter( const missingModules = requiredModules.filter(
([module]) => foundModules.indexOf(module) === -1 ([module]) => foundModules.indexOf(module) === -1,
); );
missingModules.forEach(([moduleName]) => { missingModules.forEach(([moduleName]) => {
context.report( context.report(
node, node,
'Mandatory module "{{moduleName}}" must be loaded.', 'Mandatory module "{{moduleName}}" must be loaded.',
{ moduleName: moduleName } { moduleName: moduleName },
); );
}); });
} }
} },
}; };
if (isESM) { if (isESM) {
@ -95,7 +95,7 @@ module.exports.meta = {
schema: [{ schema: [{
'type': 'object', 'type': 'object',
'additionalProperties': { 'additionalProperties': {
'type': 'string' 'type': 'string',
}, },
}], }],
}; };

View File

@ -11,7 +11,7 @@ import { parseArgs } from 'node:util';
const args = parseArgs({ const args = parseArgs({
allowPositionals: true, allowPositionals: true,
options: { verbose: { type: 'boolean', short: 'v' } } options: { verbose: { type: 'boolean', short: 'v' } },
}); });
const verbose = args.values.verbose; const verbose = args.values.verbose;
@ -27,7 +27,7 @@ async function runGitCommand(cmd, mapFn) {
input: childProcess.stdout, input: childProcess.stdout,
}); });
const errorHandler = new Promise( const errorHandler = new Promise(
(_, reject) => childProcess.on('error', reject) (_, reject) => childProcess.on('error', reject),
); );
let returnValue = mapFn ? new Set() : ''; let returnValue = mapFn ? new Set() : '';
await Promise.race([errorHandler, Promise.resolve()]); await Promise.race([errorHandler, Promise.resolve()]);
@ -50,13 +50,13 @@ async function runGitCommand(cmd, mapFn) {
// Get all commit authors during the time period. // Get all commit authors during the time period.
const authors = await runGitCommand( const authors = await runGitCommand(
`git shortlog -n -s --email --since="${SINCE}" HEAD`, `git shortlog -n -s --email --since="${SINCE}" HEAD`,
(line) => line.trim().split('\t', 2)[1] (line) => line.trim().split('\t', 2)[1],
); );
// Get all approving reviewers of landed commits during the time period. // Get all approving reviewers of landed commits during the time period.
const approvingReviewers = await runGitCommand( const approvingReviewers = await runGitCommand(
`git log --since="${SINCE}" | egrep "^ Reviewed-By: "`, `git log --since="${SINCE}" | egrep "^ Reviewed-By: "`,
(line) => /^ {4}Reviewed-By: ([^<]+)/.exec(line)[1].trim() (line) => /^ {4}Reviewed-By: ([^<]+)/.exec(line)[1].trim(),
); );
async function getCollaboratorsFromReadme() { async function getCollaboratorsFromReadme() {
@ -81,7 +81,7 @@ async function getCollaboratorsFromReadme() {
if (line.startsWith(' **') && isCollaborator) { if (line.startsWith(' **') && isCollaborator) {
const [, name, email] = /^ {2}\*\*([^*]+)\*\* <<(.+)>>/.exec(line); const [, name, email] = /^ {2}\*\*([^*]+)\*\* <<(.+)>>/.exec(line);
const mailmap = await runGitCommand( const mailmap = await runGitCommand(
`git check-mailmap '${name} <${email}>'` `git check-mailmap '${name} <${email}>'`,
); );
if (mailmap !== `${name} <${email}>`) { if (mailmap !== `${name} <${email}>`) {
console.log(`README entry for Collaborator does not match mailmap:\n ${name} <${email}> => ${mailmap}`); console.log(`README entry for Collaborator does not match mailmap:\n ${name} <${email}> => ${mailmap}`);
@ -191,7 +191,7 @@ if (verbose) {
} }
const inactive = collaborators.filter((collaborator) => const inactive = collaborators.filter((collaborator) =>
!authors.has(collaborator.mailmap) && !authors.has(collaborator.mailmap) &&
!approvingReviewers.has(collaborator.name) !approvingReviewers.has(collaborator.name),
); );
if (inactive.length) { if (inactive.length) {

View File

@ -16,7 +16,7 @@ import { parseArgs } from 'node:util';
const args = parseArgs({ const args = parseArgs({
allowPositionals: true, allowPositionals: true,
options: { verbose: { type: 'boolean', short: 'v' } } options: { verbose: { type: 'boolean', short: 'v' } },
}); });
const verbose = args.values.verbose; const verbose = args.values.verbose;
@ -32,7 +32,7 @@ async function runGitCommand(cmd, options = {}) {
input: childProcess.stdout, input: childProcess.stdout,
}); });
const errorHandler = new Promise( const errorHandler = new Promise(
(_, reject) => childProcess.on('error', reject) (_, reject) => childProcess.on('error', reject),
); );
let returnValue = options.mapFn ? new Set() : ''; let returnValue = options.mapFn ? new Set() : '';
await Promise.race([errorHandler, Promise.resolve()]); await Promise.race([errorHandler, Promise.resolve()]);
@ -122,7 +122,7 @@ async function getVotingRecords(tscMembers, votes) {
for (const vote of votes) { for (const vote of votes) {
// Get the vote data. // Get the vote data.
const voteData = JSON.parse( const voteData = JSON.parse(
await fs.promises.readFile(path.join('.tmp', vote), 'utf8') await fs.promises.readFile(path.join('.tmp', vote), 'utf8'),
); );
for (const member in voteData.votes) { for (const member in voteData.votes) {
if (tscMembers.includes(member)) { if (tscMembers.includes(member)) {
@ -227,33 +227,33 @@ await runGitCommand('git reset HEAD README.md');
await runGitCommand('git checkout -- README.md'); await runGitCommand('git checkout -- README.md');
const tscMembers = tscMembersAtEnd.filter( const tscMembers = tscMembersAtEnd.filter(
(memberAtEnd) => tscMembersAtStart.includes(memberAtEnd) (memberAtEnd) => tscMembersAtStart.includes(memberAtEnd),
); );
// Get all meetings since SINCE. // Get all meetings since SINCE.
// Assumes that the TSC repo is cloned in the .tmp dir. // Assumes that the TSC repo is cloned in the .tmp dir.
const meetings = await runGitCommand( const meetings = await runGitCommand(
`git whatchanged --since '${SINCE}' --name-only --pretty=format: meetings`, `git whatchanged --since '${SINCE}' --name-only --pretty=format: meetings`,
{ cwd: '.tmp', mapFn: (line) => line } { cwd: '.tmp', mapFn: (line) => line },
); );
// Get TSC meeting attendance. // Get TSC meeting attendance.
const attendance = await getAttendance(tscMembers, meetings); const attendance = await getAttendance(tscMembers, meetings);
const lightAttendance = tscMembers.filter( const lightAttendance = tscMembers.filter(
(member) => attendance[member] < meetings.size * 0.25 (member) => attendance[member] < meetings.size * 0.25,
); );
// Get all votes since SINCE. // Get all votes since SINCE.
// Assumes that the TSC repo is cloned in the .tmp dir. // Assumes that the TSC repo is cloned in the .tmp dir.
const votes = await runGitCommand( const votes = await runGitCommand(
`git whatchanged --since '${SINCE}' --name-only --pretty=format: votes/*.json`, `git whatchanged --since '${SINCE}' --name-only --pretty=format: votes/*.json`,
{ cwd: '.tmp', mapFn: (line) => line } { cwd: '.tmp', mapFn: (line) => line },
); );
// Check voting record. // Check voting record.
const votingRecords = await getVotingRecords(tscMembers, votes); const votingRecords = await getVotingRecords(tscMembers, votes);
const noVotes = tscMembers.filter( const noVotes = tscMembers.filter(
(member) => votingRecords[member] === 0 (member) => votingRecords[member] === 0,
); );
const inactive = lightAttendance.filter((member) => noVotes.includes(member)); const inactive = lightAttendance.filter((member) => noVotes.includes(member));

View File

@ -63,7 +63,7 @@ class ParagraphParser extends Stream {
this.paragraph = { this.paragraph = {
li: '', li: '',
inLicenseBlock: this.blockIsLicenseBlock, inLicenseBlock: this.blockIsLicenseBlock,
lines: [] lines: [],
}; };
} }

View File

@ -32,7 +32,7 @@ const dir = await fs.promises.opendir(dataFolder);
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isFile()) { if (dirent.isFile()) {
filesToCheck.push( filesToCheck.push(
getVersionsFromFile(new URL(dirent.name, dataFolder)) getVersionsFromFile(new URL(dirent.name, dataFolder)),
); );
} }
} }

View File

@ -28,7 +28,7 @@ for await (const line of diff) {
} else if (!validatePrUrl(line.match(prUrlDefinition)?.[1])) { } else if (!validatePrUrl(line.match(prUrlDefinition)?.[1])) {
console.warn( console.warn(
`::warning file=${currentFile},line=${currentLine++},col=${line.length}` + `::warning file=${currentFile},line=${currentLine++},col=${line.length}` +
'::pr-url doesn\'t match the URL of the current PR.' '::pr-url doesn\'t match the URL of the current PR.',
); );
} else if (line[0] !== '-') { } else if (line[0] !== '-') {
// Increment line counter if line is not being deleted. // Increment line counter if line is not being deleted.

View File

@ -77,12 +77,12 @@ async function checkFiles(...files) {
(process.env.GITHUB_ACTIONS ? (process.env.GITHUB_ACTIONS ?
`::error file=${file},line=1,col=1::` : `::error file=${file},line=1,col=1::` :
'Fixable with --fix: ') + 'Fixable with --fix: ') +
`Invalid hashbang for ${file} (expected /bin/sh).` `Invalid hashbang for ${file} (expected /bin/sh).`,
); );
} }
} }
await fd.close(); await fd.close();
}) }),
); );
const stdout = await new Promise((resolve, reject) => { const stdout = await new Promise((resolve, reject) => {
@ -102,7 +102,7 @@ async function checkFiles(...files) {
files.map((filePath) => relative(SPAWN_OPTIONS.cwd, filePath)) : files.map((filePath) => relative(SPAWN_OPTIONS.cwd, filePath)) :
files), files),
], ],
SPAWN_OPTIONS SPAWN_OPTIONS,
); );
shellcheck.once('error', reject); shellcheck.once('error', reject);
@ -138,7 +138,7 @@ async function checkFiles(...files) {
const data = JSON.parse(stdout); const data = JSON.parse(stdout);
for (const { file, line, column, message } of data) { for (const { file, line, column, message } of data) {
console.error( console.error(
`::error file=${file},line=${line},col=${column}::${file}:${line}:${column}: ${message}` `::error file=${file},line=${line},col=${column}::${file}:${line}:${column}: ${message}`,
); );
} }
} }

View File

@ -17,7 +17,7 @@ const log = spawn(
'git', 'git',
// Inspect author name/email and body. // Inspect author name/email and body.
['log', '--reverse', '--format=Author: %aN <%aE>\n%b'], { ['log', '--reverse', '--format=Author: %aN <%aE>\n%b'], {
stdio: ['inherit', 'pipe', 'inherit'] stdio: ['inherit', 'pipe', 'inherit'],
}); });
const rl = readline.createInterface({ input: log.stdout }); const rl = readline.createInterface({ input: log.stdout });