github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/control/controldisplay/result.go (about)

     1  package controldisplay
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/spf13/viper"
     7  	"github.com/turbot/go-kit/helpers"
     8  	"github.com/turbot/steampipe/pkg/constants"
     9  	"github.com/turbot/steampipe/pkg/control/controlexecute"
    10  )
    11  
    12  const minReasonWidth = 10
    13  
    14  type ResultRenderer struct {
    15  	status         string
    16  	reason         string
    17  	dimensions     []controlexecute.Dimension
    18  	colorGenerator *controlexecute.DimensionColorGenerator
    19  
    20  	// screen width
    21  	width int
    22  	// if true, only display failed results
    23  	errorsOnly bool
    24  	indent     string
    25  }
    26  
    27  func NewResultRenderer(status, reason string, dimensions []controlexecute.Dimension, colorGenerator *controlexecute.DimensionColorGenerator, width int, indent string) *ResultRenderer {
    28  	return &ResultRenderer{
    29  		status:         status,
    30  		reason:         reason,
    31  		dimensions:     dimensions,
    32  		colorGenerator: colorGenerator,
    33  		width:          width,
    34  		errorsOnly:     viper.GetString(constants.ArgOutput) == "brief",
    35  		indent:         indent,
    36  	}
    37  }
    38  
    39  func (r ResultRenderer) Render() string {
    40  	// in quiet mode, only render failures
    41  	if r.errorsOnly && !helpers.StringSliceContains([]string{string(constants.ControlAlarm), string(constants.ControlError)}, r.status) {
    42  		return ""
    43  	}
    44  
    45  	status := NewResultStatusRenderer(r.status)
    46  	statusString := status.Render()
    47  	statusWidth := helpers.PrintableLength(statusString)
    48  
    49  	formattedIndent := fmt.Sprintf("%s", ControlColors.Indent(r.indent))
    50  	indentWidth := helpers.PrintableLength(formattedIndent)
    51  
    52  	// figure out how much width we have available for the  dimensions, allowing the minimum for the reason
    53  	availableWidth := r.width - statusWidth - indentWidth
    54  
    55  	// for now give this all to reason
    56  	availableDimensionWidth := availableWidth - minReasonWidth
    57  	var dimensionsString string
    58  	var dimensionWidth int
    59  	if availableDimensionWidth > 0 {
    60  		dimensionsString = NewDimensionsRenderer(r.dimensions, r.colorGenerator, availableDimensionWidth).Render()
    61  		dimensionWidth = helpers.PrintableLength(dimensionsString)
    62  		availableWidth -= dimensionWidth
    63  	}
    64  
    65  	// now availableWidth is all we have - if it is not enough we need to truncate the reason
    66  	reasonString := NewResultReasonRenderer(r.status, r.reason, availableWidth).Render()
    67  	reasonWidth := helpers.PrintableLength(reasonString)
    68  
    69  	// is there any room for a spacer
    70  	availableWidth -= reasonWidth
    71  	var spacerString string
    72  	if availableWidth > 0 && r.dimensions != nil {
    73  		spacerString = NewSpacerRenderer(availableWidth).Render()
    74  	}
    75  
    76  	// now put these all together
    77  	str := fmt.Sprintf("%s%s%s%s%s", formattedIndent, statusString, reasonString, spacerString, dimensionsString)
    78  	return str
    79  }