go.tools/dashboard/app: show sub-repository build history
LGTM=cmang R=adonovan, gobot, cmang CC=golang-codereviews https://golang.org/cl/56410043
This commit is contained in:
parent
4dcb74e810
commit
5cb6365d33
|
|
@ -162,11 +162,11 @@ func (c *Commit) Result(builder, goHash string) *Result {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Results returns the build Results for this Commit for the given goHash.
|
||||
func (c *Commit) Results(goHash string) (results []*Result) {
|
||||
// Results returns the build Results for this Commit.
|
||||
func (c *Commit) Results() (results []*Result) {
|
||||
for _, r := range c.ResultData {
|
||||
p := strings.SplitN(r, "|", 4)
|
||||
if len(p) != 4 || p[3] != goHash {
|
||||
if len(p) != 4 {
|
||||
continue
|
||||
}
|
||||
results = append(results, partsToHash(c, p))
|
||||
|
|
@ -174,6 +174,39 @@ func (c *Commit) Results(goHash string) (results []*Result) {
|
|||
return
|
||||
}
|
||||
|
||||
func (c *Commit) ResultGoHashes() []string {
|
||||
var hashes []string
|
||||
for _, r := range c.ResultData {
|
||||
p := strings.SplitN(r, "|", 4)
|
||||
if len(p) != 4 {
|
||||
continue
|
||||
}
|
||||
// Append only new results (use linear scan to preserve order).
|
||||
if !contains(hashes, p[3]) {
|
||||
hashes = append(hashes, p[3])
|
||||
}
|
||||
}
|
||||
// Return results in reverse order (newest first).
|
||||
reverse(hashes)
|
||||
return hashes
|
||||
}
|
||||
|
||||
func contains(t []string, s string) bool {
|
||||
for _, s2 := range t {
|
||||
if s2 == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func reverse(s []string) {
|
||||
for i := 0; i < len(s)/2; i++ {
|
||||
j := len(s) - i - 1
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
}
|
||||
|
||||
// partsToHash converts a Commit and ResultData substrings to a Result.
|
||||
func partsToHash(c *Commit, p []string) *Result {
|
||||
return &Result{
|
||||
|
|
|
|||
|
|
@ -41,9 +41,11 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if page < 0 {
|
||||
page = 0
|
||||
}
|
||||
repo := r.FormValue("repo")
|
||||
useCache := page == 0 && repo == ""
|
||||
|
||||
// Used cached version of front page, if available.
|
||||
if page == 0 {
|
||||
if useCache {
|
||||
var b []byte
|
||||
if cache.Get(r, now, key, &b) {
|
||||
w.Write(b)
|
||||
|
|
@ -51,16 +53,25 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
commits, err := dashCommits(c, page)
|
||||
pkg := &Package{} // empty package is the main repository
|
||||
if repo != "" {
|
||||
var err error
|
||||
pkg, err = GetPackage(c, repo)
|
||||
if err != nil {
|
||||
logErr(w, r, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
commits, err := dashCommits(c, pkg, page)
|
||||
if err != nil {
|
||||
logErr(w, r, err)
|
||||
return
|
||||
}
|
||||
builders := commitBuilders(commits, "")
|
||||
builders := commitBuilders(commits)
|
||||
|
||||
var tipState *TagState
|
||||
if page == 0 {
|
||||
// only show sub-repo state on first page
|
||||
if pkg.Kind == "" && page == 0 {
|
||||
// only show sub-repo state on first page of normal repo view
|
||||
tipState, err = TagStateByName(c, "tip")
|
||||
if err != nil {
|
||||
logErr(w, r, err)
|
||||
|
|
@ -76,7 +87,7 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
p.Prev = page - 1
|
||||
p.HasPrev = true
|
||||
}
|
||||
data := &uiTemplateData{d, commits, builders, tipState, p}
|
||||
data := &uiTemplateData{d, pkg, commits, builders, tipState, p}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := uiTemplate.Execute(&buf, data); err != nil {
|
||||
|
|
@ -85,7 +96,7 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Cache the front page.
|
||||
if page == 0 {
|
||||
if useCache {
|
||||
cache.Set(r, now, key, buf.Bytes())
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +110,9 @@ type Pagination struct {
|
|||
|
||||
// dashCommits gets a slice of the latest Commits to the current dashboard.
|
||||
// If page > 0 it paginates by commitsPerPage.
|
||||
func dashCommits(c appengine.Context, page int) ([]*Commit, error) {
|
||||
func dashCommits(c appengine.Context, pkg *Package, page int) ([]*Commit, error) {
|
||||
q := datastore.NewQuery("Commit").
|
||||
Ancestor((&Package{}).Key(c)).
|
||||
Ancestor(pkg.Key(c)).
|
||||
Order("-Num").
|
||||
Limit(commitsPerPage).
|
||||
Offset(page * commitsPerPage)
|
||||
|
|
@ -112,10 +123,10 @@ func dashCommits(c appengine.Context, page int) ([]*Commit, error) {
|
|||
|
||||
// commitBuilders returns the names of the builders that provided
|
||||
// Results for the provided commits.
|
||||
func commitBuilders(commits []*Commit, goHash string) []string {
|
||||
func commitBuilders(commits []*Commit) []string {
|
||||
builders := make(map[string]bool)
|
||||
for _, commit := range commits {
|
||||
for _, r := range commit.Results(goHash) {
|
||||
for _, r := range commit.Results() {
|
||||
builders[r.Builder] = true
|
||||
}
|
||||
}
|
||||
|
|
@ -211,6 +222,7 @@ func TagStateByName(c appengine.Context, name string) (*TagState, error) {
|
|||
|
||||
type uiTemplateData struct {
|
||||
Dashboard *Dashboard
|
||||
Package *Package
|
||||
Commits []*Commit
|
||||
Builders []string
|
||||
TipState *TagState
|
||||
|
|
|
|||
|
|
@ -76,11 +76,12 @@
|
|||
<a href="{{.RelPath}}">{{.Name}}</a>
|
||||
{{end}}
|
||||
</nav>
|
||||
{{with $.Package.Name}}<h2>{{.}}</h2>{{end}}
|
||||
|
||||
{{if $.Commits}}
|
||||
|
||||
<table class="build">
|
||||
<colgroup class="col-hash"></colgroup>
|
||||
<colgroup class="col-hash" {{if $.Package.Path}}span="2"{{end}}></colgroup>
|
||||
{{range $.Builders | builderSpans}}
|
||||
<colgroup class="col-result" span="{{.N}}"></colgroup>
|
||||
{{end}}
|
||||
|
|
@ -91,7 +92,11 @@
|
|||
<!-- extra row to make alternating colors use dark for first result -->
|
||||
</tr>
|
||||
<tr>
|
||||
{{if $.Package.Path}}
|
||||
<th colspan="2">revision</th>
|
||||
{{else}}
|
||||
<th> </th>
|
||||
{{end}}
|
||||
{{range $.Builders | builderSpans}}
|
||||
<th colspan="{{.N}}">{{.OS}}</th>
|
||||
{{end}}
|
||||
|
|
@ -100,38 +105,58 @@
|
|||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
{{if $.Package.Path}}
|
||||
<th class="result arch">repo</th>
|
||||
<th class="result arch">{{$.Dashboard.Name}}</th>
|
||||
{{else}}
|
||||
<th> </th>
|
||||
{{end}}
|
||||
{{range $.Builders}}
|
||||
<th class="result arch" title="{{.}}">{{builderSubheading .}}</th>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{range $c := $.Commits}}
|
||||
<tr class="commit">
|
||||
<td class="hash"><a href="{{repoURL $.Dashboard.Name .Hash ""}}">{{shortHash .Hash}}</a></td>
|
||||
{{range $.Builders}}
|
||||
<td class="result">
|
||||
{{with $c.Result . ""}}
|
||||
{{if .OK}}
|
||||
<span class="ok">ok</span>
|
||||
{{else}}
|
||||
<a href="{{$.Dashboard.RelPath}}log/{{.LogHash}}" class="fail">fail</a>
|
||||
{{end}}
|
||||
{{else}}
|
||||
|
||||
{{end}}
|
||||
</td>
|
||||
{{range $i, $h := $c.ResultGoHashes}}
|
||||
<tr class="commit">
|
||||
{{if $i}}
|
||||
<td> </td>
|
||||
{{else}}
|
||||
<td class="hash"><a href="{{repoURL $.Dashboard.Name $c.Hash $.Package.Path}}">{{shortHash $c.Hash}}</a></td>
|
||||
{{end}}
|
||||
<td class="user" title="{{.User}}">{{shortUser .User}}</td>
|
||||
<td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
|
||||
<td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</td>
|
||||
</tr>
|
||||
{{if $h}}
|
||||
<td class="hash"><a href="{{repoURL $.Dashboard.Name $h ""}}">{{shortHash $h}}</a></td>
|
||||
{{end}}
|
||||
{{range $.Builders}}
|
||||
<td class="result">
|
||||
{{with $c.Result . $h}}
|
||||
{{if .OK}}
|
||||
<span class="ok">ok</span>
|
||||
{{else}}
|
||||
<a href="{{$.Dashboard.RelPath}}log/{{.LogHash}}" class="fail">fail</a>
|
||||
{{end}}
|
||||
{{else}}
|
||||
|
||||
{{end}}
|
||||
</td>
|
||||
{{end}}
|
||||
{{if $i}}
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
{{else}}
|
||||
<td class="user" title="{{$c.User}}">{{shortUser $c.User}}</td>
|
||||
<td class="time">{{$c.Time.Format "Mon 02 Jan 15:04"}}</td>
|
||||
<td class="desc" title="{{$c.Desc}}">{{shortDesc $c.Desc}}</td>
|
||||
{{end}}
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
|
||||
{{with $.Pagination}}
|
||||
<div class="paginate">
|
||||
<a {{if .HasPrev}}href="?page={{.Prev}}"{{else}}class="inactive"{{end}}>newer</a>
|
||||
<a {{if .Next}}href="?page={{.Next}}"{{else}}class="inactive"{{end}}>older</a>
|
||||
<a {{if .HasPrev}}href="?{{with $.Package.Path}}repo={{.}}&{{end}}page={{.Prev}}"{{else}}class="inactive"{{end}}>newer</a>
|
||||
<a {{if .Next}}href="?{{with $.Package.Path}}repo={{.}}&{{end}}page={{.Next}}"{{else}}class="inactive"{{end}}>older</a>
|
||||
<a {{if .HasPrev}}href="."{{else}}class="inactive"{{end}}>latest</a>
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
@ -182,7 +207,7 @@
|
|||
</tr>
|
||||
{{range $pkg := .Packages}}
|
||||
<tr class="commit">
|
||||
<td><a title="{{.Package.Path}}">{{.Package.Name}}</a></td>
|
||||
<td><a title="{{.Package.Path}}" href="?repo={{.Package.Path}}">{{.Package.Name}}</a></td>
|
||||
<td class="hash">
|
||||
{{$h := $pkg.Commit.Hash}}
|
||||
<a href="{{repoURL $.Dashboard.Name $h $pkg.Commit.PackagePath}}">{{shortHash $h}}</a>
|
||||
|
|
|
|||
Loading…
Reference in New Issue