Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support forcing color output on/off #799

Merged
merged 2 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Support forcing color output on/off
Closes #798

Introduce flag `--color` to control the colorization of diff output.

Add flag to all commands that can output colorized diff text:
- `diff`
- `apply`
- `prune`

`--color` has 3 allowed values:
- `auto` (default): colorize if stdout is a tty (current behavior)
- `always`: always colorize output
- `never`: never colorize output
  • Loading branch information
mattwilder committed Jan 6, 2023
commit ac49d149b22b594373031e8f36623acd6574490d
4 changes: 4 additions & 0 deletions cmd/tk/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func workflowFlags(fs *pflag.FlagSet) *workflowFlagVars {
return &v
}

func addDiffFlags(fs *pflag.FlagSet, opts *tanka.DiffBaseOpts) {
fs.StringVar(&opts.Color, "color", "auto", `controls color in diff output, must be "auto", "always", or "never"`)
}

func addApplyFlags(fs *pflag.FlagSet, opts *tanka.ApplyBaseOpts, autoApproveDeprecated *bool, autoApprove *string) {
fs.StringVar(&opts.DryRun, "dry-run", "", `--dry-run parameter to pass down to kubectl, must be "none", "server", or "client"`)
fs.BoolVar(&opts.Force, "force", false, "force applying (kubectl apply --force)")
Expand Down
43 changes: 43 additions & 0 deletions cmd/tk/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/fatih/color"
"github.com/go-clix/cli"
"github.com/posener/complete"

Expand All @@ -20,6 +21,24 @@ const (
ExitStatusDiff = 16
)

var (
colorValues = cli.PredictSet("auto", "always", "never")
)

func setForceColor(opts *tanka.DiffBaseOpts) error {
switch opts.Color {
case "":
case "auto":
case "always":
color.NoColor = false
case "never":
color.NoColor = true
default:
return fmt.Errorf(`--color must be either: "auto", "always", or "never"`)
}
return nil
}

func validateDryRun(dryRunStr string) error {
switch dryRunStr {
case "", "none", "client", "server":
Expand Down Expand Up @@ -56,6 +75,7 @@ func applyCmd() *cli.Command {
Short: "apply the configuration to the cluster",
Args: workflowArgs,
Predictors: complete.Flags{
"color": colorValues,
"diff-strategy": cli.PredictSet("native", "subset", "validate", "server", "none"),
"apply-strategy": cli.PredictSet("client", "server"),
},
Expand All @@ -71,6 +91,7 @@ func applyCmd() *cli.Command {
autoApproveString string
)
addApplyFlags(cmd.Flags(), &opts.ApplyBaseOpts, &autoApproveDeprecated, &autoApproveString)
addDiffFlags(cmd.Flags(), &opts.DiffBaseOpts)
vars := workflowFlags(cmd.Flags())
getJsonnetOpts := jsonnetFlags(cmd.Flags())

Expand All @@ -82,6 +103,9 @@ func applyCmd() *cli.Command {
if opts.AutoApprove, err = validateAutoApprove(autoApproveDeprecated, autoApproveString); err != nil {
return err
}
if err := setForceColor(&opts.DiffBaseOpts); err != nil {
return err
}

filters, err := process.StrExps(vars.targets...)
if err != nil {
Expand All @@ -101,6 +125,9 @@ func pruneCmd() *cli.Command {
Use: "prune <path>",
Short: "delete resources removed from Jsonnet",
Args: workflowArgs,
Predictors: complete.Flags{
"color": colorValues,
},
}

var opts tanka.PruneOpts
Expand All @@ -110,6 +137,7 @@ func pruneCmd() *cli.Command {
autoApproveString string
)
addApplyFlags(cmd.Flags(), &opts.ApplyBaseOpts, &autoApproveDeprecated, &autoApproveString)
addDiffFlags(cmd.Flags(), &opts.DiffBaseOpts)
getJsonnetOpts := jsonnetFlags(cmd.Flags())

cmd.Run = func(cmd *cli.Command, args []string) error {
Expand All @@ -120,6 +148,9 @@ func pruneCmd() *cli.Command {
if opts.AutoApprove, err = validateAutoApprove(autoApproveDeprecated, autoApproveString); err != nil {
return err
}
if err := setForceColor(&opts.DiffBaseOpts); err != nil {
return err
}

opts.JsonnetOpts = getJsonnetOpts()

Expand All @@ -134,6 +165,9 @@ func deleteCmd() *cli.Command {
Use: "delete <path>",
Short: "delete the environment from cluster",
Args: workflowArgs,
Predictors: complete.Flags{
"color": colorValues,
},
}

var opts tanka.DeleteOpts
Expand All @@ -143,6 +177,7 @@ func deleteCmd() *cli.Command {
autoApproveString string
)
addApplyFlags(cmd.Flags(), &opts.ApplyBaseOpts, &autoApproveDeprecated, &autoApproveString)
addDiffFlags(cmd.Flags(), &opts.DiffBaseOpts)
vars := workflowFlags(cmd.Flags())
getJsonnetOpts := jsonnetFlags(cmd.Flags())

Expand All @@ -154,6 +189,9 @@ func deleteCmd() *cli.Command {
if opts.AutoApprove, err = validateAutoApprove(autoApproveDeprecated, autoApproveString); err != nil {
return err
}
if err := setForceColor(&opts.DiffBaseOpts); err != nil {
return err
}

filters, err := process.StrExps(vars.targets...)
if err != nil {
Expand All @@ -174,11 +212,13 @@ func diffCmd() *cli.Command {
Short: "differences between the configuration and the cluster",
Args: workflowArgs,
Predictors: complete.Flags{
"color": colorValues,
"diff-strategy": cli.PredictSet("native", "subset", "validate", "server"),
},
}

var opts tanka.DiffOpts
addDiffFlags(cmd.Flags(), &opts.DiffBaseOpts)
cmd.Flags().StringVar(&opts.Strategy, "diff-strategy", "", "force the diff-strategy to use. Automatically chosen if not set.")
cmd.Flags().BoolVarP(&opts.Summarize, "summarize", "s", false, "print summary of the differences, not the actual contents")
cmd.Flags().BoolVarP(&opts.WithPrune, "with-prune", "p", false, "include objects deleted from the configuration in the differences")
Expand All @@ -188,6 +228,9 @@ func diffCmd() *cli.Command {
getJsonnetOpts := jsonnetFlags(cmd.Flags())

cmd.Run = func(cmd *cli.Command, args []string) error {
if err := setForceColor(&opts.DiffBaseOpts); err != nil {
return err
}
filters, err := process.StrExps(vars.targets...)
if err != nil {
return err
Expand Down
9 changes: 9 additions & 0 deletions pkg/tanka/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (

type ApplyBaseOpts struct {
Opts
DiffBaseOpts

// AutoApprove skips the interactive approval
AutoApprove AutoApproveSetting
Expand All @@ -38,6 +39,13 @@ type ApplyBaseOpts struct {
Force bool
}

type DiffBaseOpts struct {
// ForceColor enables color output even if stdout is not a terminal
ForceColor bool
// Color controls color output
Color string
}

// ApplyOpts specify additional properties for the Apply action
type ApplyOpts struct {
ApplyBaseOpts
Expand Down Expand Up @@ -152,6 +160,7 @@ func confirmPrompt(action, namespace string, info client.Info) error {

// DiffOpts specify additional properties for the Diff action
type DiffOpts struct {
DiffBaseOpts
Opts

// Strategy must be one of "native", "validate", "subset" or "server"
Expand Down