2011-03-02 20:41:09 -07:00
|
|
|
// 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 (
|
2011-11-01 20:06:05 -06:00
|
|
|
"errors"
|
2011-09-04 22:48:27 -06:00
|
|
|
"fmt"
|
2011-03-02 20:41:09 -07:00
|
|
|
"go/doc"
|
|
|
|
"go/parser"
|
|
|
|
"go/token"
|
|
|
|
"log"
|
|
|
|
"os"
|
2011-06-28 00:01:52 -06:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2011-03-02 20:41:09 -07:00
|
|
|
)
|
|
|
|
|
2011-07-01 22:02:42 -06:00
|
|
|
const MaxCommentLength = 500 // App Engine won't store more in a StringProperty.
|
|
|
|
|
2011-12-07 16:31:06 -07:00
|
|
|
func (b *Builder) buildExternalPackages(workpath string, hash string) error {
|
2011-09-04 22:48:27 -06:00
|
|
|
logdir := filepath.Join(*buildroot, "log")
|
|
|
|
if err := os.Mkdir(logdir, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2011-05-12 09:21:34 -06:00
|
|
|
pkgs, err := packages()
|
2011-03-02 20:41:09 -07:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, p := range pkgs {
|
2011-06-28 00:01:52 -06:00
|
|
|
goroot := filepath.Join(workpath, "go")
|
2011-07-01 22:02:42 -06:00
|
|
|
gobin := filepath.Join(goroot, "bin")
|
|
|
|
goinstall := filepath.Join(gobin, "goinstall")
|
2011-03-02 20:41:09 -07:00
|
|
|
envv := append(b.envv(), "GOROOT="+goroot)
|
|
|
|
|
2011-07-01 22:02:42 -06:00
|
|
|
// add GOBIN to path
|
|
|
|
for i, v := range envv {
|
|
|
|
if strings.HasPrefix(v, "PATH=") {
|
|
|
|
p := filepath.SplitList(v[5:])
|
|
|
|
p = append([]string{gobin}, p...)
|
|
|
|
s := strings.Join(p, string(filepath.ListSeparator))
|
|
|
|
envv[i] = "PATH=" + s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-02 20:41:09 -07:00
|
|
|
// goinstall
|
2011-07-20 00:07:40 -06:00
|
|
|
buildLog, code, err := runLog(envv, "", goroot, goinstall, "-dashboard=false", p)
|
2011-03-02 20:41:09 -07:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("goinstall %v: %v", p, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// get doc comment from package source
|
2011-09-04 22:48:27 -06:00
|
|
|
var info string
|
|
|
|
pkgPath := filepath.Join(goroot, "src", "pkg", p)
|
|
|
|
if _, err := os.Stat(pkgPath); err == nil {
|
|
|
|
info, err = packageComment(p, pkgPath)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("packageComment %v: %v", p, err)
|
|
|
|
}
|
2011-03-02 20:41:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// update dashboard with build state + info
|
2011-07-01 22:02:42 -06:00
|
|
|
err = b.updatePackage(p, code == 0, buildLog, info)
|
2011-03-02 20:41:09 -07:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("updatePackage %v: %v", p, err)
|
|
|
|
}
|
2011-09-04 22:48:27 -06:00
|
|
|
|
|
|
|
if code == 0 {
|
|
|
|
log.Println("Build succeeded:", p)
|
|
|
|
} else {
|
|
|
|
log.Println("Build failed:", p)
|
|
|
|
fn := filepath.Join(logdir, strings.Replace(p, "/", "_", -1))
|
|
|
|
if f, err := os.Create(fn); err != nil {
|
|
|
|
log.Printf("creating %s: %v", fn, err)
|
|
|
|
} else {
|
|
|
|
fmt.Fprint(f, buildLog)
|
|
|
|
f.Close()
|
|
|
|
}
|
|
|
|
}
|
2011-03-02 20:41:09 -07:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2011-11-30 10:04:16 -07:00
|
|
|
func isGoFile(fi os.FileInfo) bool {
|
|
|
|
return !fi.IsDir() && // exclude directories
|
|
|
|
!strings.HasPrefix(fi.Name(), ".") && // ignore .files
|
|
|
|
!strings.HasSuffix(fi.Name(), "_test.go") && // ignore tests
|
|
|
|
filepath.Ext(fi.Name()) == ".go"
|
2011-06-28 00:01:52 -06:00
|
|
|
}
|
|
|
|
|
2011-11-01 20:06:05 -06:00
|
|
|
func packageComment(pkg, pkgpath string) (info string, err error) {
|
2011-03-02 20:41:09 -07:00
|
|
|
fset := token.NewFileSet()
|
2011-06-28 00:01:52 -06:00
|
|
|
pkgs, err := parser.ParseDir(fset, pkgpath, isGoFile, parser.PackageClauseOnly|parser.ParseComments)
|
2011-03-02 20:41:09 -07:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for name := range pkgs {
|
|
|
|
if name == "main" {
|
|
|
|
continue
|
|
|
|
}
|
2012-01-12 18:36:57 -07:00
|
|
|
pdoc := doc.New(pkgs[name], pkg, doc.AllDecls)
|
2011-09-04 22:48:27 -06:00
|
|
|
if pdoc.Doc == "" {
|
|
|
|
continue
|
|
|
|
}
|
2011-03-02 20:41:09 -07:00
|
|
|
if info != "" {
|
2011-11-01 20:06:05 -06:00
|
|
|
return "", errors.New("multiple packages with docs")
|
2011-03-02 20:41:09 -07:00
|
|
|
}
|
|
|
|
info = pdoc.Doc
|
|
|
|
}
|
2011-07-01 22:02:42 -06:00
|
|
|
// grab only first paragraph
|
|
|
|
if parts := strings.SplitN(info, "\n\n", 2); len(parts) > 1 {
|
|
|
|
info = parts[0]
|
|
|
|
}
|
|
|
|
// replace newlines with spaces
|
|
|
|
info = strings.Replace(info, "\n", " ", -1)
|
|
|
|
// truncate
|
|
|
|
if len(info) > MaxCommentLength {
|
|
|
|
info = info[:MaxCommentLength]
|
|
|
|
}
|
2011-03-02 20:41:09 -07:00
|
|
|
return
|
|
|
|
}
|