How it works
For the curious of how kubecolor behaves, here’s a rundown.
Simply put:
-
Parse the arguments to understand which subcommand it is. For example:
Terminal window kubecolor --kubecolor-theme="light" get --pager="less -RF" pods -o wide --watch -
Parse subcommand and kubecolor-specific flags:
- “subcommand is
get” - “flag
--outputis set towide” - “flag
--watchis set totrue” - “set kubecolor theme to
light” - “set pager to
less -RF”
- “subcommand is
-
Prepare
kubectlsubcommand, filtering out kubecolor-specific flags, turning the command into:Terminal window kubectl get pods -o wide --watch -
If it’s a subcommand that doesn’t support colors (e.g
kubectl execor kubectl plugins), then just give provide thekubectlcommand with the raw stdin, stdout, and stderr pipes, and then just let it execute. -
If paging is enabled and it’s a subcommand that supports paging, then start up the pager process (e.g
less -RF) and pipe kubecolor’s output through it. Effectively doing this:Terminal window kubectl get pods -o wide --watch | kubecolor-parsing-logic | less -RF -
Select the correct parser and printer for the associated subcommand. For example
kubectl get-> “table printer” andkubectl --help-> “help printer”.Side note: Most of kubecolor’s code base is in the parsers. Parsing arbitrary
kubectl describeoutput andkubectl gettables (with potential empty cells) is non-trivial. -
Let the code fly, continuously parsing and printing as the
kubectlprocess is outputting data. -
Upon exit, reuse
kubectl’s exit code.
Kubecolor does not talk to the Kubernetes API at all.
The only IO it performs is executing the kubectl (and potential pager)
processes and parsing the results.
If we were to fork kubectl’s code base, then we could probably add a lot of colorization with deep levels of domain knowledge about the output. But that is an unreasonable amount of work.
Instead, with this approach, kubecolor is arguably way more flexible,
and it also allows us to support the OpenShift oc command at the same time.
Dynamic tty support
Section titled “Dynamic tty support”When the kubecolor output tty is not standard output, it automatically disables the colorization. For example:
# Prints with color codeskubecolor get pods
# Automatically disables color codes for these two:kubecolor get pods > result.txtkubecolor get pods | grep Running
# Force kubecolor to print color codes anywayskubecolor get pods --force-colors > result.txtDynamic color support
Section titled “Dynamic color support”Kubecolor will infer which colors your terminal supports.
For context, practically all terminals supports the basic “3-bit” or “4-bit” ANSI color set
which includes 8 or 16 different colors (respectively),
while most support the “8-bit” ANSI color set
which, includes 256 different colors.
More advanced and modern terminal emulators also support the “24-bit” color set (aka true color),
which includes the famous 16 777 216 number of colors,
and are most commonly referred to by their RGB (e.g rgb(90, 12, 135)) or HEX (e.g #5a8487) representations.
When using kubecolor you can freely configure it to use RGB values in your theme, and depending on your terminal’s color support, it will convert the color to the nearest 8-bit or 4-bit color.
The color support can be overridden via the --force-colors flag and KUBECOLOR_FORCE_COLORS environment variable,
and it support multiple values: auto, basic, 256, truecolor, and none
# As an example, let's set the header color to a 24-bit/truecolor value:export KUBECOLOR_THEME_TABLE_HEADER='#5a8487'
# Automatically detect color support,# but fallback to basic/4-bit colors if detection failskubecolor get pods --force-colors=auto
# Force colors to basic/4-bit colors,# resulting in header color code `␛[37m`kubecolor get pods --force-colors=basic
# Force colors to 256/8-bit colors,# resulting in header color code `␛[38;5;66m`kubecolor get pods --force-colors=256
# Force colors to truecolor/24-bit colors,# resulting in header color code `␛[38;2;90;132;135m`kubecolor get pods --force-colors=truecolor
# Forcing no colors, i.e. disabling colorskubecolor get pods --force-colors=noneWhen not using the --force-colors flag or KUBECOLOR_FORCE_COLORS env var,
the behavior then depends on if the output is a terminal or not:
# Same behavior as --force-colors=autokubecolor get pods
# Same behavior as --force-colors=nonekubecolor get pods > result.txtkubecolor get pods | grep RunningHow kubecolor figures this out is through some standards using the
COLORTERM environment variable and TERMINFO files,
where we rely on the github.com/gookit/color package’s detection logic.