Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit fd3ed19

Browse files
author
Julien Gilli
committed
Load existing .mailmap file before generating new one
1 parent 0328ec4 commit fd3ed19

File tree

1 file changed

+101
-35
lines changed

1 file changed

+101
-35
lines changed

tools/update-authors.js

Lines changed: 101 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ var OPTS = processCmdLineArgs();
5353
var AUTHORS_FILE = OPTS.authorsFile || 'AUTHORS';
5454
var MAILMAP_FILE = OPTS.mailmapFile || '.mailmap';
5555

56+
var PLATFORM_AGNOSTIC_EOL = /\r|\n|\r\n/;
57+
5658
var authorsMailMap = {};
5759

5860
function usage() {
@@ -92,12 +94,13 @@ function addAuthorToEmailMap(authorName, authorEmail) {
9294

9395
debug('ADDING AUTHOR [' + authorName + '] [' + authorEmail + ']');
9496

95-
if (authorsMailMap[authorName]) {
96-
if (authorsMailMap[authorName].indexOf(authorEmail) === -1) {
97-
authorsMailMap[authorName].push(authorEmail);
97+
var authorEntry = authorsMailMap[authorName];
98+
if (authorEntry && authorEntry.emails) {
99+
if (authorEntry.emails.indexOf(authorEmail) === -1) {
100+
authorEntry.emails.push(authorEmail);
98101
}
99102
} else {
100-
authorsMailMap[authorName] = [ authorEmail ];
103+
authorsMailMap[authorName] = { emails: [ authorEmail ] };
101104
}
102105
}
103106

@@ -126,7 +129,7 @@ function generateAuthorsMailMapFile(authorsMailMap, mailmapFilepath, cb) {
126129
assert(Array.isArray(authorsNames), 'authorsNames must be an array');
127130

128131
var authorName = authorsNames.splice(0, 1);
129-
var authorEmails = authorsMailMap[authorName];
132+
var authorEntry = authorsMailMap[authorName];
130133

131134
function writeNextAuthorOrDone() {
132135
process.nextTick(function onNextTick() {
@@ -136,16 +139,19 @@ function generateAuthorsMailMapFile(authorsMailMap, mailmapFilepath, cb) {
136139
return cb();
137140
});
138141
}
139-
// Authors with no more than one email address don't need to be added
142+
// Unless the entry was already present in the original .mailmap file,
143+
// authors with no more than one email address don't need to be added
140144
// to the .mailmap file, since its purpose is to handle authors with
141145
// more than one email address.
142-
if (!authorEmails || authorEmails.length < 2) {
146+
if (!authorEntry || !authorEntry.emails ||
147+
(authorEntry.emails.length < 2 && !authorEntry.loadedFromExisting)) {
143148
debug('Skipping mailmap entry for author [' + authorName + ']');
144149
return writeNextAuthorOrDone();
145150
}
146151

147152
debug('Writing mailmap entry for author [' + authorName + ']');
148153

154+
var authorEmails = authorEntry.emails;
149155
authorEmails = authorEmails.map(emailFormatter);
150156

151157
var mapAuthorEntry = authorName + ' ' + authorEmails.join(' ');
@@ -182,7 +188,7 @@ var latestAuthorsLineChunk = '';
182188
function addAuthors(authors) {
183189
assert(typeof authors === 'string', 'authors must be a string');
184190

185-
var authors = (latestAuthorsLineChunk + authors).split(os.EOL);
191+
var authors = (latestAuthorsLineChunk + authors).split(PLATFORM_AGNOSTIC_EOL);
186192
latestAuthorsLineChunk = '';
187193
authors.forEach(function eachAuthor(author) {
188194
if (author && author.length > 0) {
@@ -202,38 +208,98 @@ function addAuthors(authors) {
202208
});
203209
}
204210

205-
var gitLog = child_process.spawn('git', GIT_LOG_COMMAND_ARGS);
211+
function loadAdditionalAuthorsFromGitLog(cb) {
212+
var gitLog = child_process.spawn('git', GIT_LOG_COMMAND_ARGS);
206213

207-
gitLog.on('close', function onGitLogClose(exitCode, signal) {
208-
if (exitCode === 0 && signal === null) {
214+
gitLog.on('close', function onGitLogClose(exitCode, signal) {
215+
if (exitCode === 0 && signal === null) {
209216

210-
debug('NB AUTHORS:' + Object.keys(authorsMailMap).length);
217+
debug('NB AUTHORS:' + Object.keys(authorsMailMap).length);
211218

212-
generateAuthorsFile(AUTHORS_FILE, function onAuthorsFileGenerated(err) {
213-
if (err) {
214-
console.error('Error when generating authors file:', err);
215-
} else {
216-
console.log('Authors file generated successfully!');
217-
}
218-
});
219+
generateAuthorsFile(AUTHORS_FILE, function onAuthorsFileGenerated(err) {
220+
if (err) {
221+
return cb(new Error('Error when generating authors file:', err));
222+
} else {
223+
console.log('Authors file generated successfully!');
224+
}
225+
});
219226

220-
generateAuthorsMailMapFile(authorsMailMap,
221-
MAILMAP_FILE,
222-
function onMailmapFileGenerated(err) {
223-
if (err) {
224-
console.error('Error when generating mailmap file:', err);
225-
} else {
226-
console.log('mailmap file generated successfully!');
227-
}
227+
generateAuthorsMailMapFile(authorsMailMap,
228+
MAILMAP_FILE,
229+
function onMailmapFileGenerated(err) {
230+
if (err) {
231+
return cb(new Error('Error when generating mailmap file:', err));
232+
} else {
233+
console.log('mailmap file generated successfully!');
234+
}
235+
});
236+
}
237+
});
238+
239+
gitLog.on('error', function onGitLogError(err) {
240+
var errorMsg = util.format('Error when executing command %s: %s', GIT_LOG_COMMAND, err);
241+
return cb(new Error(errorMsg));
242+
});
243+
244+
gitLog.stdout.on('data', function onGitLogData(data) {
245+
addAuthors(data.toString());
246+
});
247+
}
248+
249+
function addExistingMailmapEntries(mailmapEntries, cb) {
250+
assert(typeof mailmapEntries === 'string',
251+
'mailmapEntries must be a string');
252+
assert(typeof cb === 'function', 'cb must be a function');
253+
254+
var mailmapLines = mailmapEntries.split(PLATFORM_AGNOSTIC_EOL);
255+
mailmapLines.forEach(function(mailmapLine) {
256+
debug('Processing existing mailmap line:');
257+
debug(mailmapLine);
258+
259+
var indexFirstEmail = mailmapLine.indexOf('<');
260+
var authorName = mailmapLine.substr(0, indexFirstEmail).trim();
261+
debug('author name: ' + authorName);
262+
263+
var authorEmails = [];
264+
265+
var nextEmailIndex = indexFirstEmail;
266+
for (var idx = nextEmailIndex;
267+
nextEmailIndex !== -1;
268+
idx += mailmapLine.indexOf('<', nextEmailIndex + 1)) {
269+
var indexOfEmailEnd = mailmapLine.indexOf('>', nextEmailIndex)
270+
var authorEmail = mailmapLine.substr(nextEmailIndex + 1,
271+
indexOfEmailEnd - (nextEmailIndex + 1))
272+
debug('author email: ' + authorEmail);
273+
authorEmails.push(authorEmail);
274+
275+
nextEmailIndex = mailmapLine.indexOf('<', indexOfEmailEnd);
276+
}
277+
278+
if (authorEmails.length > 0) {
279+
authorsMailMap[authorName] = {
280+
loadedFromExisting: true, emails: authorEmails
281+
};
282+
}
283+
});
284+
285+
return cb();
286+
}
287+
288+
function loadExistingMailmapFile(cb) {
289+
debug('Loading existing mailmap file');
290+
291+
fs.readFile(MAILMAP_FILE, function onMailmapFileRead(err, data) {
292+
addExistingMailmapEntries(data.toString(), cb);
293+
});
294+
}
295+
296+
loadExistingMailmapFile(function onMailmapFileLoaded(err) {
297+
if (err) {
298+
console.error('Error when loading existing mailmap file:' ,err);
299+
} else {
300+
return loadAdditionalAuthorsFromGitLog(function onGitLoneDone(err) {
301+
console.error('Error when loading git log data:', err);
228302
});
229303
}
230304
});
231305

232-
gitLog.on('error', function onGitLogError(err) {
233-
console.error('Error when executing command %s: %s', GIT_LOG_COMMAND, err);
234-
process.exit(1);
235-
});
236-
237-
gitLog.stdout.on('data', function onGitLogData(data) {
238-
addAuthors(data.toString());
239-
});

0 commit comments

Comments
 (0)