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  }