From d8366e4a886e328f38a3d58c8696868e4aa165a2 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 23 Jul 2018 17:41:59 +0200 Subject: [PATCH] authors: Enable auto updates (#5074) Removes the manual handling of the AUTHORS file, giving every committer automatic credit for their contribution. Manual tweaks to the file are still accepted and retained by the scripts. --- .github/PULL_REQUEST_TEMPLATE.md | 13 +- AUTHORS | 57 ++++++- build.sh | 4 +- .../syncthing/core/aboutModalView.html | 2 +- meta/authors_test.go | 150 ------------------ script/authors.go | 117 +++++++++++++- 6 files changed, 172 insertions(+), 171 deletions(-) delete mode 100644 meta/authors_test.go diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5cf767536..3efacd824 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -20,13 +20,8 @@ If this is a user visible change (including API and protocol changes), add a lin to the corresponding pull request on https://github.com/syncthing/docs or describe the documentation changes necessary. -### Authorship +## Authorship + +Your name and email will be added automatically to the AUTHORS file +based on the commit metadata. -Every author of a code contribution (Go, Javascript, HTML, CSS etc, with the -possible exception of minor typo corrections and similar) is recorded in the -AUTHORS and NICKS files and the in-GUI credits. If this is your first -contribution, a maintainer will add you properly before accepting the -contribution. You need not do so yourself or worry about the fact that the -"authors" automated test fails. However, if your name (such as you want it -presented in the credits) is not visible on your Github profile or in your -commit messages, please assist by providing it here. diff --git a/AUTHORS b/AUTHORS index 82e555a2b..db1f323c5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,16 @@ # This is the official list of Syncthing authors for copyright purposes. -# The format is: +# +# THIS FILE IS MOSTLY AUTO GENERATED. IF YOU'VE MADE A COMMIT TO THE +# REPOSITORY YOU WILL BE ADDED HERE AUTOMATICALLY WITHOUT THE NEED FOR +# ANY MANUAL ACTION. +# +# That said, you are welcome to correct your name or add a nickname / GitHub +# user name as appropriate. The format is: # # Name Name Name (nickname) # -# After changing this list, run "go run script/authors.go" to sort and update -# the GUI HTML. +# The in-GUI authors list is periodically automatically updated from the +# contents of this file. # Aaron Bieber (qbit) @@ -14,11 +20,14 @@ Alessandro G. (alessandro.g89) Alexander Graf (alex2108) Alexandre Viau (aviau) Anderson Mesquita (andersonvom) +andresvia Andrew Dunham (andrew-d) -Andrew Rabert (nvllsvm) -Andrey D (scienmind) +Andrew Rabert (nvllsvm) <6550543+nvllsvm@users.noreply.github.com> +Andrey D (scienmind) +andyleap Antoine Lamielle (0x010C) Antony Male (canton7) +Aranjedeath Arthur Axel fREW Schmidt (frioux) Audrius Butkevicius (AudriusButkevicius) Bart De Vries (mogwa1) @@ -27,17 +36,21 @@ Ben Schulz (uok) Ben Shepherd (benshep) Ben Sidhom (bsidhom) Benedikt Heine (bebehei) +Benedikt Morbach Benny Ng (tpng) Brandon Philips (philips) Brendan Long (brendanlong) Brian R. Becker (brbecker) Caleb Callaway (cqcallaw) Carsten Hagemann (Moter8) -Cathryne Linenweaver (Cathryne) +Cathryne Linenweaver (Cathryne) Cedric Staniewski (xduugu) Chris Howie (cdhowie) Chris Joel (cdata) +Chris Tonkinson +chucic Colin Kennedy (moshen) +Dale Visser Daniel Bergmann (brgmnn) Daniel Harte (norgeous) Daniel Martí (mvdan) @@ -45,9 +58,11 @@ Darshil Chanpura (dtchanpura) David Rimmer (dinosore) Denis A. (dva) Dennis Wilson (snnd) +derekriemer Dmitry Saveliev (dsaveliev) Dominik Heidler (asdil12) Elias Jarlebring (jarlebring) +Elliot Huffman Emil Hessman (ceh) Erik Meitner (WSGCSysadmin) Federico Castagnini (facastagnini) @@ -57,29 +72,38 @@ Francois-Xavier Gsell (zukoo) Frank Isemann (fti7) Gilli Sigurdsson (gillisig) Graham Miln (grahammiln) +Han Boetes Harrison Jones (harrisonhjones) Heiko Zuerker (Smiley73) +Iain Barnett Ian Johnson (anonymouse64) Jaakko Hannikainen (jgke) Jacek Szafarkiewicz (hadogenes) Jake Peterson (acogdev) Jakob Borg (calmh) James Patterson (jpjp) +janost Jaroslav Malec (dzarda) +jaseg Jaya Chithra (jayachithra) Jens Diemer (jedie) Jerry Jacobs (xor-gate) Jochen Voss (seehuhn) +Johan Andersson Johan Vromans (sciurius) John Rinehart (fuzzybear3965) +Jonathan Cross Jose Manuel Delicado (jmdaweb) Karol Różycki (krozycki) +Keith Turner Kelong Cong (kc1212) Ken'ichi Kamada (kamadak) Kevin Allen (ironmig) Kevin White, Jr. (kwhite17) +klemens Kurt Fitzner (Kudalufi) Lars K.W. Gohlke (lkwg82) +Laurent Arnoud Laurent Etiemble (letiemble) Leo Arias (elopio) Liu Siyuan (liusy182) @@ -89,50 +113,71 @@ Majed Abdulaziz (majedev) Marc Laporte (marclaporte) Marc Pujol (kilburn) Marcin Dziadus (marcindziadus) +marco-m Mark Pulford (mpx) Mateusz Naściszewski (mateon1) +Matic Potočnik Matt Burke (burkemw3) +Matteo Ruina Max Schulze (kralo) +MaximAL +Maxime Thirouin Michael Jephcote (Rewt0r) Michael Ploujnikov (plouj) Michael Tilli (pyfisch) +Mike Boone +MikeLund Nate Morrison (nrm21) Nicholas Rishel (PrototypeNM1) +Nicolas Braud-Santoni Niels Peter Roest (Niller303) Nils Jakobi (thunderstorm99) +NoLooseEnds Pascal Jungblut (pascalj) Pawel Palenica (qepasa) +perewa +Peter Dave Hello Peter Hoeg (peterhoeg) Peter Marquardt (wwwutz) +Phil Davis Philippe Schommers (filoozoom) Phill Luby (pluby) +Pier Paolo Ramon Piotr Bejda (piobpl) Pramodh KP (pramodhkp) <1507241+pramodhkp@users.noreply.github.com> +Richard Hartmann Robert Carosi (nov1n) Roman Zaynetdinov (zaynetro) Ross Smith II (rasa) +rubenbe Ryan Sullivan (KayoticSully) Sacheendra Talluri (sacheendra) Scott Klupfel (kluppy) Sergey Mishin (ralder) Simon Frei (imsodin) +Sly_tom_cat Stefan Kuntz (Stefan-Code) Stefan Tatschner (rumpelsepp) Suhas Gundimeda (snugghash) Taylor Khan (nelsonkhan) +Thomas Hipp Tim Abell (timabell) Tim Howes (timhowes) Tobias Nygren (tnn2) Tobias Tom (tobiastom) Tomas Cerveny (kozec) +Tommy Thorn Tully Robinson (tojrobinson) Tyler Brazier (tylerbrazier) Unrud (Unrud) Veeti Paananen (veeti) Victor Buinsky (buinsky) Vil Brekin (Vilbrekin) +Vladimir Rusinov +wangguoliang William A. Kennington III (wkennington) Wulf Weich (wweich) Xavier O. (damajor) xjtdy888 (xjtdy888) Yannic A. (eipiminus1) +佛跳墙 diff --git a/build.sh b/build.sh index db64b655f..23f8d221d 100755 --- a/build.sh +++ b/build.sh @@ -59,8 +59,8 @@ case "${1:-default}" in go run script/authors.go build transifex pushd man ; ./refresh.sh ; popd - git add -A gui man - git commit -m 'gui, man: Update docs & translations' + git add -A gui man AUTHORS + git commit -m 'gui, man, authors: Update docs, translations, and contributors' ;; noupgrade) diff --git a/gui/default/syncthing/core/aboutModalView.html b/gui/default/syncthing/core/aboutModalView.html index ad5ed8c2a..8a5a22910 100644 --- a/gui/default/syncthing/core/aboutModalView.html +++ b/gui/default/syncthing/core/aboutModalView.html @@ -12,7 +12,7 @@

Copyright © 2014-2017 the following Contributors:

-Jakob Borg, Audrius Butkevicius, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, Aaron Bieber, Adam Piggott, Adel Qalieh, Alessandro G., Andrew Dunham, Andrew Rabert, Andrey D, Antoine Lamielle, Arthur Axel fREW Schmidt, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benny Ng, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chris Howie, Chris Joel, Colin Kennedy, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dmitry Saveliev, Dominik Heidler, Elias Jarlebring, Emil Hessman, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Graham Miln, Harrison Jones, Heiko Zuerker, Ian Johnson, Jaakko Hannikainen, Jacek Szafarkiewicz, Jake Peterson, James Patterson, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Vromans, John Rinehart, Jose Manuel Delicado, Karol Różycki, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin White, Jr., Kurt Fitzner, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Mark Pulford, Mateusz Naściszewski, Matt Burke, Max Schulze, Michael Jephcote, Michael Tilli, Nicholas Rishel, Niels Peter Roest, Nils Jakobi, Pascal Jungblut, Pawel Palenica, Peter Hoeg, Peter Marquardt, Phill Luby, Piotr Bejda, Pramodh KP, Robert Carosi, Roman Zaynetdinov, Ross Smith II, Sacheendra Talluri, Scott Klupfel, Stefan Kuntz, Suhas Gundimeda, Taylor Khan, Tim Abell, Tim Howes, Tobias Nygren, Tobias Tom, Tomas Cerveny, Tully Robinson, Tyler Brazier, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, William A. Kennington III, Xavier O., Yannic A., xjtdy888 +Jakob Borg, Audrius Butkevicius, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Wulf Weich, Aaron Bieber, Adam Piggott, Adel Qalieh, Alessandro G., Andrew Dunham, Andrew Rabert, Andrey D, Antoine Lamielle, Aranjedeath, Arthur Axel fREW Schmidt, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benny Ng, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne, Cathryne Linenweaver, Cedric Staniewski, Chris Howie, Chris Joel, Chris Tonkinson, Colin Kennedy, Dale Visser, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Dmitry Saveliev, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Erik Meitner, Federico Castagnini, Felix Ableitner, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gilli Sigurdsson, Graham Miln, Han Boetes, Harrison Jones, Heiko Zuerker, Iain Barnett, Ian Johnson, Jaakko Hannikainen, Jacek Szafarkiewicz, Jake Peterson, James Patterson, Jaroslav Malec, Jaya Chithra, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonathan Cross, Jose Manuel Delicado, Karol Różycki, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin White, Jr., Kurt Fitzner, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Mark Pulford, Mateusz Naściszewski, Matic Potočnik, Matt Burke, Matteo Ruina, Max Schulze, MaximAL, Maxime Thirouin, Michael Jephcote, Michael Tilli, Mike Boone, MikeLund, Nicholas Rishel, Nicolas Braud-Santoni, Niels Peter Roest, Nils Jakobi, NoLooseEnds, Pascal Jungblut, Pawel Palenica, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Richard Hartmann, Robert Carosi, Roman Zaynetdinov, Ross Smith II, Sacheendra Talluri, Scott Klupfel, Sly_tom_cat, Stefan Kuntz, Suhas Gundimeda, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Nygren, Tobias Tom, Tomas Cerveny, Tommy Thorn, Tully Robinson, Tyler Brazier, Unrud, Veeti Paananen, Victor Buinsky, Vil Brekin, Vladimir Rusinov, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, chucic, derekriemer, janost, jaseg, klemens, marco-m, perewa, rubenbe, scienmind, wangguoliang, xjtdy888, 佛跳墙

diff --git a/meta/authors_test.go b/meta/authors_test.go deleted file mode 100644 index 292639725..000000000 --- a/meta/authors_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2015 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at https://mozilla.org/MPL/2.0/. - -// Checks for authors that are not mentioned in AUTHORS -package meta - -import ( - "bytes" - "io/ioutil" - "os/exec" - "regexp" - "strings" - "testing" -) - -// list of commits that we don't include in our checks; because they are -// legacy things that don't check code, are committed with incorrect address, -// or for other reasons. -var excludeCommits = stringSetFromStrings([]string{ - "63bd0136fb40a91efaa279cb4b4159d82e8e6904", - "4e2feb6fbc791bb8a2daf0ab8efb10775d66343e", - "f2459ef3319b2f060dbcdacd0c35a1788a94b8bd", - "b61f418bf2d1f7d5a9d7088a20a2a448e5e66801", - "a9339d0627fff439879d157c75077f02c9fac61b", - "254c63763a3ad42fd82259f1767db526cff94a14", - "4b76ec40c07078beaa2c5e250ed7d9bd6276a718", - "32a76901a91ff0f663db6f0830e0aedec946e4d0", - "3626003f680bad3e63677982576d3a05421e88e9", - "342036408e65bd25bb6afbcc705e2e2c013bb01f", - "e37cefdbee1c1cd95ad095b5da6d1252723f103b", - "bcc5d7c00f52552303b463d43a636f27b7f7e19b", - "bc7639b0ffcea52b2197efb1c0bb68b338d1c915", -}) - -func TestCheckAuthors(t *testing.T) { - if testing.Short() { - t.Skip("skipping slow test") - } - - actual, hashes := actualAuthorEmails(t, ".", "../cmd/", "../lib/", "../gui/", "../test/", "../script/") - listed := listedAuthorEmails(t) - missing := actual.except(listed) - for author := range missing { - t.Logf("Missing author: %s", author) - for _, hash := range hashes[author] { - t.Logf(" in hash: %s", hash) - } - } - if len(missing) > 0 { - t.Errorf("Missing %d author(s)", len(missing)) - } -} - -// actualAuthorEmails returns the set of author emails found in the actual git -// commit log, except those in excluded commits. -func actualAuthorEmails(t *testing.T, paths ...string) (stringSet, map[string][]string) { - args := append([]string{"log", "--format=%H %ae"}, paths...) - cmd := exec.Command("git", args...) - bs, err := cmd.Output() - if err != nil { - t.Fatal("authorEmails:", err) - } - - hashes := make(map[string][]string) - authors := newStringSet() - for _, line := range bytes.Split(bs, []byte{'\n'}) { - fields := strings.Fields(string(line)) - if len(fields) != 2 { - continue - } - - hash, author := fields[0], fields[1] - if excludeCommits.has(hash) { - continue - } - - if strings.Contains(strings.ToLower(body(t, hash)), "skip-check: authors") { - continue - } - - authors.add(author) - hashes[author] = append(hashes[author], hash) - } - - return authors, hashes -} - -// listedAuthorEmails returns the set of author emails mentioned in AUTHORS -func listedAuthorEmails(t *testing.T) stringSet { - bs, err := ioutil.ReadFile("../AUTHORS") - if err != nil { - t.Fatal("listedAuthorEmails:", err) - } - - emailRe := regexp.MustCompile(`<([^>]+)>`) - matches := emailRe.FindAllStringSubmatch(string(bs), -1) - - authors := newStringSet() - for _, match := range matches { - authors.add(match[1]) - } - return authors -} - -func body(t *testing.T, hash string) string { - cmd := exec.Command("git", "show", "--pretty=format:%b", "-s", hash) - bs, err := cmd.Output() - if err != nil { - t.Fatal("body:", err) - } - return string(bs) -} - -// A simple string set type - -type stringSet map[string]struct{} - -func newStringSet() stringSet { - return make(stringSet) -} - -func stringSetFromStrings(ss []string) stringSet { - s := newStringSet() - for _, e := range ss { - s.add(e) - } - return s -} - -func (s stringSet) add(e string) { - s[e] = struct{}{} -} - -func (s stringSet) has(e string) bool { - _, ok := s[e] - return ok -} - -func (s stringSet) except(other stringSet) stringSet { - diff := newStringSet() - for e := range s { - if !other.has(e) { - diff.add(e) - } - } - return diff -} diff --git a/script/authors.go b/script/authors.go index 9336861f7..66ffe7123 100644 --- a/script/authors.go +++ b/script/authors.go @@ -32,12 +32,18 @@ var ( ) const authorsHeader = `# This is the official list of Syncthing authors for copyright purposes. -# The format is: +# +# THIS FILE IS MOSTLY AUTO GENERATED. IF YOU'VE MADE A COMMIT TO THE +# REPOSITORY YOU WILL BE ADDED HERE AUTOMATICALLY WITHOUT THE NEED FOR +# ANY MANUAL ACTION. +# +# That said, you are welcome to correct your name or add a nickname / GitHub +# user name as appropriate. The format is: # # Name Name Name (nickname) # -# After changing this list, run "go run script/authors.go" to sort and update -# the GUI HTML. +# The in-GUI authors list is periodically automatically updated from the +# contents of this file. # ` @@ -50,8 +56,42 @@ type author struct { } func main() { + // Read authors from the AUTHORS file authors := getAuthors() + // Grab the set of thus known email addresses + listed := make(stringSet) + names := make(map[string]int) + for i, a := range authors { + names[a.name] = i + for _, e := range a.emails { + listed.add(e) + } + } + + // Grab the set of all known authors based on the git log, and add any + // missing ones to the authors list. + all := allAuthors() + for email, name := range all { + if listed.has(email) { + continue + } + + if _, ok := names[name]; ok && name != "" { + // We found a match on name + authors[names[name]].emails = append(authors[names[name]].emails, email) + listed.add(email) + continue + } + + authors = append(authors, author{ + name: name, + emails: []string{email}, + }) + names[name] = len(authors) - 1 + listed.add(email) + } + // Write author names in GUI about modal getContributions(authors) @@ -167,6 +207,46 @@ next: } } +// list of commits that we don't include in our author file; because they +// are legacy things that don't affect code, are committed with incorrect +// address, or for other reasons. +var excludeCommits = stringSetFromStrings([]string{ + "a9339d0627fff439879d157c75077f02c9fac61b", + "254c63763a3ad42fd82259f1767db526cff94a14", + "32a76901a91ff0f663db6f0830e0aedec946e4d0", + "bc7639b0ffcea52b2197efb1c0bb68b338d1c915", +}) + +// allAuthors returns the set of authors in the git commit log, except those +// in excluded commits. +func allAuthors() map[string]string { + args := append([]string{"log", "--format=%H %ae %an"}) + cmd := exec.Command("git", args...) + bs, err := cmd.Output() + if err != nil { + log.Fatal("git:", err) + } + + names := make(map[string]string) + for _, line := range bytes.Split(bs, []byte{'\n'}) { + fields := strings.SplitN(string(line), " ", 3) + if len(fields) != 3 { + continue + } + hash, email, name := fields[0], fields[1], fields[2] + + if excludeCommits.has(hash) { + continue + } + + if names[email] == "" { + names[email] = name + } + } + + return names +} + type byContributions []author func (l byContributions) Len() int { return len(l) } @@ -194,3 +274,34 @@ func (l byName) Less(a, b int) bool { } func (l byName) Swap(a, b int) { l[a], l[b] = l[b], l[a] } + +// A simple string set type + +type stringSet map[string]struct{} + +func stringSetFromStrings(ss []string) stringSet { + s := make(stringSet) + for _, e := range ss { + s.add(e) + } + return s +} + +func (s stringSet) add(e string) { + s[e] = struct{}{} +} + +func (s stringSet) has(e string) bool { + _, ok := s[e] + return ok +} + +func (s stringSet) except(other stringSet) stringSet { + diff := make(stringSet) + for e := range s { + if !other.has(e) { + diff.add(e) + } + } + return diff +}