github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/eventstream/render.go (about) 1 package eventstream 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 "github.com/pf-qiu/concourse/v6/atc/event" 9 "github.com/pf-qiu/concourse/v6/fly/ui" 10 "github.com/pf-qiu/concourse/v6/go-concourse/concourse/eventstream" 11 "github.com/fatih/color" 12 ) 13 14 type RenderOptions struct { 15 ShowTimestamp bool 16 IgnoreEventParsingErrors bool 17 } 18 19 func Render(dst io.Writer, src eventstream.EventStream, options RenderOptions) int { 20 dstImpl := NewTimestampedWriter(dst, options.ShowTimestamp) 21 22 exitStatus := 0 23 24 for { 25 ev, err := src.NextEvent() 26 if err != nil { 27 if err == io.EOF { 28 return exitStatus 29 } else if options.IgnoreEventParsingErrors && isEventParseError(err) { 30 continue 31 } else { 32 dstImpl.SetTimestamp(0) 33 fmt.Fprintf(dstImpl, "failed to parse next event: %s\n", ui.ErroredColor.Sprint(err)) 34 return 255 35 } 36 } 37 38 switch e := ev.(type) { 39 case event.Log: 40 dstImpl.SetTimestamp(e.Time) 41 fmt.Fprintf(dstImpl, "%s", e.Payload) 42 43 case event.SelectedWorker: 44 dstImpl.SetTimestamp(e.Time) 45 fmt.Fprintf(dstImpl, "\x1b[1mselected worker:\x1b[0m %s\n", e.WorkerName) 46 47 case event.InitializeTask: 48 dstImpl.SetTimestamp(e.Time) 49 fmt.Fprintf(dstImpl, "\x1b[1minitializing\x1b[0m\n") 50 51 case event.StartTask: 52 buildConfig := e.TaskConfig 53 54 argv := strings.Join(append([]string{buildConfig.Run.Path}, buildConfig.Run.Args...), " ") 55 dstImpl.SetTimestamp(e.Time) 56 fmt.Fprintf(dstImpl, "\x1b[1mrunning %s\x1b[0m\n", argv) 57 58 case event.FinishTask: 59 exitStatus = e.ExitStatus 60 61 case event.Error: 62 errCol := ui.ErroredColor.SprintFunc() 63 dstImpl.SetTimestamp(0) 64 fmt.Fprintf(dstImpl, "%s\n", errCol(e.Message)) 65 66 case event.Status: 67 dstImpl.SetTimestamp(e.Time) 68 var printColor *color.Color 69 70 switch e.Status { 71 case "started": 72 continue 73 case "succeeded": 74 printColor = ui.SucceededColor 75 case "failed": 76 printColor = ui.FailedColor 77 78 if exitStatus == 0 { 79 exitStatus = 1 80 } 81 case "errored": 82 printColor = ui.ErroredColor 83 84 if exitStatus == 0 { 85 exitStatus = 2 86 } 87 case "aborted": 88 printColor = ui.AbortedColor 89 90 if exitStatus == 0 { 91 exitStatus = 3 92 } 93 default: 94 fmt.Fprintf(dstImpl, "unknown status: %s", e.Status) 95 return 255 96 } 97 98 printColorFunc := printColor.SprintFunc() 99 fmt.Fprintf(dstImpl, "%s\n", printColorFunc(e.Status)) 100 101 return exitStatus 102 } 103 } 104 } 105 106 func isEventParseError(err error) bool { 107 if _, ok := err.(event.UnknownEventTypeError); ok { 108 return true 109 } else if _, ok := err.(event.UnknownEventVersionError); ok { 110 return true 111 } 112 return false 113 }