Louis-Rémi Babé <lrbabe@gmail.com>
Robert Katić <robert.katic@gmail.com>
Damian Janowski <damian.janowski@gmail.com>
-Anton Kovalyov <anton@kovalyov.net>
Dušan B. Jovanovic <dbjdbj@gmail.com>
Earle Castledine <mrspeaker@gmail.com>
Rich Dougherty <rich@rd.gen.nz>
Colin Snover <github.com@zetafleet.com>
Jared Grippe <jared@deadlyicon.com>
Ryan W Tenney <ryan@10e.us>
-Alex Sexton <AlexSexton@gmail.com>
Pinhook <contact@pinhooklabs.com>
Ron Otten <r.j.g.otten@gmail.com>
Jephte Clain <Jephte.Clain@univ-reunion.fr>
Anton Matzneller <obhvsbypqghgc@gmail.com>
+Alex Sexton <AlexSexton@gmail.com>
Dan Heberden <danheberden@gmail.com>
Henri Wiechers <hwiechers@gmail.com>
Russell Holbrook <russell.holbrook@patch.com>
Brandon Sterne <bsterne@mozilla.com>
Mathias Bynens <mathias@qiwi.be>
Lee Carpenter <elcarpie@gmail.com>
-Timmy Willison <4timmywil@gmail.com>
+Timmy Willison <timmywil@users.noreply.github.com>
Corey Frang <gnarf37@gmail.com>
Digitalxero <digitalxero>
+Anton Kovalyov <anton@kovalyov.net>
David Murdoch <david@davidmurdoch.com>
Josh Varner <josh.varner@gmail.com>
Charles McNulty <cmcnulty@kznf.com>
Greg Hazel <ghazel@gmail.com>
Schalk Neethling <schalk@ossreleasefeed.com>
Denis Knauf <Denis.Knauf@gmail.com>
-Timo Tijhof <krinklemail@gmail.com>
+Timo Tijhof <krinkle@fastmail.com>
Steen Nielsen <swinedk@gmail.com>
Anton Ryzhov <anton@ryzhov.me>
Shi Chuan <shichuanr@gmail.com>
Marcel Greter <marcel.greter@ocbnet.ch>
Elijah Manor <elijah.manor@gmail.com>
Daniel Chatfield <chatfielddaniel@gmail.com>
-Daniel Gálvez <dgalvez@editablething.com>
Nikita Govorov <nikita.govorov@gmail.com>
Wesley Walser <waw325@gmail.com>
Mike Pennisi <mike@mikepennisi.com>
Callum Macrae <callum@lynxphp.com>
Jonathan Sampson <jjdsampson@gmail.com>
Benjamin Truyman <bentruyman@gmail.com>
-Jay Merrifield <fracmak@gmail.com>
James Huston <james@jameshuston.net>
-Sai Lung Wong <sai.wong@huffingtonpost.com>
Erick Ruiz de Chávez <erickrdch@gmail.com>
David Bonner <dbonner@cogolabs.com>
Allen J Schmidt Jr <cobrasoft@gmail.com>
Carl Danley <carldanley@gmail.com>
Mike Petrovich <michael.c.petrovich@gmail.com>
Greg Lavallee <greglavallee@wapolabs.com>
+Daniel Gálvez <dgalvez@editablething.com>
+Sai Lung Wong <sai.wong@huffingtonpost.com>
Tom H Fuertes <TomFuertes@gmail.com>
Roland Eckl <eckl.roland@googlemail.com>
+Jay Merrifield <fracmak@gmail.com>
Yiming He <yiminghe@gmail.com>
David Fox <dfoxinator@gmail.com>
Bennett Sorbo <bsorbo@gmail.com>
Jean Boussier <jean.boussier@gmail.com>
Andrew Plummer <plummer.andrew@gmail.com>
Mark Raddatz <mraddatz@gmail.com>
-Pascal Borreli <pascal@borreli.com>
Isaac Z. Schlueter <i@izs.me>
Karl Sieburg <ksieburg@yahoo.com>
+Pascal Borreli <pascal@borreli.com>
Nguyen Phuc Lam <ruado1987@gmail.com>
Dmitry Gusev <dmitry.gusev@gmail.com>
Steven Benner <admin@stevenbenner.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Renato Oliveira dos Santos <ros3@cin.ufpe.br>
Frederic Junod <frederic.junod@camptocamp.com>
-Tom H Fuertes <tomfuertes@gmail.com>
Mitch Foley <mitch@thefoley.net>
ros3cin <ros3@cin.ufpe.br>
Kyle Robinson Young <kyle@dontkry.com>
Nazar Mokrynskyi <nazar@mokrynskyi.com>
Benjamin Tan <demoneaux@gmail.com>
Amit Merchant <bullredeyes@gmail.com>
-Jason Bedard <jason+github@jbedard.ca>
Veaceslav Grimalschi <grimalschi@yandex.ru>
Richard McDaniel <rm0026@uah.edu>
Arthur Verschaeve <contact@arthurverschaeve.be>
Colin Frick <colin@bash.li>
Winston Howes <winstonhowes@gmail.com>
Alexander O'Mara <me@alexomara.com>
-Chris Rebert <github@rebertia.com>
Bastian Buchholz <buchholz.bastian@googlemail.com>
Mu Haibao <mhbseal@163.com>
Calvin Metcalf <calvin.metcalf@gmail.com>
Arthur Stolyar <nekr.fabula@gmail.com>
Gabriel Schulhof <gabriel.schulhof@intel.com>
+Chris Rebert <github@rebertia.com>
Gilad Peleg <giladp007@gmail.com>
Julian Alexander Murillo <julian.alexander.murillo@gmail.com>
Kevin Kirsche <Kev.Kirsche+GitHub@gmail.com>
Tom von Clef <thomas.vonclef@gmail.com>
Liza Ramo <liza.h.ramo@gmail.com>
Joelle Fleurantin <joasqueeniebee@gmail.com>
-Steve Mao <maochenyan@gmail.com>
Jon Dufresne <jon.dufresne@gmail.com>
Jae Sung Park <alberto.park@gmail.com>
Josh Soref <apache@soref.com>
-Saptak Sengupta <saptak013@gmail.com>
Henry Wong <henryw4k@gmail.com>
Jun Sun <klsforever@gmail.com>
Martijn W. van der Lee <martijn@vanderlee.com>
Devin Wilson <dwilson6.github@gmail.com>
+Steve Mao <maochenyan@gmail.com>
Damian Senn <jquery@topaxi.codes>
Zack Hall <zackhall@outlook.com>
Vitaliy Terziev <vitaliyterziev@gmail.com>
Henry Zhu <hi@henryzoo.com>
Nilton Cesar <niltoncms@gmail.com>
basil.belokon <basil.belokon@gmail.com>
+Saptak Sengupta <saptak013@gmail.com>
Andrey Meshkov <ay.meshkov@gmail.com>
tmybr11 <tomas.perone@gmail.com>
Luis Emilio Velasco Sanchez <emibloque@gmail.com>
Sébastien Règne <regseb@users.noreply.github.com>
wartmanm <3869625+wartmanm@users.noreply.github.com>
Siddharth Dungarwal <sd5869@gmail.com>
-abnud1 <ahmad13932013@hotmail.com>
Andrei Fangli <andrei_fangli@outlook.com>
Marja Hölttä <marja.holtta@gmail.com>
+abnud1 <ahmad13932013@hotmail.com>
buddh4 <mail@jharrer.de>
Hoang <dangkyokhoang@gmail.com>
+Sean Robinson <sean.robinson@scottsdalecc.edu>
Wonseop Kim <wonseop.kim@samsung.com>
Pat O'Callaghan <patocallaghan@gmail.com>
JuanMa Ruiz <ruizjuanma@gmail.com>
Ahmed.S.ElAfifi <ahmed.s.elafifi@gmail.com>
-Sean Robinson <sean.robinson@scottsdalecc.edu>
Christian Oliff <christianoliff@pm.me>
+Christian Wenz <christian@wenz.org>
+Jonathan <vanillajonathan@users.noreply.github.com>
+Ed Sanders <ejsanders@gmail.com>
+Pierre Grimaud <grimaud.pierre@gmail.com>
+Beatriz Rezener <beatrizrezener@users.noreply.github.com>
+Necmettin Karakaya <necmettin.karakaya@gmail.com>
+Wonhyoung Park <wh05.park@samsung.com>
+Dallas Fraser <dallas.fraser.waterloo@gmail.com>
+高灰 <www@zeroplace.cn>
+fecore1 <89127124+fecore1@users.noreply.github.com>
+ygj6 <7699524+ygj6@users.noreply.github.com>
+Bruno PIERRE <brunopierre4@yahoo.fr>
+Simon Legner <Simon.Legner@gmail.com>
+Baoshuo Ren <i@baoshuo.ren>
+Anders Kaseorg <andersk@mit.edu>
+Alex <aleksandrosansan@gmail.com>
+Gabriela Gutierrez <gabigutierrez@google.com>
+Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com>
--- /dev/null
+"use strict";
+
+const fs = require( "node:fs" );
+const util = require( "node:util" );
+const exec = util.promisify( require( "node:child_process" ).exec );
+const rnewline = /\r?\n/;
+const rdate = /^\[(\d+)\] /;
+
+const ignore = [
+ /dependabot\[bot\]/
+];
+
+function compareAuthors( a, b ) {
+ const aName = a.replace( rdate, "" ).replace( / <.*>/, "" );
+ const bName = b.replace( rdate, "" ).replace( / <.*>/, "" );
+ return aName === bName;
+}
+
+function uniq( arr ) {
+ const unique = [];
+ for ( const item of arr ) {
+ if ( ignore.some( re => re.test( item ) ) ) {
+ continue;
+ }
+ if ( item && !unique.find( ( e ) => compareAuthors( e, item ) ) ) {
+ unique.push( item );
+ }
+ }
+ return unique;
+}
+
+function cleanupSizzle() {
+ console.log( "Cleaning up..." );
+ return exec( "npx rimraf .sizzle" );
+}
+
+function cloneSizzle() {
+ console.log( "Cloning Sizzle..." );
+ return exec( "git clone https://github.com/jquery/sizzle .sizzle" );
+}
+
+async function getLastAuthor() {
+ const authorsTxt = await fs.promises.readFile( "AUTHORS.txt", "utf8" );
+ return authorsTxt.trim().split( rnewline ).pop();
+}
+
+async function logAuthors( preCommand ) {
+ let command = "git log --pretty=format:\"[%at] %aN <%aE>\"";
+ if ( preCommand ) {
+ command = `${ preCommand } && ${ command }`;
+ }
+ const { stdout } = await exec( command );
+ return uniq( stdout.trim().split( rnewline ).reverse() );
+}
+
+async function getSizzleAuthors() {
+ await cloneSizzle();
+ const authors = await logAuthors( "cd .sizzle" );
+ await cleanupSizzle();
+ return authors;
+}
+
+function sortAuthors( a, b ) {
+ const [ , aDate ] = rdate.exec( a );
+ const [ , bDate ] = rdate.exec( b );
+ return Number( aDate ) - Number( bDate );
+}
+
+function formatAuthor( author ) {
+ return author.replace( rdate, "" );
+}
+
+async function getAuthors() {
+ console.log( "Getting authors..." );
+ const authors = await logAuthors();
+ const sizzleAuthors = await getSizzleAuthors();
+ return uniq( authors.concat( sizzleAuthors ) ).sort( sortAuthors ).map( formatAuthor );
+}
+
+async function checkAuthors() {
+ const authors = await getAuthors();
+ const lastAuthor = await getLastAuthor();
+
+ if ( authors[ authors.length - 1 ] !== lastAuthor ) {
+ console.log( "AUTHORS.txt: ", lastAuthor );
+ console.log( "Last 20 in git: ", authors.slice( -20 ) );
+ throw new Error( "Last author in AUTHORS.txt does not match last git author" );
+ }
+ console.log( "AUTHORS.txt is up to date" );
+}
+
+async function updateAuthors() {
+ const authors = await getAuthors();
+
+ const authorsTxt = "Authors ordered by first contribution.\n\n" + authors.join( "\n" ) + "\n";
+ await fs.promises.writeFile( "AUTHORS.txt", authorsTxt );
+
+ console.log( "AUTHORS.txt updated" );
+}
+
+module.exports = {
+ checkAuthors,
+ getAuthors,
+ updateAuthors
+};