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

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

Issue 2718373004: Milo: Print raw json for buildbot build properties (Closed)
Patch Set: Just render the JSON string 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
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 representation of v based off k, and a boolean to
nodir 2017/04/11 07:13:19 there is no k
nodir 2017/04/11 07:13:19 high level: i think JSON encoding should be in a t
hinoka 2017/04/13 21:01:59 This was done this was because previously rietveld
317 // specify whether or not to hide it altogether. 318 // specify whether or not to hide it altogether.
nodir 2017/04/11 07:13:19 after I read this, i thought the function returns
hinoka 2017/04/13 21:01:59 Removed block.
318 func parseProp(prop map[string]Prop, k string, v interface{}) (string, bool) { 319 func parseProp(v interface{}) (string, bool) {
319 » switch k { 320 » if vs, ok := v.(string); ok && vs == "" {
320 » case "requestedAt": 321 » » return "", false // Value is empty, don't show it.
nodir 2017/04/11 07:13:19 why we are hiding empty strings? They are legit va
hinoka 2017/04/13 21:01:59 They why is because it seems kind of useless to di
nodir 2017/04/13 21:08:20 Yeah, I think they should be there. Imagine someon
321 » » if vf, ok := v.(float64); ok { 322 » }
322 » » » return time.Unix(int64(vf), 0).UTC().Format(time.RFC3339 ), true 323 » if v == nil {
324 » » return "", false
325 » }
326 » // if v is a whole number, force it into an int. json.Marshal() would t urn
327 » // it into what looks like a float instead. We want this to remain and
328 » // int instead of a number.
329 » if vf, ok := v.(float64); ok {
330 » » if math.Floor(vf) == vf {
331 » » » return fmt.Sprintf("%d", int64(vf)), true
323 } 332 }
324 » case "buildbucket": 333 » }
325 » » var b map[string]interface{} 334 » // return the json representation of the value.
326 » » json.Unmarshal([]byte(v.(string)), &b) 335 » b, err := json.Marshal(v)
327 » » if b["build"] == nil { 336 » if err == nil {
328 » » » return "", false 337 » » return string(b), true
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 » » }
357 } 338 }
358 return fmt.Sprintf("%v", v), true 339 return fmt.Sprintf("%v", v), true
359 } 340 }
360 341
361 // Prop is a struct used to store a value and group so that we can make a map 342 // 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 343 // of key:Prop to pass into parseProp() for the purpose of cross referencing
363 // one prop while working on another. 344 // one prop while working on another.
364 type Prop struct { 345 type Prop struct {
365 Value interface{} 346 Value interface{}
366 Group string 347 Group string
367 } 348 }
368 349
369 // properties extracts all properties from buildbot builds and groups them into 350 // properties extracts all properties from buildbot builds and groups them into
370 // property groups. 351 // property groups.
371 func properties(b *buildbotBuild) (result []*resp.PropertyGroup) { 352 func properties(b *buildbotBuild) (result []*resp.PropertyGroup) {
372 groups := map[string]*resp.PropertyGroup{} 353 groups := map[string]*resp.PropertyGroup{}
373 allProps := map[string]Prop{} 354 allProps := map[string]Prop{}
374 for _, prop := range b.Properties { 355 for _, prop := range b.Properties {
375 allProps[prop.Name] = Prop{ 356 allProps[prop.Name] = Prop{
376 Value: prop.Value, 357 Value: prop.Value,
377 Group: prop.Source, 358 Group: prop.Source,
378 } 359 }
379 } 360 }
380 for key, prop := range allProps { 361 for key, prop := range allProps {
381 value := prop.Value 362 value := prop.Value
382 groupName := prop.Group 363 groupName := prop.Group
383 if _, ok := groups[groupName]; !ok { 364 if _, ok := groups[groupName]; !ok {
384 groups[groupName] = &resp.PropertyGroup{GroupName: group Name} 365 groups[groupName] = &resp.PropertyGroup{GroupName: group Name}
385 } 366 }
386 » » vs, ok := parseProp(allProps, key, value) 367 » » vs, ok := parseProp(value)
387 if !ok { 368 if !ok {
388 continue 369 continue
389 } 370 }
390 groups[groupName].Property = append(groups[groupName].Property, &resp.Property{ 371 groups[groupName].Property = append(groups[groupName].Property, &resp.Property{
391 Key: key, 372 Key: key,
392 Value: vs, 373 Value: vs,
nodir 2017/04/11 07:13:20 i think this should be an interface{} and JSON-enc
hinoka 2017/04/13 21:01:59 I'll do that in a different CL. That would underm
393 }) 374 })
394 } 375 }
395 // Insert the groups into a list in alphabetical order. 376 // Insert the groups into a list in alphabetical order.
396 // You have to make a separate sorting data structure because Go doesn't like 377 // You have to make a separate sorting data structure because Go doesn't like
397 // sorting things for you. 378 // sorting things for you.
398 groupNames := []string{} 379 groupNames := []string{}
399 for n := range groups { 380 for n := range groups {
400 groupNames = append(groupNames, n) 381 groupNames = append(groupNames, n)
401 } 382 }
402 sort.Strings(groupNames) 383 sort.Strings(groupNames)
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 var newAliases map[string][]*buildbotLinkAlias 640 var newAliases map[string][]*buildbotLinkAlias
660 if l := remainingAliases.Len(); l > 0 { 641 if l := remainingAliases.Len(); l > 0 {
661 newAliases = make(map[string][]*buildbotLinkAlias, l) 642 newAliases = make(map[string][]*buildbotLinkAlias, l)
662 remainingAliases.Iter(func(v string) bool { 643 remainingAliases.Iter(func(v string) bool {
663 newAliases[v] = s.Aliases[v] 644 newAliases[v] = s.Aliases[v]
664 return true 645 return true
665 }) 646 })
666 } 647 }
667 s.Aliases = newAliases 648 s.Aliases = newAliases
668 } 649 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698