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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Results returns the build Results for this Commit for the given goHash.
|
// Results returns the build Results for this Commit.
|
||||||
func (c *Commit) Results(goHash string) (results []*Result) {
|
func (c *Commit) Results() (results []*Result) {
|
||||||
for _, r := range c.ResultData {
|
for _, r := range c.ResultData {
|
||||||
p := strings.SplitN(r, "|", 4)
|
p := strings.SplitN(r, "|", 4)
|
||||||
if len(p) != 4 || p[3] != goHash {
|
if len(p) != 4 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
results = append(results, partsToHash(c, p))
|
results = append(results, partsToHash(c, p))
|
||||||
|
|
@ -174,6 +174,39 @@ func (c *Commit) Results(goHash string) (results []*Result) {
|
||||||
return
|
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.
|
// partsToHash converts a Commit and ResultData substrings to a Result.
|
||||||
func partsToHash(c *Commit, p []string) *Result {
|
func partsToHash(c *Commit, p []string) *Result {
|
||||||
return &Result{
|
return &Result{
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,11 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if page < 0 {
|
if page < 0 {
|
||||||
page = 0
|
page = 0
|
||||||
}
|
}
|
||||||
|
repo := r.FormValue("repo")
|
||||||
|
useCache := page == 0 && repo == ""
|
||||||
|
|
||||||
// Used cached version of front page, if available.
|
// Used cached version of front page, if available.
|
||||||
if page == 0 {
|
if useCache {
|
||||||
var b []byte
|
var b []byte
|
||||||
if cache.Get(r, now, key, &b) {
|
if cache.Get(r, now, key, &b) {
|
||||||
w.Write(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 {
|
if err != nil {
|
||||||
logErr(w, r, err)
|
logErr(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
builders := commitBuilders(commits, "")
|
}
|
||||||
|
commits, err := dashCommits(c, pkg, page)
|
||||||
|
if err != nil {
|
||||||
|
logErr(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
builders := commitBuilders(commits)
|
||||||
|
|
||||||
var tipState *TagState
|
var tipState *TagState
|
||||||
if page == 0 {
|
if pkg.Kind == "" && page == 0 {
|
||||||
// only show sub-repo state on first page
|
// only show sub-repo state on first page of normal repo view
|
||||||
tipState, err = TagStateByName(c, "tip")
|
tipState, err = TagStateByName(c, "tip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logErr(w, r, err)
|
logErr(w, r, err)
|
||||||
|
|
@ -76,7 +87,7 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
p.Prev = page - 1
|
p.Prev = page - 1
|
||||||
p.HasPrev = true
|
p.HasPrev = true
|
||||||
}
|
}
|
||||||
data := &uiTemplateData{d, commits, builders, tipState, p}
|
data := &uiTemplateData{d, pkg, commits, builders, tipState, p}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := uiTemplate.Execute(&buf, data); err != nil {
|
if err := uiTemplate.Execute(&buf, data); err != nil {
|
||||||
|
|
@ -85,7 +96,7 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the front page.
|
// Cache the front page.
|
||||||
if page == 0 {
|
if useCache {
|
||||||
cache.Set(r, now, key, buf.Bytes())
|
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.
|
// dashCommits gets a slice of the latest Commits to the current dashboard.
|
||||||
// If page > 0 it paginates by commitsPerPage.
|
// 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").
|
q := datastore.NewQuery("Commit").
|
||||||
Ancestor((&Package{}).Key(c)).
|
Ancestor(pkg.Key(c)).
|
||||||
Order("-Num").
|
Order("-Num").
|
||||||
Limit(commitsPerPage).
|
Limit(commitsPerPage).
|
||||||
Offset(page * 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
|
// commitBuilders returns the names of the builders that provided
|
||||||
// Results for the provided commits.
|
// Results for the provided commits.
|
||||||
func commitBuilders(commits []*Commit, goHash string) []string {
|
func commitBuilders(commits []*Commit) []string {
|
||||||
builders := make(map[string]bool)
|
builders := make(map[string]bool)
|
||||||
for _, commit := range commits {
|
for _, commit := range commits {
|
||||||
for _, r := range commit.Results(goHash) {
|
for _, r := range commit.Results() {
|
||||||
builders[r.Builder] = true
|
builders[r.Builder] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,6 +222,7 @@ func TagStateByName(c appengine.Context, name string) (*TagState, error) {
|
||||||
|
|
||||||
type uiTemplateData struct {
|
type uiTemplateData struct {
|
||||||
Dashboard *Dashboard
|
Dashboard *Dashboard
|
||||||
|
Package *Package
|
||||||
Commits []*Commit
|
Commits []*Commit
|
||||||
Builders []string
|
Builders []string
|
||||||
TipState *TagState
|
TipState *TagState
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,12 @@
|
||||||
<a href="{{.RelPath}}">{{.Name}}</a>
|
<a href="{{.RelPath}}">{{.Name}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</nav>
|
</nav>
|
||||||
|
{{with $.Package.Name}}<h2>{{.}}</h2>{{end}}
|
||||||
|
|
||||||
{{if $.Commits}}
|
{{if $.Commits}}
|
||||||
|
|
||||||
<table class="build">
|
<table class="build">
|
||||||
<colgroup class="col-hash"></colgroup>
|
<colgroup class="col-hash" {{if $.Package.Path}}span="2"{{end}}></colgroup>
|
||||||
{{range $.Builders | builderSpans}}
|
{{range $.Builders | builderSpans}}
|
||||||
<colgroup class="col-result" span="{{.N}}"></colgroup>
|
<colgroup class="col-result" span="{{.N}}"></colgroup>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -91,7 +92,11 @@
|
||||||
<!-- extra row to make alternating colors use dark for first result -->
|
<!-- extra row to make alternating colors use dark for first result -->
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
{{if $.Package.Path}}
|
||||||
|
<th colspan="2">revision</th>
|
||||||
|
{{else}}
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
{{end}}
|
||||||
{{range $.Builders | builderSpans}}
|
{{range $.Builders | builderSpans}}
|
||||||
<th colspan="{{.N}}">{{.OS}}</th>
|
<th colspan="{{.N}}">{{.OS}}</th>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -100,17 +105,30 @@
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
{{if $.Package.Path}}
|
||||||
|
<th class="result arch">repo</th>
|
||||||
|
<th class="result arch">{{$.Dashboard.Name}}</th>
|
||||||
|
{{else}}
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
{{end}}
|
||||||
{{range $.Builders}}
|
{{range $.Builders}}
|
||||||
<th class="result arch" title="{{.}}">{{builderSubheading .}}</th>
|
<th class="result arch" title="{{.}}">{{builderSubheading .}}</th>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{range $c := $.Commits}}
|
{{range $c := $.Commits}}
|
||||||
|
{{range $i, $h := $c.ResultGoHashes}}
|
||||||
<tr class="commit">
|
<tr class="commit">
|
||||||
<td class="hash"><a href="{{repoURL $.Dashboard.Name .Hash ""}}">{{shortHash .Hash}}</a></td>
|
{{if $i}}
|
||||||
|
<td> </td>
|
||||||
|
{{else}}
|
||||||
|
<td class="hash"><a href="{{repoURL $.Dashboard.Name $c.Hash $.Package.Path}}">{{shortHash $c.Hash}}</a></td>
|
||||||
|
{{end}}
|
||||||
|
{{if $h}}
|
||||||
|
<td class="hash"><a href="{{repoURL $.Dashboard.Name $h ""}}">{{shortHash $h}}</a></td>
|
||||||
|
{{end}}
|
||||||
{{range $.Builders}}
|
{{range $.Builders}}
|
||||||
<td class="result">
|
<td class="result">
|
||||||
{{with $c.Result . ""}}
|
{{with $c.Result . $h}}
|
||||||
{{if .OK}}
|
{{if .OK}}
|
||||||
<span class="ok">ok</span>
|
<span class="ok">ok</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
@ -121,17 +139,24 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</td>
|
</td>
|
||||||
{{end}}
|
{{end}}
|
||||||
<td class="user" title="{{.User}}">{{shortUser .User}}</td>
|
{{if $i}}
|
||||||
<td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
|
<td> </td>
|
||||||
<td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</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>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{end}}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{{with $.Pagination}}
|
{{with $.Pagination}}
|
||||||
<div class="paginate">
|
<div class="paginate">
|
||||||
<a {{if .HasPrev}}href="?page={{.Prev}}"{{else}}class="inactive"{{end}}>newer</a>
|
<a {{if .HasPrev}}href="?{{with $.Package.Path}}repo={{.}}&{{end}}page={{.Prev}}"{{else}}class="inactive"{{end}}>newer</a>
|
||||||
<a {{if .Next}}href="?page={{.Next}}"{{else}}class="inactive"{{end}}>older</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>
|
<a {{if .HasPrev}}href="."{{else}}class="inactive"{{end}}>latest</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -182,7 +207,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{{range $pkg := .Packages}}
|
{{range $pkg := .Packages}}
|
||||||
<tr class="commit">
|
<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">
|
<td class="hash">
|
||||||
{{$h := $pkg.Commit.Hash}}
|
{{$h := $pkg.Commit.Hash}}
|
||||||
<a href="{{repoURL $.Dashboard.Name $h $pkg.Commit.PackagePath}}">{{shortHash $h}}</a>
|
<a href="{{repoURL $.Dashboard.Name $h $pkg.Commit.PackagePath}}">{{shortHash $h}}</a>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue