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  `