golang.org/x/playground@v0.0.0-20230418134305-14ebe15bcd59/cmd/latestgo/main.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // latestgo prints the latest Go release tag to stdout as a part of the playground deployment process. 6 package main 7 8 import ( 9 "context" 10 "flag" 11 "fmt" 12 "log" 13 "sort" 14 "strings" 15 "time" 16 17 "golang.org/x/build/gerrit" 18 "golang.org/x/build/maintner/maintnerd/maintapi/version" 19 ) 20 21 var prev = flag.Bool("prev", false, "whether to query the previous Go release, rather than the last (e.g. 1.17 versus 1.18)") 22 23 func main() { 24 client := gerrit.NewClient("https://go-review.googlesource.com", gerrit.NoAuth) 25 26 flag.Parse() 27 28 ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) 29 defer cancel() 30 31 tagInfo, err := client.GetProjectTags(ctx, "go") 32 if err != nil { 33 log.Fatalf("error retrieving project tags for 'go': %v", err) 34 } 35 36 if len(tagInfo) == 0 { 37 log.Fatalln("no project tags found for 'go'") 38 } 39 40 // Find the latest patch version for each major Go version. 41 type majMin struct { 42 maj, min int // maj, min in semver terminology, which corresponds to a major go release 43 } 44 type patchTag struct { 45 patch int 46 tag string // Go repo tag for this version 47 } 48 latestPatches := make(map[majMin]patchTag) // (maj, min) -> latest patch info 49 50 for _, tag := range tagInfo { 51 tagName := strings.TrimPrefix(tag.Ref, "refs/tags/") 52 maj, min, patch, ok := version.ParseTag(tagName) 53 if !ok { 54 continue 55 } 56 57 mm := majMin{maj, min} 58 if latest, ok := latestPatches[mm]; !ok || latest.patch < patch { 59 latestPatches[mm] = patchTag{patch, tagName} 60 } 61 } 62 63 var mms []majMin 64 for mm := range latestPatches { 65 mms = append(mms, mm) 66 } 67 sort.Slice(mms, func(i, j int) bool { 68 if mms[i].maj != mms[j].maj { 69 return mms[i].maj < mms[j].maj 70 } 71 return mms[i].min < mms[j].min 72 }) 73 74 var mm majMin 75 if *prev && len(mms) > 1 { 76 mm = mms[len(mms)-2] // latest patch of the previous Go release 77 } else { 78 mm = mms[len(mms)-1] 79 } 80 fmt.Print(latestPatches[mm].tag) 81 }