aboutsummaryrefslogtreecommitdiff
path: root/build.go
diff options
context:
space:
mode:
authorJakob Borg <jakob@kastelo.net>2020-06-02 10:40:45 +0100
committerGitHub <noreply@github.com>2020-06-02 11:40:45 +0200
commitb033c36b3173702afa5a97eed625d49e2593a3cd (patch)
tree168b66a8974cf23607c7a5ca536dcfd10766f70c /build.go
parentbfc94789653b2367b0a0335330bf6898232005ce (diff)
downloadsyncthing-b033c36b3173702afa5a97eed625d49e2593a3cd.tar.gz
syncthing-b033c36b3173702afa5a97eed625d49e2593a3cd.zip
build: Add "changelog" command (#6700)
Diffstat (limited to 'build.go')
-rw-r--r--build.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/build.go b/build.go
index 430fc24d4..3c0358019 100644
--- a/build.go
+++ b/build.go
@@ -49,6 +49,7 @@ var (
debugBinary bool
coverage bool
timeout = "120s"
+ numVersions = 5
)
type target struct {
@@ -333,6 +334,20 @@ func runCommand(cmd string, target target) {
case "version":
fmt.Println(getVersion())
+ case "changelog":
+ vers, err := currentAndLatestVersions(numVersions)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for _, ver := range vers {
+ underline := strings.Repeat("=", len(ver))
+ msg, err := tagMessage(ver)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("%s\n%s\n\n%s\n\n", ver, underline, msg)
+ }
+
default:
log.Fatalf("Unknown command %q", cmd)
}
@@ -351,6 +366,7 @@ func parseFlags() {
flag.StringVar(&cc, "cc", os.Getenv("CC"), "Set CC environment variable for `go build`")
flag.BoolVar(&debugBinary, "debug-binary", debugBinary, "Create unoptimized binary to use with delve, set -gcflags='-N -l' and omit -ldflags")
flag.BoolVar(&coverage, "coverage", coverage, "Write coverage profile of tests to coverage.txt")
+ flag.IntVar(&numVersions, "num-versions", numVersions, "Number of versions for changelog command")
flag.Parse()
}
@@ -1240,3 +1256,62 @@ func protobufVersion() string {
}
return string(bs)
}
+
+func currentAndLatestVersions(n int) ([]string, error) {
+ bs, err := runError("git", "tag", "--sort", "taggerdate")
+ if err != nil {
+ return nil, err
+ }
+
+ lines := strings.Split(string(bs), "\n")
+ reverseStrings(lines)
+
+ // The one at the head is the latest version. We always keep that one.
+ // Then we filter out remaining ones with dashes (pre-releases etc).
+
+ latest := lines[:1]
+ nonPres := filterStrings(lines[1:], func(s string) bool { return !strings.Contains(s, "-") })
+ vers := append(latest, nonPres...)
+ return vers[:n], nil
+}
+
+func reverseStrings(ss []string) {
+ for i := 0; i < len(ss)/2; i++ {
+ ss[i], ss[len(ss)-1-i] = ss[len(ss)-1-i], ss[i]
+ }
+}
+
+func filterStrings(ss []string, op func(string) bool) []string {
+ n := ss[:0]
+ for _, s := range ss {
+ if op(s) {
+ n = append(n, s)
+ }
+ }
+ return n
+}
+
+func tagMessage(tag string) (string, error) {
+ hash, err := runError("git", "rev-parse", tag)
+ if err != nil {
+ return "", err
+ }
+ obj, err := runError("git", "cat-file", "-p", string(hash))
+ if err != nil {
+ return "", err
+ }
+ return trimTagMessage(string(obj), tag), nil
+}
+
+func trimTagMessage(msg, tag string) string {
+ firstBlank := strings.Index(msg, "\n\n")
+ if firstBlank > 0 {
+ msg = msg[firstBlank+2:]
+ }
+ msg = strings.TrimPrefix(msg, tag)
+ beginSig := strings.Index(msg, "-----BEGIN PGP")
+ if beginSig > 0 {
+ msg = msg[:beginSig]
+ }
+ return strings.TrimSpace(msg)
+}