Skip to content

Commit

Permalink
added environment variable ICE_COLOR
Browse files Browse the repository at this point in the history
updated colours to support custom colours
tidied up colour code
updated readme
  • Loading branch information
NimbleArchitect committed Feb 7, 2023
1 parent 13166b3 commit cea93fb
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 48 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ ice also supports all the standard kubectl flags in addition to:
Flags:
-A, --all-namespaces List containers from pods in all namespaces
--annotation string Show the selected annotation as a column
--color string Colour columns in the table output. string can be one of: columns, errors, mix, none
--color string Add some much needed colour to the table output. string can be one of: columns, custom, errors, mix and none (overrides environment variable ICE_COLOUR)
-c, --container string Container name. If set shows only the named containers
--context string The name of the kubeconfig context to use
-m, --match string Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and !=
Expand Down
27 changes: 19 additions & 8 deletions pkg/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ type commonFlags struct {
annotationPodName string
showColumnByName string // list of column names to show, overrides other hidden columns
outputAsColour int // which coloring type do we use when displaying columns
useTheseColours [][2]int
}

const (
COLOUR_NONE = 0
COLOUR_ERRORS = 1
COLOUR_COLUMNS = 2
COLOUR_MIX = 3
COLOUR_CUSTOM = 4
COLOUR_NONE = 0
COLOUR_ERRORS = 1
COLOUR_COLUMNS = 2
COLOUR_MIX = 3
COLOUR_CUSTOM = 4
COLOUR_CUSTOMMIX = 5
)

