-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
105 lines (95 loc) · 2.59 KB
/
main.go
File metadata and controls
105 lines (95 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"log"
"os"
"os/exec"
"sort"
"strings"
)
const Version = "0.4"
func init() {
flag.Usage = func() {
os.Stderr.WriteString(`write_mailmap
Runs 'git log' on your codebase, rewriting commit authors using a .mailmap file
if it exists, and deduplicates any authors that are present. The sorted list
of authors is printed to stdout.
`)
flag.PrintDefaults()
}
}
// parseCoAuthors scans commit message bodies for "Co-Authored-By:" trailers
// and returns any new authors not already present in seenAuthors. Found authors
// are added to seenAuthors as a side effect.
func parseCoAuthors(body []byte, seenAuthors map[string]bool) []string {
var authors []string
scanner := bufio.NewScanner(bytes.NewReader(body))
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// Match "Co-Authored-By:" case-insensitively.
if len(line) < len("Co-Authored-By:") {
continue
}
if !strings.EqualFold(line[:len("Co-Authored-By:")], "Co-Authored-By:") {
continue
}
author := strings.TrimSpace(line[len("Co-Authored-By:"):])
if author == "" {
continue
}
lowerAuthor := strings.ToLower(author)
if seenAuthors[lowerAuthor] {
continue
}
authors = append(authors, author)
seenAuthors[lowerAuthor] = true
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
return authors
}
func main() {
var version = flag.Bool("version", false, "Print the version string and exit")
flag.Parse()
if flag.Arg(0) == "version" || *version {
fmt.Fprintf(os.Stderr, "write_mailmap version %s\n", Version)
os.Exit(2)
}
cmd := exec.Command("git", "log", "--use-mailmap", "--format='%aN <%aE>'")
bits, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
seenAuthors := make(map[string]bool)
authors := make([]string, 0)
scanner := bufio.NewScanner(bytes.NewReader(bits))
for scanner.Scan() {
author := strings.Trim(strings.TrimSpace(scanner.Text()), "'")
lowerAuthor := strings.ToLower(author)
if _, ok := seenAuthors[lowerAuthor]; ok {
continue
} else {
authors = append(authors, author)
}
seenAuthors[lowerAuthor] = true
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
// Also parse Co-Authored-By trailers from commit messages.
coAuthorCmd := exec.Command("git", "log", "--use-mailmap", "--format=%B")
coAuthorBits, err := coAuthorCmd.Output()
if err != nil {
log.Fatal(err)
}
coAuthors := parseCoAuthors(coAuthorBits, seenAuthors)
authors = append(authors, coAuthors...)
sort.Strings(authors)
if _, err := os.Stdout.WriteString(strings.Join(authors, "\n") + "\n"); err != nil {
log.Fatal(err)
}
}