diff options
author | Jakob Borg <jakob@kastelo.net> | 2020-06-02 10:40:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-02 11:40:45 +0200 |
commit | b033c36b3173702afa5a97eed625d49e2593a3cd (patch) | |
tree | 168b66a8974cf23607c7a5ca536dcfd10766f70c /build.go | |
parent | bfc94789653b2367b0a0335330bf6898232005ce (diff) | |
download | syncthing-b033c36b3173702afa5a97eed625d49e2593a3cd.tar.gz syncthing-b033c36b3173702afa5a97eed625d49e2593a3cd.zip |
build: Add "changelog" command (#6700)
Diffstat (limited to 'build.go')
-rw-r--r-- | build.go | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -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) +} |