Skip to content

Commit cea93fb

Browse files
added environment variable ICE_COLOR
updated colours to support custom colours tidied up colour code updated readme
1 parent 13166b3 commit cea93fb

File tree

5 files changed

+181
-48
lines changed

5 files changed

+181
-48
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ ice also supports all the standard kubectl flags in addition to:
108108
Flags:
109109
-A, --all-namespaces List containers from pods in all namespaces
110110
--annotation string Show the selected annotation as a column
111-
--color string Colour columns in the table output. string can be one of: columns, errors, mix, none
111+
--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)
112112
-c, --container string Container name. If set shows only the named containers
113113
--context string The name of the kubeconfig context to use
114114
-m, --match string Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and !=

pkg/plugin/plugin.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ type commonFlags struct {
3434
annotationPodName string
3535
showColumnByName string // list of column names to show, overrides other hidden columns
3636
outputAsColour int // which coloring type do we use when displaying columns
37+
useTheseColours [][2]int
3738
}
3839

3940
const (
40-
COLOUR_NONE = 0
41-
COLOUR_ERRORS = 1
42-
COLOUR_COLUMNS = 2
43-
COLOUR_MIX = 3
44-
COLOUR_CUSTOM = 4
41+
COLOUR_NONE = 0
42+
COLOUR_ERRORS = 1
43+
COLOUR_COLUMNS = 2
44+
COLOUR_MIX = 3
45+
COLOUR_CUSTOM = 4
46+
COLOUR_CUSTOMMIX = 5
4547
)
4648

