blob: cf3633dc07c98551cd5e65043b2c5681c804c45a [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The relnote command summarizes the Go changes in Gerrit marked with
// RELNOTE annotations for the release notes.
package main
import (
"context"
"fmt"
"log"
"regexp"
"sort"
"strings"
"golang.org/x/build/maintner"
"golang.org/x/build/maintner/godata"
)
func main() {
corpus, err := godata.Get(context.Background())
if err != nil {
log.Fatal(err)
}
ger := corpus.Gerrit()
changes := map[string][]string{} // keyed by pkg
ger.ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
if gp.Server() != "go.googlesource.com" {
return nil
}
gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
if relnote := clRelNote(cl); relnote != "" {
subj := cl.Commit.Msg
if i := strings.Index(subj, "\n"); i != -1 {
subj = subj[:i]
}
pkg := "??"
if i := strings.Index(subj, ":"); i != -1 {
pkg = subj[:i]
}
if relnote != "yes" {
subj = relnote + ": " + subj
}
change := fmt.Sprintf("https://golang.org/cl/%d: %s", cl.Number, subj)
changes[pkg] = append(changes[pkg], change)
}
return nil
})
return nil
})
var pkgs []string
for pkg, lines := range changes {
pkgs = append(pkgs, pkg)
sort.Strings(lines)
}
sort.Strings(pkgs)
for _, pkg := range pkgs {
fmt.Printf("%s\n", pkg)
for _, change := range changes[pkg] {
fmt.Printf(" %s\n", change)
}
}
}
var relNoteRx = regexp.MustCompile(`RELNOTES?=(.+)`)
func parseRelNote(s string) string {
if m := relNoteRx.FindStringSubmatch(s); m != nil {
return m[1]
}
return ""
}
func clRelNote(cl *maintner.GerritCL) string {
msg := cl.Commit.Msg
if strings.Contains(msg, "RELNOTE") {
return parseRelNote(msg)
}
for _, comment := range cl.Messages {
if strings.Contains(comment.Message, "RELNOTE") {
return parseRelNote(comment.Message)
}
}
return ""
}