func InitSubCommands(rootCmd *cobra.Command) {
Expand Down Expand Up @@ -390,7 +392,7 @@ func addCommonFlags(cmdObj *cobra.Command) {
cmdObj.Flags().StringP("annotation", "", "", `Show the selected annotation as a column`)
cmdObj.Flags().StringP("filename", "f", "", `read pod information from this yaml file instead`)
cmdObj.Flags().StringP("columns", "", "", `list of column names to show in the table output, all other columns are hidden`)
cmdObj.Flags().StringP("color", "", "", `Colour columns in the table output. string can be one of: columns, errors, mix, none`)
cmdObj.Flags().StringP("color", "", "", `Add some much needed colour to the table output. string can be one of: columns, custom, errors, mix and none (overrides env variable ICE_COLOUR)`)
}

func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
Expand Down Expand Up @@ -562,7 +564,10 @@ func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {

if len(colourOut) > 0 {
// we use a switch to match --colour flag so I can expand in future
switch strings.ToLower(colourOut) {
colourEnv := strings.ToLower(colourOut)
colourSet := strings.Split(colourEnv, ";")

switch strings.ToLower(colourSet[0]) {
case "mix":
f.outputAsColour = COLOUR_MIX
case "columns":
Expand All @@ -571,9 +576,15 @@ func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
f.outputAsColour = COLOUR_ERRORS
case "none":
f.outputAsColour = COLOUR_NONE
case "custom":
// f.outputAsColour = COLOUR_CUSTOM
f.useTheseColours, f.outputAsColour, err = getColourSetFromString(colourSet[1:])
if err != nil {
return commonFlags{}, err
}

default:
return commonFlags{}, errors.New("unknown colour type only columns, errors, mix and none are supported")
return commonFlags{}, errors.New("unknown colour type only columns, custom, errors, mix and none are supported")
}
}

Expand Down
19 changes: 10 additions & 9 deletions pkg/plugin/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func Status(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args [

table := Table{}
table.ColourOutput = commonFlagList.outputAsColour
table.CustomColours = commonFlagList.useTheseColours

builder.Table = &table
log.Debug("commonFlagList.showTreeView =", commonFlagList.showTreeView)
Expand Down Expand Up @@ -203,20 +204,20 @@ func (s *status) BuildBranch(info BuilderInformation, rows [][]Cell) ([]Cell, er
// rowOut[10] // message

rowOut[0].text = "true"
rowOut[0].colour = [2]int{colourOk, colourModOk}
rowOut[0].colour = colourOk
rowOut[1].text = "true"
rowOut[1].colour = [2]int{colourOk, colourModOk}
rowOut[1].colour = colourOk

// loop through each row in podTotals and add the columns in each row
for _, r := range rows {
if r[0].text == "false" {
// ready = false
rowOut[0].text = "false" // ready
rowOut[0].colour = [2]int{colourBad, colourModBad}
rowOut[0].colour = colourBad
}
if r[1].text == "false" {
rowOut[1].text = "false" // started
rowOut[1].colour = [2]int{colourBad, colourModBad}
rowOut[1].colour = colourBad
}
rowOut[2].number += r[2].number // restarts

Expand All @@ -232,7 +233,7 @@ func (s *status) BuildBranch(info BuilderInformation, rows [][]Cell) ([]Cell, er
rowOut[3].text = string(info.Data.pod.Status.Phase) // state
} else {
rowOut[3].text = "Terminating" // state
rowOut[3].colour = [2]int{colourWarn, colourModWarn}
rowOut[3].colour = colourWarn
}
rowOut[4].text = info.Data.pod.Status.Reason // reason
rowOut[8].text = info.Data.pod.CreationTimestamp.Format(timestampFormat) // timestamp
Expand Down Expand Up @@ -277,7 +278,7 @@ func (s *status) BuildContainerStatus(container v1.ContainerStatus, info Builder
message = state.Waiting.Message
// waiting state dosent have a start time so we skip setting the age variable, used further down
skipAgeCalculation = true
colourcode = [2]int{colourWarn, colourModWarn}
colourcode = colourWarn
}

if state.Terminated != nil {
Expand All @@ -292,17 +293,17 @@ func (s *status) BuildContainerStatus(container v1.ContainerStatus, info Builder
message = state.Terminated.Message

if rawExitCode == 0 {
colourcode = [2]int{colourOk, colourModOk}
colourcode = colourOk
} else {
colourcode = [2]int{colourBad, colourModBad}
colourcode = colourBad
}
}

if state.Running != nil {
strState = "Running"
startedAt = state.Running.StartedAt.Format(timestampFormat)
startTime = state.Running.StartedAt.Time
colourcode = [2]int{colourOk, colourModOk}
colourcode = colourOk
}

if container.Started != nil {
Expand Down
70 changes: 51 additions & 19 deletions pkg/plugin/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Table struct {
placeHolder map[int][]Cell
placeHolderID int
ColourOutput int
CustomColours [][2]int
}

// SetHeader sets the header row to the specified array of strings
Expand Down Expand Up @@ -178,18 +179,41 @@ func (t *Table) Print() {
var cellcolour [2]int
var withColour bool
var visibleColumns int

headLine := ""
colourArray := make([][2]int, t.headCount)

if t.ColourOutput != COLOUR_NONE {
switch t.ColourOutput {
case COLOUR_NONE:
withColour = false
case COLOUR_CUSTOMMIX:
fallthrough
case COLOUR_CUSTOM:
withColour = true
maxColours := len(t.CustomColours)
for i := 0; i < t.headCount; i++ {
colourCode := int(math.Mod(float64(i), float64(maxColours)))
colourArray[i][0] = t.CustomColours[colourCode][0] // colour
colourArray[i][1] = t.CustomColours[colourCode][1] // colour modifier
}
default:
withColour = true

maxColours := 7
// generate the colour numbers for the default colour wheel, the colour set is repeated if there are more heades than colours
maxColours := 14
modFlip := 0

for i := 0; i < t.headCount; i++ {
colourCode := int(math.Mod(float64(i), float64(maxColours)))
colourArray[i][0] = colourCode + 30
if colourCode < 6 {
// we start at 31 and increase for 6 colours this allow us to excclude black and light gray
colourArray[i][0] = colourCode + 31
} else {
// the second set covers the dark variations of the colours
colourArray[i][0] = colourCode + 84
}

// we flip the text to bold after every colour run
colourArray[i][1] = modFlip

if colourCode >= maxColours-1 {
Expand Down Expand Up @@ -219,7 +243,7 @@ func (t *Table) Print() {
word = "-"
}

if t.ColourOutput == COLOUR_MIX || t.ColourOutput == COLOUR_COLUMNS {
if t.ColourOutput != COLOUR_NONE && t.ColourOutput != COLOUR_ERRORS {
word = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], word, colourEnd)
}
pad := strings.Repeat(" ", t.head[idx].columnLength-runelen)
Expand Down Expand Up @@ -257,7 +281,26 @@ func (t *Table) Print() {
continue
}

cellcolour := colourArray[visibleColumns]
if withColour { // if colour wanted
cellcolour = colourArray[visibleColumns] //set colour from wheel as default colour
switch t.ColourOutput {
case COLOUR_ERRORS:
// override if we should only show error colours
if cell.colour[0] != -1 {
cellcolour = cell.colour
} else {
cellcolour[0] = -1
}
case COLOUR_CUSTOMMIX:
fallthrough
case COLOUR_MIX:
// override if we should mix colours
if cell.colour[0] > 0 {
cellcolour = cell.colour
}
}
}

visibleColumns += 1

if len(cell.text) == 0 {
Expand All @@ -273,20 +316,9 @@ func (t *Table) Print() {
pad := strings.Repeat(" ", spaceCount)

// colour output has been set and the cell has data
if withColour {
if t.ColourOutput == COLOUR_MIX || t.ColourOutput == COLOUR_COLUMNS {
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
}

// we check for errors last so it can overwrite the column colours when we are using the mix colour set
if cell.colour[0] > -1 && (t.ColourOutput == COLOUR_ERRORS || t.ColourOutput == COLOUR_MIX) {
// error colour set uses red/yellow/green for ok/warning/problem
if cell.colour[0] == 0 && t.ColourOutput == COLOUR_MIX {
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
} else {
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cell.colour[1], cell.colour[0], origtxt, colourEnd)
}
}
if withColour && cellcolour[0] != -1 {
// so we add the colour codes and modifier
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
}

line += fmt.Sprint(celltxt, pad)
Expand Down
Loading

0 comments on commit cea93fb

Please sign in to comment.