tools: use mailmap for find-inactive-collaborators

The current version of find-inactive-collaborators can generate a false
positive if the mailmap entry for a collaborator does not match the
entry in the README. (We should probably lint or otherwise check for
that sort of mismatch but regardless, it is relatively easy to avoid
having find-inactive-collaborators tripped up by it, so let's fix that
too, which is this commit.)

PR-URL: https://github.com/nodejs/node/pull/39432
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Rich Trott 2021-07-18 21:30:03 -07:00 committed by Node.js GitHub Bot
parent 6c32434c8b
commit 28a579bbc2

View File

@ -22,27 +22,33 @@ async function runGitCommand(cmd, mapFn) {
const errorHandler = new Promise(
(_, reject) => childProcess.on('error', reject)
);
const returnedSet = new Set();
let returnValue = mapFn ? new Set() : '';
await Promise.race([errorHandler, Promise.resolve()]);
// If no mapFn, return the value. If there is a mapFn, use it to make a Set to
// return.
for await (const line of lines) {
await Promise.race([errorHandler, Promise.resolve()]);
const val = mapFn(line);
if (val) {
returnedSet.add(val);
if (mapFn) {
const val = mapFn(line);
if (val) {
returnValue.add(val);
}
} else {
returnValue += line;
}
}
return Promise.race([errorHandler, Promise.resolve(returnedSet)]);
return Promise.race([errorHandler, Promise.resolve(returnValue)]);
}
// Get all commit authors during the time period.
const authors = await runGitCommand(
`git shortlog -n -s --max-count="${SINCE}" HEAD`,
`git shortlog -n -s --email --max-count="${SINCE}" HEAD`,
(line) => line.trim().split('\t', 2)[1]
);
// Get all commit landers during the time period.
const landers = await runGitCommand(
`git shortlog -n -s -c --max-count="${SINCE}" HEAD`,
`git shortlog -n -s -c --email --max-count="${SINCE}" HEAD`,
(line) => line.trim().split('\t', 2)[1]
);
@ -52,7 +58,7 @@ const approvingReviewers = await runGitCommand(
(line) => /^ Reviewed-By: ([^<]+)/.exec(line)[1].trim()
);
async function retrieveCollaboratorsFromReadme() {
async function getCollaboratorsFromReadme() {
const readmeText = readline.createInterface({
input: fs.createReadStream(new URL('../README.md', import.meta.url)),
crlfDelay: Infinity,
@ -69,14 +75,22 @@ async function retrieveCollaboratorsFromReadme() {
break;
}
if (line.startsWith('**') && isCollaborator) {
returnedArray.push(line.split('**', 2)[1].trim());
const [, name, email] = /^\*\*([^*]+)\*\* &lt;(.+)&gt;/.exec(line);
const mailmap = await runGitCommand(
`git check-mailmap '${name} <${email}>'`
);
returnedArray.push({
name,
email,
mailmap,
});
}
}
return returnedArray;
}
// Get list of current collaborators from README.md.
const collaborators = await retrieveCollaboratorsFromReadme();
const collaborators = await getCollaboratorsFromReadme();
console.log(`In the last ${SINCE} commits:\n`);
console.log(`* ${authors.size.toLocaleString()} authors have made commits.`);
@ -85,10 +99,10 @@ console.log(`* ${approvingReviewers.size.toLocaleString()} reviewers have approv
console.log(`* ${collaborators.length.toLocaleString()} collaborators currently in the project.`);
const inactive = collaborators.filter((collaborator) =>
!authors.has(collaborator) &&
!landers.has(collaborator) &&
!approvingReviewers.has(collaborator)
);
!authors.has(collaborator.mailmap) &&
!landers.has(collaborator.mailmap) &&
!approvingReviewers.has(collaborator.name)
).map((collaborator) => collaborator.name);
if (inactive.length) {
console.log('\nInactive collaborators:\n');