summaryrefslogtreecommitdiff
path: root/misc/dashboard/builder/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/dashboard/builder/main.go')
-rw-r--r--misc/dashboard/builder/main.go113
1 files changed, 97 insertions, 16 deletions
diff --git a/misc/dashboard/builder/main.go b/misc/dashboard/builder/main.go
index 7e80934e1..fc11d365e 100644
--- a/misc/dashboard/builder/main.go
+++ b/misc/dashboard/builder/main.go
@@ -1,3 +1,7 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
package main
import (
@@ -15,13 +19,24 @@ import (
)
const (
- codeProject = "go"
- codePyScript = "misc/dashboard/googlecode_upload.py"
- hgUrl = "https://go.googlecode.com/hg/"
- waitInterval = 10e9 // time to wait before checking for new revs
- mkdirPerm = 0750
+ codeProject = "go"
+ codePyScript = "misc/dashboard/googlecode_upload.py"
+ hgUrl = "https://go.googlecode.com/hg/"
+ waitInterval = 10e9 // time to wait before checking for new revs
+ mkdirPerm = 0750
+ pkgBuildInterval = 1e9 * 60 * 60 * 24 // rebuild packages every 24 hours
)
+// These variables are copied from the gobuilder's environment
+// to the envv of its subprocesses.
+var extraEnv = []string{
+ "GOHOSTOS",
+ "GOHOSTARCH",
+ "PATH",
+ "DISABLE_NET_TESTS",
+ "GOARM",
+}
+
type Builder struct {
name string
goos, goarch string
@@ -43,6 +58,8 @@ var (
buildRelease = flag.Bool("release", false, "Build and upload binary release archives")
buildRevision = flag.String("rev", "", "Build specified revision and exit")
buildCmd = flag.String("cmd", "./all.bash", "Build command (specify absolute or relative to go/src/)")
+ external = flag.Bool("external", false, "Build external packages")
+ verbose = flag.Bool("v", false, "verbose")
)
var (
@@ -70,6 +87,8 @@ func main() {
}
builders[i] = b
}
+
+ // set up work environment
if err := os.RemoveAll(*buildroot); err != nil {
log.Fatalf("Error removing build root (%s): %s", *buildroot, err)
}
@@ -79,6 +98,7 @@ func main() {
if err := run(nil, *buildroot, "hg", "clone", hgUrl, goroot); err != nil {
log.Fatal("Error cloning repository:", err)
}
+
// if specified, build revision and return
if *buildRevision != "" {
c, err := getCommit(*buildRevision)
@@ -93,6 +113,16 @@ func main() {
}
return
}
+
+ // external package build mode
+ if *external {
+ if len(builders) != 1 {
+ log.Fatal("only one goos-goarch should be specified with -external")
+ }
+ builders[0].buildExternal()
+ }
+
+ // go continuous build mode (default)
// check for new commits and build them
for {
err := run(nil, goroot, "hg", "pull", "-u")
@@ -179,6 +209,44 @@ func NewBuilder(builder string) (*Builder, os.Error) {
return b, nil
}
+// buildExternal downloads and builds external packages, and
+// reports their build status to the dashboard.
+// It will re-build all packages after pkgBuildInterval nanoseconds or
+// a new release tag is found.
+func (b *Builder) buildExternal() {
+ var prevTag string
+ var nextBuild int64
+ for {
+ time.Sleep(waitInterval)
+ err := run(nil, goroot, "hg", "pull", "-u")
+ if err != nil {
+ log.Println("hg pull failed:", err)
+ continue
+ }
+ c, tag, err := getTag(releaseRegexp)
+ if err != nil {
+ log.Println(err)
+ continue
+ }
+ if *verbose {
+ log.Println("latest release:", tag)
+ }
+ // don't rebuild if there's no new release
+ // and it's been less than pkgBuildInterval
+ // nanoseconds since the last build.
+ if tag == prevTag && time.Nanoseconds() < nextBuild {
+ continue
+ }
+ // buildCommit will also build the packages
+ if err := b.buildCommit(c); err != nil {
+ log.Println(err)
+ continue
+ }
+ prevTag = tag
+ nextBuild = time.Nanoseconds() + pkgBuildInterval
+ }
+}
+
// build checks for a new commit for this builder
// and builds it if one is found.
// It returns true if a build was attempted.
@@ -262,23 +330,23 @@ func (b *Builder) buildCommit(c Commit) (err os.Error) {
return
}
- // set up environment for build/bench execution
- env := []string{
- "GOOS=" + b.goos,
- "GOARCH=" + b.goarch,
- "GOHOSTOS=" + os.Getenv("GOHOSTOS"),
- "GOHOSTARCH=" + os.Getenv("GOHOSTARCH"),
- "GOROOT_FINAL=/usr/local/go",
- "PATH=" + os.Getenv("PATH"),
- }
srcDir := path.Join(workpath, "go", "src")
// build
logfile := path.Join(workpath, "build.log")
- buildLog, status, err := runLog(env, logfile, srcDir, *buildCmd)
+ buildLog, status, err := runLog(b.envv(), logfile, srcDir, *buildCmd)
if err != nil {
return fmt.Errorf("all.bash: %s", err)
}
+
+ // if we're in external mode, build all packages and return
+ if *external {
+ if status != 0 {
+ return os.NewError("go build failed")
+ }
+ return b.buildPackages(workpath, c)
+ }
+
if status != 0 {
// record failure
return b.recordResult(buildLog, c)
@@ -307,7 +375,7 @@ func (b *Builder) buildCommit(c Commit) (err os.Error) {
// if this is a release, create tgz and upload to google code
if release := releaseRegexp.FindString(c.desc); release != "" {
// clean out build state
- err = run(env, srcDir, "./clean.bash", "--nopkg")
+ err = run(b.envv(), srcDir, "./clean.bash", "--nopkg")
if err != nil {
return fmt.Errorf("clean.bash: %s", err)
}
@@ -329,6 +397,19 @@ func (b *Builder) buildCommit(c Commit) (err os.Error) {
return
}
+// envv returns an environment for build/bench execution
+func (b *Builder) envv() []string {
+ e := []string{
+ "GOOS=" + b.goos,
+ "GOARCH=" + b.goarch,
+ "GOROOT_FINAL=/usr/local/go",
+ }
+ for _, k := range extraEnv {
+ e = append(e, k+"="+os.Getenv(k))
+ }
+ return e
+}
+
func isDirectory(name string) bool {
s, err := os.Stat(name)
return err == nil && s.IsDirectory()