diff --git a/dashboard/app/build/build.go b/dashboard/app/build/build.go index b178d270..2fa6e7b4 100644 --- a/dashboard/app/build/build.go +++ b/dashboard/app/build/build.go @@ -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{ diff --git a/dashboard/app/build/ui.go b/dashboard/app/build/ui.go index 108915e0..c2d95b3d 100644 --- a/dashboard/app/build/ui.go +++ b/dashboard/app/build/ui.go @@ -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 diff --git a/dashboard/app/build/ui.html b/dashboard/app/build/ui.html index 1c787c89..69b56d93 100644 --- a/dashboard/app/build/ui.html +++ b/dashboard/app/build/ui.html @@ -76,11 +76,12 @@ {{.Name}} {{end}} + {{with $.Package.Name}}

{{.}}

{{end}} {{if $.Commits}} - + {{range $.Builders | builderSpans}} {{end}} @@ -91,7 +92,11 @@ + {{if $.Package.Path}} + + {{else}} + {{end}} {{range $.Builders | builderSpans}} {{end}} @@ -100,38 +105,58 @@ + {{if $.Package.Path}} + + + {{else}} + {{end}} {{range $.Builders}} {{end}} {{range $c := $.Commits}} - - - {{range $.Builders}} - + {{range $i, $h := $c.ResultGoHashes}} + + {{if $i}} + + {{else}} + {{end}} - - - - + {{if $h}} + + {{end}} + {{range $.Builders}} + + {{end}} + {{if $i}} + + + + {{else}} + + + + {{end}} + + {{end}} {{end}}
revision {{.OS}}
repo{{$.Dashboard.Name}} {{builderSubheading .}}
{{shortHash .Hash}} - {{with $c.Result . ""}} - {{if .OK}} - ok - {{else}} - fail - {{end}} - {{else}} -   - {{end}} -
 {{shortHash $c.Hash}}{{shortUser .User}}{{.Time.Format "Mon 02 Jan 15:04"}}{{shortDesc .Desc}}
{{shortHash $h}} + {{with $c.Result . $h}} + {{if .OK}} + ok + {{else}} + fail + {{end}} + {{else}} +   + {{end}} +    {{shortUser $c.User}}{{$c.Time.Format "Mon 02 Jan 15:04"}}{{shortDesc $c.Desc}}
{{with $.Pagination}}
- newer - older + newer + older latest
{{end}} @@ -182,7 +207,7 @@ {{range $pkg := .Packages}} - {{.Package.Name}} + {{.Package.Name}} {{$h := $pkg.Commit.Hash}} {{shortHash $h}}