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

     1  package controldisplay
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/logrusorgru/aurora"
     8  	"github.com/turbot/steampipe/pkg/constants"
     9  	"github.com/turbot/steampipe/pkg/utils"
    10  )
    11  
    12  type colorFunc func(interface{}) aurora.Value
    13  
    14  // ControlColors is a global variable containing the current control color scheme
    15  var ControlColors *ControlColorScheme
    16  
    17  type ControlColorSchemaDefinition struct {
    18  	// group
    19  	GroupTitle           string
    20  	Severity             string
    21  	CountZeroFail        string
    22  	CountZeroFailDivider string
    23  	CountDivider         string
    24  	CountFail            string
    25  	CountTotal           string
    26  	CountTotalAllPassed  string
    27  	CountGraphFail       string
    28  	CountGraphPass       string
    29  	CountGraphAlarm      string
    30  	CountGraphError      string
    31  	CountGraphInfo       string
    32  	CountGraphOK         string
    33  	CountGraphSkip       string
    34  	CountGraphBracket    string
    35  
    36  	// results
    37  	StatusAlarm string
    38  	StatusError string
    39  	StatusSkip  string
    40  	StatusInfo  string
    41  	StatusOK    string
    42  	StatusColon string
    43  	ReasonAlarm string
    44  	ReasonError string
    45  	ReasonSkip  string
    46  	ReasonInfo  string
    47  	ReasonOK    string
    48  
    49  	Spacer   string
    50  	Indent   string
    51  	UseColor bool
    52  }
    53  
    54  type ControlColorScheme struct {
    55  	GroupTitle           colorFunc
    56  	Severity             colorFunc
    57  	CountZeroFail        colorFunc
    58  	CountZeroFailDivider colorFunc
    59  	CountDivider         colorFunc
    60  	CountFail            colorFunc
    61  	CountTotal           colorFunc
    62  	CountTotalAllPassed  colorFunc
    63  	CountGraphFail       colorFunc
    64  	CountGraphPass       colorFunc
    65  	CountGraphAlarm      colorFunc
    66  	CountGraphError      colorFunc
    67  	CountGraphInfo       colorFunc
    68  	CountGraphOK         colorFunc
    69  	CountGraphSkip       colorFunc
    70  	CountGraphBracket    colorFunc
    71  	StatusAlarm          colorFunc
    72  	StatusError          colorFunc
    73  	StatusSkip           colorFunc
    74  	StatusInfo           colorFunc
    75  	StatusOK             colorFunc
    76  	StatusColon          colorFunc
    77  	ReasonAlarm          colorFunc
    78  	ReasonError          colorFunc
    79  	ReasonSkip           colorFunc
    80  	ReasonInfo           colorFunc
    81  	ReasonOK             colorFunc
    82  	Spacer               colorFunc
    83  	Indent               colorFunc
    84  
    85  	ReasonColors map[string]colorFunc
    86  	StatusColors map[string]colorFunc
    87  	GraphColors  map[string]colorFunc
    88  	UseColor     bool
    89  }
    90  
    91  func NewControlColorScheme(def *ControlColorSchemaDefinition) (*ControlColorScheme, error) {
    92  	res := &ControlColorScheme{
    93  		ReasonColors: make(map[string]colorFunc),
    94  		StatusColors: make(map[string]colorFunc),
    95  	}
    96  	err := res.Initialise(def)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	return res, nil
   101  }
   102  
   103  func (c *ControlColorScheme) Initialise(def *ControlColorSchemaDefinition) error {
   104  	destV := reflect.ValueOf(c).Elem()
   105  
   106  	nullColorFunc := func(val interface{}) aurora.Value { return aurora.Reset(val) }
   107  	var validationErrors []string
   108  
   109  	v := reflect.ValueOf(def).Elem()
   110  	t := v.Type()
   111  	for i := 0; i < v.NumField(); i++ {
   112  		fieldValue := v.Field(i)
   113  		fieldType := t.Field(i)
   114  
   115  		// all string fields are colors skip non string fields
   116  		if fieldType.Type.Name() != "string" {
   117  			continue
   118  		}
   119  
   120  		colorString := fieldValue.Interface().(string)
   121  		property := fieldType.Name
   122  		// find corresponding field in dest
   123  		destField := destV.FieldByName(property)
   124  
   125  		// if no color is set, use null color function
   126  		if colorString == "" {
   127  			destField.Set(reflect.ValueOf(nullColorFunc))
   128  			continue
   129  		}
   130  
   131  		// is this a valid color string?
   132  		if f, ok := constants.Colors[colorString]; ok {
   133  			destField.Set(reflect.ValueOf(f))
   134  		} else {
   135  			validationErrors = append(validationErrors, property)
   136  		}
   137  	}
   138  	if len(validationErrors) > 0 {
   139  		return fmt.Errorf("invalid color scheme. %d %s have invalid colors: %v",
   140  			len(validationErrors),
   141  			utils.Pluralize("property", len(validationErrors)),
   142  			validationErrors)
   143  	}
   144  	// populate the color maps
   145  	c.ReasonColors = map[string]colorFunc{
   146  		constants.ControlAlarm: c.ReasonAlarm,
   147  		constants.ControlSkip:  c.ReasonSkip,
   148  		constants.ControlInfo:  c.ReasonInfo,
   149  		constants.ControlError: c.ReasonError,
   150  		constants.ControlOk:    c.ReasonOK,
   151  	}
   152  	c.StatusColors = map[string]colorFunc{
   153  		constants.ControlAlarm: c.StatusAlarm,
   154  		constants.ControlSkip:  c.StatusSkip,
   155  		constants.ControlInfo:  c.StatusInfo,
   156  		constants.ControlError: c.StatusError,
   157  		constants.ControlOk:    c.StatusOK,
   158  	}
   159  	c.GraphColors = map[string]colorFunc{
   160  		constants.ControlAlarm: c.CountGraphAlarm,
   161  		constants.ControlSkip:  c.CountGraphSkip,
   162  		constants.ControlInfo:  c.CountGraphInfo,
   163  		constants.ControlError: c.CountGraphError,
   164  		constants.ControlOk:    c.CountGraphOK,
   165  	}
   166  
   167  	c.UseColor = def.UseColor
   168  	return nil
   169  }
   170  
   171  var ColorSchemes = map[string]*ControlColorSchemaDefinition{
   172  	"dark": {
   173  		GroupTitle:           "bold-bright-white",
   174  		Severity:             "bold-bright-yellow",
   175  		CountZeroFail:        "gray1",
   176  		CountZeroFailDivider: "gray1",
   177  		CountDivider:         "gray2",
   178  		CountFail:            "bold-bright-red",
   179  		CountTotal:           "bright-white",
   180  		CountTotalAllPassed:  "bold-bright-green",
   181  		CountGraphFail:       "bright-red",
   182  		CountGraphPass:       "bright-green",
   183  		CountGraphAlarm:      "bright-red",
   184  		CountGraphError:      "bright-red",
   185  		CountGraphInfo:       "bright-cyan",
   186  		CountGraphOK:         "bright-green",
   187  		CountGraphSkip:       "gray3",
   188  		CountGraphBracket:    "gray2",
   189  		StatusAlarm:          "bold-bright-red",
   190  		StatusError:          "bold-bright-red",
   191  		StatusSkip:           "gray3",
   192  		StatusInfo:           "bright-cyan",
   193  		StatusOK:             "bright-green",
   194  		StatusColon:          "gray1",
   195  		ReasonAlarm:          "bright-red",
   196  		ReasonError:          "bright-red",
   197  		ReasonSkip:           "gray3",
   198  		ReasonInfo:           "bright-cyan",
   199  		ReasonOK:             "gray4",
   200  		Spacer:               "gray1",
   201  		Indent:               "gray1",
   202  		UseColor:             true,
   203  	},
   204  	"light": {
   205  		GroupTitle:           "bold-bright-black",
   206  		Severity:             "bold-bright-yellow",
   207  		CountZeroFail:        "gray5",
   208  		CountZeroFailDivider: "gray5",
   209  		CountDivider:         "gray4",
   210  		CountFail:            "bold-bright-red",
   211  		CountTotal:           "bright-black",
   212  		CountTotalAllPassed:  "bold-bright-green",
   213  		CountGraphFail:       "bright-red",
   214  		CountGraphPass:       "bright-green",
   215  		CountGraphAlarm:      "bright-red",
   216  		CountGraphError:      "bright-red",
   217  		CountGraphInfo:       "bright-cyan",
   218  		CountGraphOK:         "bright-green",
   219  		CountGraphSkip:       "gray3",
   220  		CountGraphBracket:    "gray4",
   221  		StatusAlarm:          "bold-bright-red",
   222  		StatusError:          "bold-bright-red",
   223  		StatusSkip:           "gray3",
   224  		StatusInfo:           "bright-cyan",
   225  		StatusOK:             "bright-green",
   226  		StatusColon:          "gray5",
   227  		ReasonAlarm:          "bright-red",
   228  		ReasonError:          "bright-red",
   229  		ReasonSkip:           "gray3",
   230  		ReasonInfo:           "bright-cyan",
   231  		ReasonOK:             "gray2",
   232  		Spacer:               "gray5",
   233  		Indent:               "gray5",
   234  		UseColor:             true,
   235  	},
   236  	"plain": {UseColor: false},
   237  }