Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: milo/appengine/buildbot/build.go

Issue 2718373004: Milo: Print raw json for buildbot build properties (Closed)
Patch Set: Add in empty strings Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | milo/appengine/buildbot/expectations/CrWinGoma.30608.build.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package buildbot 5 package buildbot
6 6
7 import ( 7 import (
8 "encoding/json" 8 "encoding/json"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
11 "io/ioutil" 11 "io/ioutil"
12 "math"
12 "path/filepath" 13 "path/filepath"
13 "regexp" 14 "regexp"
14 "sort" 15 "sort"
15 "strings" 16 "strings"
16 "time" 17 "time"
17 18
18 "golang.org/x/net/context" 19 "golang.org/x/net/context"
19 20
20 "github.com/luci/gae/service/datastore" 21 "github.com/luci/gae/service/datastore"
21 "github.com/luci/luci-go/common/data/stringset" 22 "github.com/luci/luci-go/common/data/stringset"
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 } 307 }
307 308
308 // Figure out the times. 309 // Figure out the times.
309 bc.Started, bc.Finished, bc.Duration = parseTimes(endingTime, st ep.Times) 310 bc.Started, bc.Finished, bc.Duration = parseTimes(endingTime, st ep.Times)
310 311
311 result = append(result, bc) 312 result = append(result, bc)
312 } 313 }
313 return 314 return
314 } 315 }
315 316
316 // parseProp returns a representation of v based off k, and a boolean to 317 // parseProp returns a string representation of v.
317 // specify whether or not to hide it altogether. 318 func parseProp(v interface{}) string {
318 func parseProp(prop map[string]Prop, k string, v interface{}) (string, bool) { 319 » // if v is a whole number, force it into an int. json.Marshal() would t urn
319 » switch k { 320 » // it into what looks like a float instead. We want this to remain and
320 » case "requestedAt": 321 » // int instead of a number.
321 » » if vf, ok := v.(float64); ok { 322 » if vf, ok := v.(float64); ok {
322 » » » return time.Unix(int64(vf), 0).UTC().Format(time.RFC3339 ), true 323 » » if math.Floor(vf) == vf {
323 » » } 324 » » » return fmt.Sprintf("%d", int64(vf))
324 » case "buildbucket":
325 » » var b map[string]interface{}
326 » » json.Unmarshal([]byte(v.(string)), &b)
327 » » if b["build"] == nil {
328 » » » return "", false
329 » » }
330 » » build := b["build"].(map[string]interface{})
331 » » id := build["id"]
332 » » if id == nil {
333 » » » return "", false
334 » » }
335 » » return fmt.Sprintf("https://cr-buildbucket.appspot.com/b/%s", id .(string)), true
336 » case "issue":
337 » » if rv, ok := prop["rietveld"]; ok {
338 » » » rietveld := rv.Value.(string)
339 » » » // Issue could be a float, int, or string.
340 » » » switch v := v.(type) {
341 » » » case float64:
342 » » » » return fmt.Sprintf("%s/%d", rietveld, int(v)), t rue
343 » » » default: // Probably int or string
344 » » » » return fmt.Sprintf("%s/%v", rietveld, v), true
345 » » » }
346 » » }
347 » » return fmt.Sprintf("%d", int(v.(float64))), true
348 » case "rietveld":
349 » » return "", false
350 » default:
351 » » if vs, ok := v.(string); ok && vs == "" {
352 » » » return "", false // Value is empty, don't show it.
353 » » }
354 » » if v == nil {
355 » » » return "", false
356 } 325 }
357 } 326 }
358 » return fmt.Sprintf("%v", v), true 327 » // return the json representation of the value.
328 » b, err := json.Marshal(v)
329 » if err == nil {
330 » » return string(b)
331 » }
332 » return fmt.Sprintf("%v", v)
359 } 333 }
360 334
361 // Prop is a struct used to store a value and group so that we can make a map 335 // Prop is a struct used to store a value and group so that we can make a map
362 // of key:Prop to pass into parseProp() for the purpose of cross referencing 336 // of key:Prop to pass into parseProp() for the purpose of cross referencing
363 // one prop while working on another. 337 // one prop while working on another.
364 type Prop struct { 338 type Prop struct {
365 Value interface{} 339 Value interface{}
366 Group string 340 Group string
367 } 341 }
368 342
369 // properties extracts all properties from buildbot builds and groups them into 343 // properties extracts all properties from buildbot builds and groups them into
370 // property groups. 344 // property groups.
371 func properties(b *buildbotBuild) (result []*resp.PropertyGroup) { 345 func properties(b *buildbotBuild) (result []*resp.PropertyGroup) {
372 groups := map[string]*resp.PropertyGroup{} 346 groups := map[string]*resp.PropertyGroup{}
373 allProps := map[string]Prop{} 347 allProps := map[string]Prop{}
374 for _, prop := range b.Properties { 348 for _, prop := range b.Properties {
375 allProps[prop.Name] = Prop{ 349 allProps[prop.Name] = Prop{
376 Value: prop.Value, 350 Value: prop.Value,
377 Group: prop.Source, 351 Group: prop.Source,
378 } 352 }
379 } 353 }
380 for key, prop := range allProps { 354 for key, prop := range allProps {
381 value := prop.Value 355 value := prop.Value
382 groupName := prop.Group 356 groupName := prop.Group
383 if _, ok := groups[groupName]; !ok { 357 if _, ok := groups[groupName]; !ok {
384 groups[groupName] = &resp.PropertyGroup{GroupName: group Name} 358 groups[groupName] = &resp.PropertyGroup{GroupName: group Name}
385 } 359 }
386 » » vs, ok := parseProp(allProps, key, value) 360 » » vs := parseProp(value)
387 » » if !ok {
388 » » » continue
389 » » }
390 groups[groupName].Property = append(groups[groupName].Property, &resp.Property{ 361 groups[groupName].Property = append(groups[groupName].Property, &resp.Property{
391 Key: key, 362 Key: key,
392 Value: vs, 363 Value: vs,
393 }) 364 })
394 } 365 }
395 // Insert the groups into a list in alphabetical order. 366 // Insert the groups into a list in alphabetical order.
396 // You have to make a separate sorting data structure because Go doesn't like 367 // You have to make a separate sorting data structure because Go doesn't like
397 // sorting things for you. 368 // sorting things for you.
398 groupNames := []string{} 369 groupNames := []string{}
399 for n := range groups { 370 for n := range groups {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 var newAliases map[string][]*buildbotLinkAlias 630 var newAliases map[string][]*buildbotLinkAlias
660 if l := remainingAliases.Len(); l > 0 { 631 if l := remainingAliases.Len(); l > 0 {
661 newAliases = make(map[string][]*buildbotLinkAlias, l) 632 newAliases = make(map[string][]*buildbotLinkAlias, l)
662 remainingAliases.Iter(func(v string) bool { 633 remainingAliases.Iter(func(v string) bool {
663 newAliases[v] = s.Aliases[v] 634 newAliases[v] = s.Aliases[v]
664 return true 635 return true
665 }) 636 })
666 } 637 }
667 s.Aliases = newAliases 638 s.Aliases = newAliases
668 } 639 }
OLDNEW
« no previous file with comments | « no previous file | milo/appengine/buildbot/expectations/CrWinGoma.30608.build.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698