get.porter.sh/porter@v1.3.0/pkg/porter/runs.go (about)

     1  package porter
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  	"time"
     7  
     8  	"get.porter.sh/porter/pkg/portercontext"
     9  	"get.porter.sh/porter/pkg/printer"
    10  	dtprinter "github.com/carolynvs/datetime-printer"
    11  )
    12  
    13  // RunListOptions represent options for showing runs of an installation
    14  type RunListOptions struct {
    15  	installationOptions
    16  	printer.PrintOptions
    17  }
    18  
    19  // Validate prepares for the list installation runs action and validates the args/options.
    20  func (so *RunListOptions) Validate(args []string, cxt *portercontext.Context) error {
    21  	// Ensure only one argument exists (installation name) if args length non-zero
    22  	err := so.installationOptions.validateInstallationName(args)
    23  	if err != nil {
    24  		return err
    25  	}
    26  
    27  	err = so.installationOptions.defaultBundleFiles(cxt)
    28  	if err != nil {
    29  		return err
    30  	}
    31  
    32  	return so.PrintOptions.Validate(ShowDefaultFormat, ShowAllowedFormats)
    33  }
    34  
    35  type DisplayRuns []DisplayRun
    36  
    37  func (l DisplayRuns) Len() int {
    38  	return len(l)
    39  }
    40  
    41  func (l DisplayRuns) Swap(i, j int) {
    42  	l[i], l[j] = l[j], l[i]
    43  }
    44  
    45  func (l DisplayRuns) Less(i, j int) bool {
    46  	return l[i].Started.Before(l[j].Started)
    47  }
    48  
    49  func (p *Porter) ListInstallationRuns(ctx context.Context, opts RunListOptions) (DisplayRuns, error) {
    50  	err := p.applyDefaultOptions(ctx, &opts.installationOptions)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	var displayRuns DisplayRuns
    56  
    57  	runs, runResults, err := p.Installations.ListRuns(ctx, opts.Namespace, opts.Name)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	for _, run := range runs {
    63  		results := runResults[run.ID]
    64  
    65  		displayRun := NewDisplayRun(run)
    66  
    67  		if len(results) > 0 {
    68  			displayRun.Status = results[len(results)-1].Status
    69  
    70  			switch len(results) {
    71  			case 2:
    72  				displayRun.Started = results[0].Created
    73  				displayRun.Stopped = &results[1].Created
    74  			case 1:
    75  				displayRun.Started = results[0].Created
    76  			default:
    77  				displayRun.Stopped = &results[len(results)-1].Created
    78  			}
    79  		}
    80  
    81  		displayRuns = append(displayRuns, displayRun)
    82  	}
    83  
    84  	return displayRuns, nil
    85  }
    86  
    87  func (p *Porter) PrintInstallationRuns(ctx context.Context, opts RunListOptions) error {
    88  	displayRuns, err := p.ListInstallationRuns(ctx, opts)
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	sort.Sort(sort.Reverse(displayRuns))
    94  
    95  	switch opts.Format {
    96  	case printer.FormatJson:
    97  		return printer.PrintJson(p.Out, displayRuns)
    98  	case printer.FormatYaml:
    99  		return printer.PrintYaml(p.Out, displayRuns)
   100  	case printer.FormatPlaintext:
   101  		now := time.Now()
   102  		tp := dtprinter.DateTimePrinter{
   103  			Now: func() time.Time { return now },
   104  		}
   105  
   106  		row :=
   107  			func(v interface{}) []string {
   108  				a, ok := v.(DisplayRun)
   109  				if !ok {
   110  					return nil
   111  				}
   112  
   113  				stopped := ""
   114  				if a.Stopped != nil {
   115  					stopped = tp.Format(*a.Stopped)
   116  				}
   117  
   118  				return []string{a.ID, a.Action, tp.Format(a.Started), stopped, a.Status}
   119  			}
   120  		return printer.PrintTable(p.Out, displayRuns, row, "Run ID", "Action", "Started", "Stopped", "Status")
   121  	}
   122  
   123  	return nil
   124  }