update-authors.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #!/usr/bin/env node
  2. // original comes from https://github.com/nodejs/node/blob/c18ca140a12b543a3f970ef379f384ebd3297c3d/tools/update-authors.js
  3. // Usage: dev/update-author.js [--dry]
  4. // Passing --dry will redirect output to stdout rather than write to 'AUTHORS'.
  5. 'use strict';
  6. const { spawn } = require('node:child_process');
  7. const fs = require('node:fs');
  8. const readline = require('node:readline');
  9. const log = spawn(
  10. 'git',
  11. // Inspect author name/email and body.
  12. ['log', '--reverse', '--format=Author: %aN <%aE>\n%b'],
  13. {
  14. stdio: ['inherit', 'pipe', 'inherit'],
  15. },
  16. );
  17. const rl = readline.createInterface({ input: log.stdout });
  18. let output;
  19. if (process.argv.includes('--dry')) {
  20. output = process.stdout;
  21. } else {
  22. output = fs.createWriteStream('AUTHORS');
  23. }
  24. output.write('# Authors ordered by first contribution.\n\n');
  25. const seen = new Set();
  26. // exclude emails from <ROOT>/AUTHORS file
  27. const excludeEmails = new Set([
  28. '<bot@renovateapp.com>',
  29. '<support@greenkeeper.io>',
  30. '<mail@sequelizejs.com>',
  31. '<bot@stepsecurity.io>',
  32. '<support@r2c.dev>',
  33. '<bot@sequelize.org>',
  34. ]);
  35. // Support regular git author metadata, as well as `Author:` and
  36. // `Co-authored-by:` in the message body. Both have been used in the past
  37. // to indicate multiple authors per commit, with the latter standardized
  38. // by GitHub now.
  39. const authorRe = /(^Author:|^Co-authored-by:)\s+(?<author>[^<]+)\s+(?<email><[^>]+>)/i;
  40. rl.on('line', line => {
  41. const match = line.match(authorRe);
  42. if (!match) {
  43. return;
  44. }
  45. const { author, email } = match.groups;
  46. const botRegex = /bot@users.noreply.github.com/g;
  47. const botEmail = email.replaceAll(/\[bot.*?\]/g, 'bot');
  48. if (seen.has(email) || excludeEmails.has(email) || botRegex.test(botEmail)) {
  49. return;
  50. }
  51. seen.add(email);
  52. output.write(`${author} ${email}\n`);
  53. });
  54. rl.on('close', () => {
  55. output.end('\n# Generated by dev/update-authors.js\n');
  56. });