diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-08-03 16:54:30 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-08-03 16:54:30 +0200 |
commit | 28592ee1ea1f5cdffcf85472f9de0285d928cf12 (patch) | |
tree | 32944e18b23f7fe4a0818a694aa2a6dfb1835463 /misc | |
parent | e836bee4716dc0d4d913537ad3ad1925a7ac32d0 (diff) | |
download | golang-28592ee1ea1f5cdffcf85472f9de0285d928cf12.tar.gz |
Imported Upstream version 59upstream/59
Diffstat (limited to 'misc')
-rw-r--r-- | misc/dashboard/builder/http.go | 7 | ||||
-rw-r--r-- | misc/dashboard/builder/main.go | 33 | ||||
-rw-r--r-- | misc/dashboard/builder/package.go | 48 | ||||
-rw-r--r-- | misc/dashboard/godashboard/auth.py | 13 | ||||
-rw-r--r-- | misc/dashboard/godashboard/gobuild.py | 7 | ||||
-rw-r--r-- | misc/dashboard/godashboard/index.yaml | 1 | ||||
-rw-r--r-- | misc/dashboard/godashboard/package.html | 30 | ||||
-rw-r--r-- | misc/dashboard/godashboard/package.py | 45 | ||||
-rw-r--r-- | misc/dashboard/godashboard/static/style.css | 13 | ||||
-rw-r--r-- | misc/emacs/go-mode.el | 4 | ||||
-rwxr-xr-x | misc/nacl/naclrun | 15 | ||||
-rw-r--r-- | misc/vim/ftdetect/gofiletype.vim | 2 |
12 files changed, 138 insertions, 80 deletions
diff --git a/misc/dashboard/builder/http.go b/misc/dashboard/builder/http.go index 5e1da0c87..98400c51a 100644 --- a/misc/dashboard/builder/http.go +++ b/misc/dashboard/builder/http.go @@ -112,16 +112,15 @@ func packages() (pkgs []string, err os.Error) { return } -// updatePackage sends package build results and info to the dashboard -func (b *Builder) updatePackage(pkg string, state bool, buildLog, info string, hash string) os.Error { +// updatePackage sends package build results and info dashboard +func (b *Builder) updatePackage(pkg string, ok bool, buildLog, info string) os.Error { return dash("POST", "package", nil, param{ "builder": b.name, "key": b.key, "path": pkg, - "state": strconv.Btoa(state), + "ok": strconv.Btoa(ok), "log": buildLog, "info": info, - "go_rev": hash[:12], }) } diff --git a/misc/dashboard/builder/main.go b/misc/dashboard/builder/main.go index 9377fbe32..989965bc4 100644 --- a/misc/dashboard/builder/main.go +++ b/misc/dashboard/builder/main.go @@ -60,8 +60,9 @@ var ( ) var ( - goroot string - releaseRegexp = regexp.MustCompile(`^(release|weekly)\.[0-9\-.]+`) + goroot string + binaryTagRe = regexp.MustCompile(`^(release\.r|weekly\.)[0-9\-.]+`) + releaseRe = regexp.MustCompile(`^release\.r[0-9\-.]+`) ) func main() { @@ -161,7 +162,7 @@ func NewBuilder(builder string) (*Builder, os.Error) { b := &Builder{name: builder} // get goos/goarch from builder string - s := strings.Split(builder, "-", 3) + s := strings.SplitN(builder, "-", 3) if len(s) >= 2 { b.goos, b.goarch = s[0], s[1] } else { @@ -177,7 +178,7 @@ func NewBuilder(builder string) (*Builder, os.Error) { if err != nil { return nil, fmt.Errorf("readKeys %s (%s): %s", b.name, fn, err) } - v := strings.Split(string(c), "\n", -1) + v := strings.Split(string(c), "\n") b.key = v[0] if len(v) >= 3 { b.codeUsername, b.codePassword = v[1], v[2] @@ -200,7 +201,7 @@ func (b *Builder) buildExternal() { log.Println("hg pull failed:", err) continue } - hash, tag, err := firstTag(releaseRegexp) + hash, tag, err := firstTag(releaseRe) if err != nil { log.Println(err) continue @@ -321,7 +322,7 @@ func (b *Builder) buildHash(hash string) (err os.Error) { } // if this is a release, create tgz and upload to google code - releaseHash, release, err := firstTag(releaseRegexp) + releaseHash, release, err := firstTag(binaryTagRe) if hash == releaseHash { // clean out build state err = run(b.envv(), srcDir, "./clean.bash", "--nopkg") @@ -357,7 +358,10 @@ func (b *Builder) envv() []string { "GOROOT_FINAL=/usr/local/go", } for _, k := range extraEnv { - e = append(e, k+"="+os.Getenv(k)) + s, err := os.Getenverror(k) + if err == nil { + e = append(e, k+"="+s) + } } return e } @@ -368,9 +372,14 @@ func (b *Builder) envvWindows() []string { "GOOS": b.goos, "GOARCH": b.goarch, "GOROOT_FINAL": "/c/go", + // TODO(brainman): remove once we find make that does not hang. + "MAKEFLAGS": "-j1", } for _, name := range extraEnv { - start[name] = os.Getenv(name) + s, err := os.Getenverror(name) + if err == nil { + start[name] = s + } } skip := map[string]bool{ "GOBIN": true, @@ -384,7 +393,7 @@ func (b *Builder) envvWindows() []string { skip[name] = true } for _, kv := range os.Environ() { - s := strings.Split(kv, "=", 2) + s := strings.SplitN(kv, "=", 2) name := strings.ToUpper(s[0]) switch { case name == "": @@ -583,7 +592,7 @@ func fullHash(rev string) (hash string, err os.Error) { if s == "" { return "", fmt.Errorf("cannot find revision") } - if len(s) != 20 { + if len(s) != 40 { return "", fmt.Errorf("hg returned invalid hash " + s) } return s, nil @@ -594,7 +603,7 @@ var revisionRe = regexp.MustCompile(`^([^ ]+) +[0-9]+:([0-9a-f]+)$`) // firstTag returns the hash and tag of the most recent tag matching re. func firstTag(re *regexp.Regexp) (hash string, tag string, err os.Error) { o, _, err := runLog(nil, "", goroot, "hg", "tags") - for _, l := range strings.Split(o, "\n", -1) { + for _, l := range strings.Split(o, "\n") { if l == "" { continue } @@ -607,7 +616,7 @@ func firstTag(re *regexp.Regexp) (hash string, tag string, err os.Error) { continue } tag = s[1] - hash, err = fullHash(s[3]) + hash, err = fullHash(s[2]) return } err = os.NewError("no matching tag found") diff --git a/misc/dashboard/builder/package.go b/misc/dashboard/builder/package.go index ee65d7669..b6674428d 100644 --- a/misc/dashboard/builder/package.go +++ b/misc/dashboard/builder/package.go @@ -10,35 +10,47 @@ import ( "go/token" "log" "os" - "path" + "path/filepath" + "strings" ) +const MaxCommentLength = 500 // App Engine won't store more in a StringProperty. + func (b *Builder) buildPackages(workpath string, hash string) os.Error { pkgs, err := packages() if err != nil { return err } for _, p := range pkgs { - goroot := path.Join(workpath, "go") - goinstall := path.Join(goroot, "bin", "goinstall") + goroot := filepath.Join(workpath, "go") + gobin := filepath.Join(goroot, "bin") + goinstall := filepath.Join(gobin, "goinstall") envv := append(b.envv(), "GOROOT="+goroot) + // 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 + } + } + // goinstall - buildLog, code, err := runLog(envv, "", goroot, goinstall, p) + buildLog, code, err := runLog(envv, "", goroot, goinstall, "-log=false", p) if err != nil { log.Printf("goinstall %v: %v", p, err) - continue } - built := code != 0 // get doc comment from package source - info, err := packageComment(p, path.Join(goroot, "pkg", p)) + info, err := packageComment(p, filepath.Join(goroot, "src", "pkg", p)) if err != nil { - log.Printf("goinstall %v: %v", p, err) + log.Printf("packageComment %v: %v", p, err) } // update dashboard with build state + info - err = b.updatePackage(p, built, buildLog, info, hash) + err = b.updatePackage(p, code == 0, buildLog, info) if err != nil { log.Printf("updatePackage %v: %v", p, err) } @@ -46,9 +58,15 @@ func (b *Builder) buildPackages(workpath string, hash string) os.Error { return nil } +func isGoFile(fi *os.FileInfo) bool { + return fi.IsRegular() && // exclude directories + !strings.HasPrefix(fi.Name, ".") && // ignore .files + filepath.Ext(fi.Name) == ".go" +} + func packageComment(pkg, pkgpath string) (info string, err os.Error) { fset := token.NewFileSet() - pkgs, err := parser.ParseDir(fset, pkgpath, nil, parser.PackageClauseOnly|parser.ParseComments) + pkgs, err := parser.ParseDir(fset, pkgpath, isGoFile, parser.PackageClauseOnly|parser.ParseComments) if err != nil { return } @@ -62,5 +80,15 @@ func packageComment(pkg, pkgpath string) (info string, err os.Error) { pdoc := doc.NewPackageDoc(pkgs[name], pkg) info = pdoc.Doc } + // 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] + } return } diff --git a/misc/dashboard/godashboard/auth.py b/misc/dashboard/godashboard/auth.py new file mode 100644 index 000000000..73a54c0d4 --- /dev/null +++ b/misc/dashboard/godashboard/auth.py @@ -0,0 +1,13 @@ +# 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. + +import hmac + +# local imports +import key + +def auth(req): + k = req.get('key') + return k == hmac.new(key.accessKey, req.get('builder')).hexdigest() or k == key.accessKey + diff --git a/misc/dashboard/godashboard/gobuild.py b/misc/dashboard/godashboard/gobuild.py index 5678f2e1b..685dc83a9 100644 --- a/misc/dashboard/godashboard/gobuild.py +++ b/misc/dashboard/godashboard/gobuild.py @@ -14,14 +14,13 @@ from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app import datetime import hashlib -import hmac import logging import os import re import bz2 # local imports -import key +from auth import auth import const # The majority of our state are commit objects. One of these exists for each of @@ -142,10 +141,6 @@ class DashboardHandler(webapp.RequestHandler): simplejson.dump(obj, self.response.out) return -def auth(req): - k = req.get('key') - return k == hmac.new(key.accessKey, req.get('builder')).hexdigest() or k == key.accessKey - # Todo serves /todo. It tells the builder which commits need to be built. class Todo(DashboardHandler): def get(self): diff --git a/misc/dashboard/godashboard/index.yaml b/misc/dashboard/godashboard/index.yaml index 4a00c4a6f..f39299d5d 100644 --- a/misc/dashboard/godashboard/index.yaml +++ b/misc/dashboard/godashboard/index.yaml @@ -49,4 +49,3 @@ indexes: # manually, move them above the marker line. The index.yaml file is # automatically uploaded to the admin console when you next deploy # your application using appcfg.py. - diff --git a/misc/dashboard/godashboard/package.html b/misc/dashboard/godashboard/package.html index 9332b5a79..043080b5b 100644 --- a/misc/dashboard/godashboard/package.html +++ b/misc/dashboard/godashboard/package.html @@ -19,37 +19,43 @@ Packages listed on this page are written by third parties and may or may not build or be safe to use. </p> + + <p> + An "ok" in the <b>build</b> column indicates that the package is + <a href="http://golang.org/cmd/goinstall/">goinstallable</a> + with the latest + <a href="http://golang.org/doc/devel/release.html">release</a> of Go. + </p> + + <p> + The <b>info</b> column shows the first paragraph from the + <a href="http://blog.golang.org/2011/03/godoc-documenting-go-code.html">package doc comment</a>. + </p> <h2>Recently Installed Packages</h2> <table class="alternate" cellpadding="0" cellspacing="0"> - <tr><th>last install</th><th>count</th><th>path</th><th>project</th></tr> + <tr><th>last install</th><th>count</th><th>build</th><th>path</th><th>info</th></tr> {% for r in by_time %} <tr> <td class="time">{{r.last_install|date:"Y-M-d H:i"}}</td> <td class="count">{{r.count}}</td> + <td class="ok">{% if r.ok %}<a title="{{r.last_ok|date:"Y-M-d H:i"}}">ok</a>{% else %} {% endif %}</td> <td class="path"><a href="{{r.web_url}}">{{r.path}}</a></td> - <td class="project"> - {% for p in r.project_set %} - <a href="{{p.web_url}}">{{p.name}}</a> - {{p.descr}} - {% endfor %} - </td> + <td class="info">{% if r.info %}{{r.info|escape}}{% endif %}</td> </tr> {% endfor %} </table> <h2>Most Installed Packages</h2> <table class="alternate" cellpadding="0" cellspacing="0"> - <tr><th>last install</th><th>count</th><th>path</th><th>project</th></tr> + <tr><th>last install</th><th>count</th><th>build</th><th>path</th><th>info</th></tr> {% for r in by_count %} <tr> <td class="time">{{r.last_install|date:"Y-M-d H:i"}}</td> <td class="count">{{r.count}}</td> + <td class="ok">{% if r.ok %}<a title="{{r.last_ok|date:"Y-M-d H:i"}}">ok</a>{% else %} {% endif %}</td> <td class="path"><a href="{{r.web_url}}">{{r.path}}</a></td> - <td class="project"> - {% for p in r.project_set %} - <a href="{{p.web_url}}">{{p.name}}</a> - {{p.descr}} - {% endfor %} - </td> + <td class="info">{% if r.info %}{{r.info|escape}}{% endif %}</td> </tr> {% endfor %} </table> diff --git a/misc/dashboard/godashboard/package.py b/misc/dashboard/godashboard/package.py index a1bca1908..316f3867f 100644 --- a/misc/dashboard/godashboard/package.py +++ b/misc/dashboard/godashboard/package.py @@ -23,6 +23,7 @@ import sets # local imports import toutf8 import const +from auth import auth template.register_template_library('toutf8') @@ -34,6 +35,11 @@ class Package(db.Model): count = db.IntegerProperty() last_install = db.DateTimeProperty() + # data contributed by gobuilder + info = db.StringProperty() + ok = db.BooleanProperty() + last_ok = db.DateTimeProperty() + class Project(db.Model): name = db.StringProperty(indexed=True) descr = db.StringProperty() @@ -43,23 +49,25 @@ class Project(db.Model): tags = db.ListProperty(str) approved = db.BooleanProperty(indexed=True) -re_bitbucket = re.compile(r'^bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$') -re_googlecode = re.compile(r'^[a-z0-9\-]+\.googlecode\.com/(svn|hg)$') -re_github = re.compile(r'^github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$') +re_bitbucket = re.compile(r'^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-zA-Z0-9_.\-]+)(/[a-z0-9A-Z_.\-/]+)?$') +re_googlecode = re.compile(r'^[a-z0-9\-]+\.googlecode\.com/(svn|hg)(/[a-z0-9A-Z_.\-/]+)?$') +re_github = re.compile(r'^github\.com/[a-z0-9A-Z_.\-]+(/[a-z0-9A-Z_.\-]+)+$') re_launchpad = re.compile(r'^launchpad\.net/([a-z0-9A-Z_.\-]+(/[a-z0-9A-Z_.\-]+)?|~[a-z0-9A-Z_.\-]+/(\+junk|[a-z0-9A-Z_.\-]+)/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]+)?$') - def vc_to_web(path): if re_bitbucket.match(path): - check_url = 'http://' + path + '/?cmd=heads' - web = 'http://' + path + '/' + m = re_bitbucket.match(path) + check_url = 'http://' + m.group(1) + '/?cmd=heads' + web = 'http://' + m.group(1) + '/' elif re_github.match(path): - # github doesn't let you fetch the .git directory anymore. - # fetch .git/info/refs instead, like git clone would. - check_url = 'http://'+path+'.git/info/refs' - web = 'http://' + path + m = re_github_web.match(path) + check_url = 'https://raw.github.com/' + m.group(1) + '/' + m.group(2) + '/master/' + web = 'http://github.com/' + m.group(1) + '/' + m.group(2) + '/' elif re_googlecode.match(path): + m = re_googlecode.match(path) check_url = 'http://'+path + if not m.group(2): # append / after bare '/hg' + check_url += '/' web = 'http://code.google.com/p/' + path[:path.index('.')] elif re_launchpad.match(path): check_url = web = 'https://'+path @@ -143,8 +151,7 @@ class PackagePage(webapp.RequestHandler): def can_get_url(self, url): try: - req = urllib2.Request(url) - response = urllib2.urlopen(req) + urllib2.urlopen(urllib2.Request(url)) return True except: return False @@ -174,15 +181,23 @@ class PackagePage(webapp.RequestHandler): return False p = Package(key_name = key, path = path, count = 0, web_url = web) + # is this the builder updating package metadata? + if auth(self.request): + p.info = self.request.get('info') + p.ok = self.request.get('ok') == "true" + if p.ok: + p.last_ok = datetime.datetime.utcnow() + else: + p.count += 1 + p.last_install = datetime.datetime.utcnow() + # update package object - p.count += 1 - p.last_install = datetime.datetime.utcnow() p.put() return True def post(self): path = self.request.get('path') - ok = self.record_pkg(path) + ok = db.run_in_transaction(self.record_pkg, path) if ok: self.response.set_status(200) self.response.out.write('ok') diff --git a/misc/dashboard/godashboard/static/style.css b/misc/dashboard/godashboard/static/style.css index 481af36d7..a7e61dda5 100644 --- a/misc/dashboard/godashboard/static/style.css +++ b/misc/dashboard/godashboard/static/style.css @@ -52,7 +52,7 @@ table.alternate tr td:last-child { padding-right: 0; } table.alternate tr:nth-child(2n) { - background-color: #f8f8f8; + background-color: #f0f0f0; } span.hash { font-family: monospace; @@ -62,10 +62,19 @@ span.hash { td.date { color: #aaa; } -td.result { +td.ok { text-align: center; + color: #060; + font-weight: bold; +} +td.ok a { + cursor: help; +} +th { + text-align: left; } th.builder { + text-align: center; font-weight: bold; } a.fail { diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el index 03f0a2a8b..ba7f72397 100644 --- a/misc/emacs/go-mode.el +++ b/misc/emacs/go-mode.el @@ -69,8 +69,8 @@ some syntax analysis.") (defvar go-mode-font-lock-keywords - (let ((builtins '("cap" "close" "closed" "len" "make" "new" - "panic" "panicln" "print" "println")) + (let ((builtins '("append" "cap" "close" "complex" "copy" "imag" "len" + "make" "new" "panic" "print" "println" "real" "recover")) (constants '("nil" "true" "false" "iota")) (type-name "\\s *\\(?:[*(]\\s *\\)*\\(?:\\w+\\s *\\.\\s *\\)?\\(\\w+\\)") ) diff --git a/misc/nacl/naclrun b/misc/nacl/naclrun deleted file mode 100755 index 1cdcf876c..000000000 --- a/misc/nacl/naclrun +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# Copyright 2010 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. - -# Run nacl binary in debug mode (allow file access) -# and then grep away the chatter. -# See ../../src/pkg/exp/nacl/README for more on -# how to configure NaCl. - -nacl -d "$@" >/tmp/nacl.out.$$ 2>&1 -status=$? -egrep -v 'DEBUG MODE ENABLED|^\[[0-9]+,' /tmp/nacl.out.$$ -rm -f /tmp/nacl.out.$$ -exit $status diff --git a/misc/vim/ftdetect/gofiletype.vim b/misc/vim/ftdetect/gofiletype.vim index 884312160..f03a1d8dc 100644 --- a/misc/vim/ftdetect/gofiletype.vim +++ b/misc/vim/ftdetect/gofiletype.vim @@ -1 +1 @@ -au BufRead,BufNewFile *.go set filetype=go +au BufReadPre,BufNewFile *.go set filetype=go fileencoding=utf-8 fileencodings=utf-8 |