4749
func InitSubCommands(rootCmd *cobra.Command) {
@@ -390,7 +392,7 @@ func addCommonFlags(cmdObj *cobra.Command) {
390392
cmdObj.Flags().StringP("annotation", "", "", `Show the selected annotation as a column`)
391393
cmdObj.Flags().StringP("filename", "f", "", `read pod information from this yaml file instead`)
392394
cmdObj.Flags().StringP("columns", "", "", `list of column names to show in the table output, all other columns are hidden`)
393-
cmdObj.Flags().StringP("color", "", "", `Colour columns in the table output. string can be one of: columns, errors, mix, none`)
395+
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)`)
394396
}
395397

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

563565
if len(colourOut) > 0 {
564566
// we use a switch to match --colour flag so I can expand in future
565-
switch strings.ToLower(colourOut) {
567+
colourEnv := strings.ToLower(colourOut)
568+
colourSet := strings.Split(colourEnv, ";")
569+
570+
switch strings.ToLower(colourSet[0]) {
566571
case "mix":
567572
f.outputAsColour = COLOUR_MIX
568573
case "columns":
@@ -571,9 +576,15 @@ func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
571576
f.outputAsColour = COLOUR_ERRORS
572577
case "none":
573578
f.outputAsColour = COLOUR_NONE
579+
case "custom":
580+
// f.outputAsColour = COLOUR_CUSTOM
581+
f.useTheseColours, f.outputAsColour, err = getColourSetFromString(colourSet[1:])
582+
if err != nil {
583+
return commonFlags{}, err
584+
}
574585

575586
default:
576-
return commonFlags{}, errors.New("unknown colour type only columns, errors, mix and none are supported")
587+
return commonFlags{}, errors.New("unknown colour type only columns, custom, errors, mix and none are supported")
577588
}
578589
}
579590

pkg/plugin/status.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func Status(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args [
9494

9595
table := Table{}
9696
table.ColourOutput = commonFlagList.outputAsColour
97+
table.CustomColours = commonFlagList.useTheseColours
9798

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

205206
rowOut[0].text = "true"
206-
rowOut[0].colour = [2]int{colourOk, colourModOk}
207+
rowOut[0].colour = colourOk
207208
rowOut[1].text = "true"
208-
rowOut[1].colour = [2]int{colourOk, colourModOk}
209+
rowOut[1].colour = colourOk
209210

210211
// loop through each row in podTotals and add the columns in each row
211212
for _, r := range rows {
212213
if r[0].text == "false" {
213214
// ready = false
214215
rowOut[0].text = "false" // ready
215-
rowOut[0].colour = [2]int{colourBad, colourModBad}
216+
rowOut[0].colour = colourBad
216217
}
217218
if r[1].text == "false" {
218219
rowOut[1].text = "false" // started
219-
rowOut[1].colour = [2]int{colourBad, colourModBad}
220+
rowOut[1].colour = colourBad
220221
}
221222
rowOut[2].number += r[2].number // restarts
222223

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

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

294295
if rawExitCode == 0 {
295-
colourcode = [2]int{colourOk, colourModOk}
296+
colourcode = colourOk
296297
} else {
297-
colourcode = [2]int{colourBad, colourModBad}
298+
colourcode = colourBad
298299
}
299300
}
300301

301302
if state.Running != nil {
302303
strState = "Running"
303304
startedAt = state.Running.StartedAt.Format(timestampFormat)
304305
startTime = state.Running.StartedAt.Time
305-
colourcode = [2]int{colourOk, colourModOk}
306+
colourcode = colourOk
306307
}
307308

308309
if container.Started != nil {

pkg/plugin/table.go

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type Table struct {
3939
placeHolder map[int][]Cell
4040
placeHolderID int
4141
ColourOutput int
42+
CustomColours [][2]int
4243
}
4344

4445
// SetHeader sets the header row to the specified array of strings
@@ -178,18 +179,41 @@ func (t *Table) Print() {
178179
var cellcolour [2]int
179180
var withColour bool
180181
var visibleColumns int
182+
181183
headLine := ""
182184
colourArray := make([][2]int, t.headCount)
183185

184-
if t.ColourOutput != COLOUR_NONE {
186+
switch t.ColourOutput {
187+
case COLOUR_NONE:
188+
withColour = false
189+
case COLOUR_CUSTOMMIX:
190+
fallthrough
191+
case COLOUR_CUSTOM:
192+
withColour = true
193+
maxColours := len(t.CustomColours)
194+
for i := 0; i < t.headCount; i++ {
195+
colourCode := int(math.Mod(float64(i), float64(maxColours)))
196+
colourArray[i][0] = t.CustomColours[colourCode][0] // colour
197+
colourArray[i][1] = t.CustomColours[colourCode][1] // colour modifier
198+
}
199+
default:
185200
withColour = true
186201

187-
maxColours := 7
202+
// generate the colour numbers for the default colour wheel, the colour set is repeated if there are more heades than colours
203+
maxColours := 14
188204
modFlip := 0
189205

190206
for i := 0; i < t.headCount; i++ {
191207
colourCode := int(math.Mod(float64(i), float64(maxColours)))
192-
colourArray[i][0] = colourCode + 30
208+
if colourCode < 6 {
209+
// we start at 31 and increase for 6 colours this allow us to excclude black and light gray
210+
colourArray[i][0] = colourCode + 31
211+
} else {
212+
// the second set covers the dark variations of the colours
213+
colourArray[i][0] = colourCode + 84
214+
}
215+
216+
// we flip the text to bold after every colour run
193217
colourArray[i][1] = modFlip
194218

195219
if colourCode >= maxColours-1 {
@@ -219,7 +243,7 @@ func (t *Table) Print() {
219243
word = "-"
220244
}
221245

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

260-
cellcolour := colourArray[visibleColumns]
284+
if withColour { // if colour wanted
285+
cellcolour = colourArray[visibleColumns] //set colour from wheel as default colour
286+
switch t.ColourOutput {
287+
case COLOUR_ERRORS:
288+
// override if we should only show error colours
289+
if cell.colour[0] != -1 {
290+
cellcolour = cell.colour
291+
} else {
292+
cellcolour[0] = -1
293+
}
294+
case COLOUR_CUSTOMMIX:
295+
fallthrough
296+
case COLOUR_MIX:
297+
// override if we should mix colours
298+
if cell.colour[0] > 0 {
299+
cellcolour = cell.colour
300+
}
301+
}
302+
}
303+
261304
visibleColumns += 1
262305

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

275318
// colour output has been set and the cell has data
276-
if withColour {
277-
if t.ColourOutput == COLOUR_MIX || t.ColourOutput == COLOUR_COLUMNS {
278-
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
279-
}
280-
281-
// we check for errors last so it can overwrite the column colours when we are using the mix colour set
282-
if cell.colour[0] > -1 && (t.ColourOutput == COLOUR_ERRORS || t.ColourOutput == COLOUR_MIX) {
283-
// error colour set uses red/yellow/green for ok/warning/problem
284-
if cell.colour[0] == 0 && t.ColourOutput == COLOUR_MIX {
285-
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
286-
} else {
287-
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cell.colour[1], cell.colour[0], origtxt, colourEnd)
288-
}
289-
}
319+
if withColour && cellcolour[0] != -1 {
320+
// so we add the colour codes and modifier
321+
celltxt = fmt.Sprintf("\033[%d;%dm%s%s", cellcolour[1], cellcolour[0], origtxt, colourEnd)
290322
}
291323

292324
line += fmt.Sprint(celltxt, pad)

0 commit comments

Comments
 (0)