github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/dashboard/updater/updater.go (about) 1 // Copyright 2013 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 package main // import "golang.org/x/tools/dashboard/updater" 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "encoding/xml" 11 "flag" 12 "fmt" 13 "io/ioutil" 14 "net/http" 15 "net/url" 16 "os" 17 "os/exec" 18 "strings" 19 ) 20 21 var ( 22 builder = flag.String("builder", "", "builder name") 23 key = flag.String("key", "", "builder key") 24 gopath = flag.String("gopath", "", "path to go repo") 25 dashboard = flag.String("dashboard", "build.golang.org", "Go Dashboard Host") 26 batch = flag.Int("batch", 100, "upload batch size") 27 ) 28 29 // Do not benchmark beyond this commit. 30 // There is little sense in benchmarking till first commit, 31 // and the benchmark won't build anyway. 32 const Go1Commit = "0051c7442fed" // test/bench/shootout: update timing.log to Go 1. 33 34 // HgLog represents a single Mercurial revision. 35 type HgLog struct { 36 Hash string 37 Branch string 38 Files string 39 } 40 41 func main() { 42 flag.Parse() 43 logs := hgLog() 44 var hashes []string 45 ngo1 := 0 46 for i := range logs { 47 if strings.HasPrefix(logs[i].Hash, Go1Commit) { 48 break 49 } 50 if needsBenchmarking(&logs[i]) { 51 hashes = append(hashes, logs[i].Hash) 52 } 53 ngo1++ 54 } 55 fmt.Printf("found %v commits, %v after Go1, %v need benchmarking\n", len(logs), ngo1, len(hashes)) 56 for i := 0; i < len(hashes); i += *batch { 57 j := i + *batch 58 if j > len(hashes) { 59 j = len(hashes) 60 } 61 fmt.Printf("sending %v-%v... ", i, j) 62 res := postCommits(hashes[i:j]) 63 fmt.Printf("%s\n", res) 64 } 65 } 66 67 func hgLog() []HgLog { 68 var out bytes.Buffer 69 cmd := exec.Command("hg", "log", "--encoding=utf-8", "--template", xmlLogTemplate) 70 cmd.Dir = *gopath 71 cmd.Stdout = &out 72 cmd.Stderr = os.Stderr 73 err := cmd.Run() 74 if err != nil { 75 fmt.Printf("failed to execute 'hg log': %v\n", err) 76 os.Exit(1) 77 } 78 var top struct{ Log []HgLog } 79 err = xml.Unmarshal([]byte("<Top>"+out.String()+"</Top>"), &top) 80 if err != nil { 81 fmt.Printf("failed to parse log: %v\n", err) 82 os.Exit(1) 83 } 84 return top.Log 85 } 86 87 func needsBenchmarking(log *HgLog) bool { 88 if log.Branch != "" { 89 return false 90 } 91 for _, f := range strings.Split(log.Files, " ") { 92 if (strings.HasPrefix(f, "include") || strings.HasPrefix(f, "src")) && 93 !strings.HasSuffix(f, "_test.go") && !strings.Contains(f, "testdata") { 94 return true 95 } 96 } 97 return false 98 } 99 100 func postCommits(hashes []string) string { 101 args := url.Values{"builder": {*builder}, "key": {*key}} 102 cmd := fmt.Sprintf("http://%v/updatebenchmark?%v", *dashboard, args.Encode()) 103 b, err := json.Marshal(hashes) 104 if err != nil { 105 return fmt.Sprintf("failed to encode request: %v\n", err) 106 } 107 r, err := http.Post(cmd, "text/json", bytes.NewReader(b)) 108 if err != nil { 109 return fmt.Sprintf("failed to send http request: %v\n", err) 110 } 111 defer r.Body.Close() 112 if r.StatusCode != http.StatusOK { 113 return fmt.Sprintf("http request failed: %v\n", r.Status) 114 } 115 resp, err := ioutil.ReadAll(r.Body) 116 if err != nil { 117 return fmt.Sprintf("failed to read http response: %v\n", err) 118 } 119 return string(resp) 120 } 121 122 const xmlLogTemplate = ` 123 <Log> 124 <Hash>{node|escape}</Hash> 125 <Branch>{branches}</Branch> 126 <Files>{files}</Files> 127 </Log> 128 `