зеркало из https://github.com/golang/build.git
cmd/release: build race detector, godoc, cover, and vet
Change-Id: Iec3edcfdadedee882866c7747e84bb119d5ab591 Reviewed-on: https://go-review.googlesource.com/3881 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Родитель
84aecb26fb
Коммит
319667fbcf
|
@ -13,7 +13,9 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -25,23 +27,61 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
revision = flag.String("rev", "", "Go revision to build")
|
||||
rev = flag.String("rev", "", "Go revision to build")
|
||||
toolsRev = flag.String("tools", "", "Tools revision to build")
|
||||
project = flag.String("project", "symbolic-datum-552", "Google Cloud Project")
|
||||
zone = flag.String("zone", "us-central1-a", "Compute Engine zone")
|
||||
target = flag.String("target", "", "If specified, build specific target platform")
|
||||
)
|
||||
|
||||
var builders = []string{
|
||||
"darwin-386",
|
||||
"darwin-amd64",
|
||||
"freebsd-386",
|
||||
"freebsd-amd64",
|
||||
"linux-386",
|
||||
"linux-amd64",
|
||||
"windows-386",
|
||||
"windows-amd64",
|
||||
const timeout = time.Hour
|
||||
|
||||
type Build struct {
|
||||
OS, Arch string
|
||||
|
||||
Race bool // Build race detector.
|
||||
Static bool // Statically-link binaries.
|
||||
|
||||
Builder string // Key for dashboard.Builders.
|
||||
}
|
||||
|
||||
const timeout = time.Hour
|
||||
func (b *Build) String() string {
|
||||
return fmt.Sprintf("%v-%v", b.OS, b.Arch)
|
||||
}
|
||||
|
||||
var builds = []*Build{
|
||||
{
|
||||
OS: "linux",
|
||||
Arch: "386",
|
||||
Builder: "linux-amd64",
|
||||
},
|
||||
{
|
||||
OS: "linux",
|
||||
Arch: "amd64",
|
||||
Race: true,
|
||||
Static: true,
|
||||
Builder: "linux-amd64",
|
||||
},
|
||||
{
|
||||
OS: "freebsd",
|
||||
Arch: "386",
|
||||
Builder: "freebsd-386-gce101",
|
||||
},
|
||||
{
|
||||
OS: "freebsd",
|
||||
Arch: "amd64",
|
||||
Race: true,
|
||||
Builder: "freebsd-amd64-gce101",
|
||||
},
|
||||
}
|
||||
|
||||
const toolsRepo = "golang.org/x/tools"
|
||||
|
||||
var toolPaths = []string{
|
||||
"golang.org/x/tools/cmd/cover",
|
||||
"golang.org/x/tools/cmd/godoc",
|
||||
"golang.org/x/tools/cmd/vet",
|
||||
}
|
||||
|
||||
var preBuildCleanFiles = []string{
|
||||
".gitattributes",
|
||||
|
@ -58,31 +98,37 @@ var postBuildCleanFiles = []string{
|
|||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *revision == "" {
|
||||
if *rev == "" {
|
||||
log.Fatal("must specify -rev flag")
|
||||
}
|
||||
if *toolsRev == "" {
|
||||
log.Fatal("must specify -tools flag")
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for _, name := range builders {
|
||||
b, ok := dashboard.Builders[name]
|
||||
if !ok {
|
||||
log.Printf("unknown builder %q", name)
|
||||
for _, b := range builds {
|
||||
b := b
|
||||
if *target != "" && b.String() != *target {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := makeRelease(b); err != nil {
|
||||
log.Printf("makeRelease(%q): %v", b.Name, err)
|
||||
}
|
||||
b.make() // error logged by make function
|
||||
}()
|
||||
}
|
||||
// TODO(adg): show progress of running builders
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func makeRelease(bc dashboard.BuildConfig) (err error) {
|
||||
func (b *Build) make() (err error) {
|
||||
bc, ok := dashboard.Builders[b.Builder]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown builder: %v", bc)
|
||||
}
|
||||
|
||||
// Start VM
|
||||
log.Printf("%v: Starting VM.", b)
|
||||
keypair, err := buildlet.NewKeyPair()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -95,44 +141,80 @@ func makeRelease(bc dashboard.BuildConfig) (err error) {
|
|||
DeleteIn: timeout,
|
||||
Description: fmt.Sprintf("release buildlet for %s", os.Getenv("USER")),
|
||||
OnInstanceRequested: func() {
|
||||
log.Printf("%v: Sent create request. Waiting for operation.", instance)
|
||||
log.Printf("%v: Sent create request. Waiting for operation.", b)
|
||||
},
|
||||
OnInstanceCreated: func() {
|
||||
log.Printf("%v: Instance created.", instance)
|
||||
log.Printf("%v: Instance created.", b)
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%v: Instance up.", instance)
|
||||
log.Printf("%v: Instance %v up.", b, instance)
|
||||
|
||||
defer func() {
|
||||
log.Printf("%v: Destroying VM.", instance)
|
||||
if err != nil {
|
||||
log.Printf("%v: %v", b, err)
|
||||
}
|
||||
log.Printf("%v: Destroying VM.", b)
|
||||
err := client.DestroyVM(projTokenSource(), *project, *zone, instance)
|
||||
if err != nil {
|
||||
log.Printf("%v: Destroying VM: %v", instance, err)
|
||||
log.Printf("%v: Destroying VM: %v", b, err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Push source to VM
|
||||
const dir = "go"
|
||||
tar := "https://go.googlesource.com/go/+archive/" + *revision + ".tar.gz"
|
||||
if err := client.PutTarFromURL(tar, dir); err != nil {
|
||||
work, err := client.WorkDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%v: Pushed source to VM.", instance)
|
||||
|
||||
if err := client.RemoveAll(preBuildCleanFiles...); err != nil {
|
||||
const (
|
||||
goDir = "go"
|
||||
goPath = "gopath"
|
||||
toolsDir = goPath + "/src/" + toolsRepo
|
||||
)
|
||||
|
||||
// Push source to VM
|
||||
log.Printf("%v: Pushing source to VM.", b)
|
||||
tar := "https://go.googlesource.com/go/+archive/" + *rev + ".tar.gz"
|
||||
if err := client.PutTarFromURL(tar, goDir); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%v: Cleaned repo (pre-build).", instance)
|
||||
tar = "https://go.googlesource.com/tools/+archive/" + *toolsRev + ".tar.gz"
|
||||
if err := client.PutTarFromURL(tar, toolsDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("%v: Cleaning goroot (pre-build).", b)
|
||||
if err := client.RemoveAll(addPrefix(goDir, preBuildCleanFiles)...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set up build environment.
|
||||
sep := "/"
|
||||
if b.OS == "windows" {
|
||||
sep = "\\"
|
||||
}
|
||||
env := []string{
|
||||
"GOOS=" + b.OS,
|
||||
"GOARCH=" + b.Arch,
|
||||
"GOHOSTOS=" + b.OS,
|
||||
"GOHOSTARCH=" + b.Arch,
|
||||
"GOROOT_FINAL=" + bc.GorootFinal(),
|
||||
"GOROOT=" + work + sep + goDir,
|
||||
"GOPATH=" + work + sep + goPath,
|
||||
}
|
||||
if b.Static {
|
||||
env = append(env, "GO_DISTFLAGS=-s")
|
||||
}
|
||||
|
||||
// Execute build
|
||||
log.Printf("%v: Building.", b)
|
||||
out := new(bytes.Buffer)
|
||||
mk := filepath.Join(dir, bc.MakeScript())
|
||||
mk := filepath.Join(goDir, bc.MakeScript())
|
||||
remoteErr, err := client.Exec(mk, buildlet.ExecOpts{
|
||||
Output: out,
|
||||
ExtraEnv: []string{"GOROOT_FINAL=" + bc.GorootFinal()},
|
||||
ExtraEnv: env,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -141,27 +223,85 @@ func makeRelease(bc dashboard.BuildConfig) (err error) {
|
|||
// TODO(adg): write log to file instead?
|
||||
return fmt.Errorf("Build failed: %v\nOutput:\n%v", remoteErr, out)
|
||||
}
|
||||
log.Printf("%v: Build complete.", instance)
|
||||
|
||||
// TODO: build race-enabled tool chain
|
||||
goCmd := path.Join(goDir, "bin/go")
|
||||
if b.OS == "windows" {
|
||||
goCmd += ".exe"
|
||||
}
|
||||
runGo := func(args ...string) error {
|
||||
out := new(bytes.Buffer)
|
||||
remoteErr, err := client.Exec(goCmd, buildlet.ExecOpts{
|
||||
Output: out,
|
||||
Args: args,
|
||||
ExtraEnv: env,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if remoteErr != nil {
|
||||
return fmt.Errorf("go %v: %v\n%s", strings.Join(args, " "), remoteErr, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: check out tools
|
||||
// TODO: build godoc, vet, cover
|
||||
if b.Race {
|
||||
log.Printf("%v: Building race detector.", b)
|
||||
|
||||
// TODO: check out blog, add to misc
|
||||
// TODO: check out tour, add to misc
|
||||
// Because on release branches, go install -a std is a NOP,
|
||||
// we have to resort to delete pkg/$GOOS_$GOARCH, install -race,
|
||||
// and then reinstall std so that we're not left with a slower,
|
||||
// race-enabled cmd/go, etc.
|
||||
if err := client.RemoveAll(path.Join(goDir, "pkg", b.OS+"_"+b.Arch)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runGo("tool", "dist", "install", "runtime"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runGo("install", "-race", "std"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runGo("install", "std"); err != nil {
|
||||
return err
|
||||
}
|
||||
// Re-building go command leaves old versions of go.exe as go.exe~ on windows.
|
||||
// See (*builder).copyFile in $GOROOT/src/cmd/go/build.go for details.
|
||||
// Remove it manually.
|
||||
if b.OS == "windows" {
|
||||
if err := client.RemoveAll(goCmd + "~"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := client.RemoveAll(postBuildCleanFiles...); err != nil {
|
||||
for _, p := range toolPaths {
|
||||
log.Printf("%v: Building %v.", b, p)
|
||||
if err := runGo("install", p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(adg): check out blog, add to misc
|
||||
// TODO(adg): check out tour, add to misc
|
||||
|
||||
log.Printf("%v: Cleaning goroot (post-build).", b)
|
||||
// Need to delete everything except the final "go" directory,
|
||||
// as we make the tarball relative to workdir.
|
||||
cleanFiles := append(addPrefix(goDir, postBuildCleanFiles), goPath)
|
||||
if err := client.RemoveAll(cleanFiles...); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%v: Cleaned repo (post-build).", instance)
|
||||
|
||||
// TODO(adg): build msi files on windows and pkg files on osx
|
||||
|
||||
// Download tarball
|
||||
tgz, err := client.GetTar(dir)
|
||||
log.Printf("%v: Downloading tarball", b)
|
||||
tgz, err := client.GetTar(".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
filename := "go-version-" + bc.Name + ".tar.gz"
|
||||
// TODO(adg): deduce actual version
|
||||
version := "VERSION"
|
||||
filename := "go." + version + "." + b.String() + ".tar.gz"
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -173,7 +313,7 @@ func makeRelease(bc dashboard.BuildConfig) (err error) {
|
|||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%v: Wrote %q.", instance, filename)
|
||||
log.Printf("%v: Wrote %q.", b, filename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -194,3 +334,11 @@ func randHex(n int) string {
|
|||
}
|
||||
return fmt.Sprintf("%x", buf)
|
||||
}
|
||||
|
||||
func addPrefix(prefix string, in []string) []string {
|
||||
var out []string
|
||||
for _, s := range in {
|
||||
out = append(out, path.Join(prefix, s))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче