From 6c736bd3c41a5c32fb78615f57b3441d65800aef Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 12 Jul 2014 20:21:46 -0700 Subject: [PATCH] command: introduce Meta and "-no-color" option --- command/apply.go | 6 ++++++ command/command.go | 13 +++++++++++++ command/format_state.go | 5 +---- command/hook_ui.go | 5 +---- command/meta.go | 35 +++++++++++++++++++++++++++++++++++ command/meta_test.go | 35 +++++++++++++++++++++++++++++++++++ command/plan.go | 8 +++++++- command/refresh.go | 6 ++++++ command/show.go | 12 ++++++++++-- 9 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 command/meta.go create mode 100644 command/meta_test.go diff --git a/command/apply.go b/command/apply.go index 0b7d362439..b27483aede 100644 --- a/command/apply.go +++ b/command/apply.go @@ -13,6 +13,8 @@ import ( // ApplyCommand is a Command implementation that applies a Terraform // configuration and actually builds or changes infrastructure. type ApplyCommand struct { + Meta + ShutdownCh <-chan struct{} ContextOpts *terraform.ContextOpts Ui cli.Ui @@ -22,6 +24,8 @@ func (c *ApplyCommand) Run(args []string) int { var init bool var statePath, stateOutPath string + args = c.Meta.process(args) + cmdFlags := flag.NewFlagSet("apply", flag.ContinueOnError) cmdFlags.BoolVar(&init, "init", false, "init") cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path") @@ -139,6 +143,8 @@ Options: to prevent accidentally spinning up a new infrastructure. + -no-color If specified, output won't contain any color. + -state=path Path to read and save state (unless state-out is specified). Defaults to "terraform.tfstate". diff --git a/command/command.go b/command/command.go index b8f4aab9d2..cef5c29247 100644 --- a/command/command.go +++ b/command/command.go @@ -7,11 +7,24 @@ import ( "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" + "github.com/mitchellh/colorstring" ) // DefaultStateFilename is the default filename used for the state file. const DefaultStateFilename = "terraform.tfstate" +// Colorize returns our default coloring settings for strings. +func Colorize() *colorstring.Colorize { + return &colorstring.Colorize{ + Colors: colorstring.DefaultColors, + Reset: true, + } +} + +// ContextArg is a helper function that creates a context based on +// the arguments given. If the path is a plan file, it creates a context +// from that. Otherwise, it creates a context based on the state file +// (if given). func ContextArg( path string, statePath string, diff --git a/command/format_state.go b/command/format_state.go index 2b31a9b512..f63e1e3529 100644 --- a/command/format_state.go +++ b/command/format_state.go @@ -17,10 +17,7 @@ func FormatState(s *terraform.State, c *colorstring.Colorize) string { } if c == nil { - c = &colorstring.Colorize{ - Colors: colorstring.DefaultColors, - Reset: false, - } + c = Colorize() } buf := new(bytes.Buffer) diff --git a/command/hook_ui.go b/command/hook_ui.go index e642e55ed1..8f7c26e8c5 100644 --- a/command/hook_ui.go +++ b/command/hook_ui.go @@ -97,10 +97,7 @@ func (h *UiHook) PreRefresh( func (h *UiHook) init() { if h.Colorize == nil { - h.Colorize = &colorstring.Colorize{ - Colors: colorstring.DefaultColors, - Reset: true, - } + h.Colorize = Colorize() } // Wrap the ui so that it is safe for concurrency regardless of the diff --git a/command/meta.go b/command/meta.go new file mode 100644 index 0000000000..ee16f45c04 --- /dev/null +++ b/command/meta.go @@ -0,0 +1,35 @@ +package command + +import ( + "github.com/mitchellh/colorstring" +) + +// Meta are the meta-options that are available on all or most commands. +type Meta struct { + Color bool +} + +// Colorize returns the colorization structure for a command. +func (m *Meta) Colorize() *colorstring.Colorize { + return &colorstring.Colorize{ + Colors: colorstring.DefaultColors, + Disable: !m.Color, + Reset: true, + } +} + +// process will process the meta-parameters out of the arguments. This +// will potentially modify the args in-place. It will return the resulting +// slice. +func (m *Meta) process(args []string) []string { + m.Color = true + + for i, v := range args { + if v == "-no-color" { + m.Color = false + return append(args[:i], args[i+1:]...) + } + } + + return args +} diff --git a/command/meta_test.go b/command/meta_test.go new file mode 100644 index 0000000000..6a2f680f31 --- /dev/null +++ b/command/meta_test.go @@ -0,0 +1,35 @@ +package command + +import ( + "reflect" + "testing" +) + +func TestMetaColorize(t *testing.T) { + var m *Meta + var args, args2 []string + + // Test basic, no change + m = new(Meta) + args = []string{"foo", "bar"} + args2 = []string{"foo", "bar"} + args = m.process(args) + if !reflect.DeepEqual(args, args2) { + t.Fatalf("bad: %#v", args) + } + if m.Colorize().Disable { + t.Fatal("should not be disabled") + } + + // Test disable #1 + m = new(Meta) + args = []string{"foo", "-no-color", "bar"} + args2 = []string{"foo", "bar"} + args = m.process(args) + if !reflect.DeepEqual(args, args2) { + t.Fatalf("bad: %#v", args) + } + if !m.Colorize().Disable { + t.Fatal("should be disabled") + } +} diff --git a/command/plan.go b/command/plan.go index 88ae709099..b1a77f7d56 100644 --- a/command/plan.go +++ b/command/plan.go @@ -15,6 +15,8 @@ import ( // PlanCommand is a Command implementation that compares a Terraform // configuration to an actual infrastructure and shows the differences. type PlanCommand struct { + Meta + ContextOpts *terraform.ContextOpts Ui cli.Ui } @@ -23,6 +25,8 @@ func (c *PlanCommand) Run(args []string) int { var destroy, refresh bool var outPath, statePath string + args = c.Meta.process(args) + cmdFlags := flag.NewFlagSet("plan", flag.ContinueOnError) cmdFlags.BoolVar(&destroy, "destroy", false, "destroy") cmdFlags.BoolVar(&refresh, "refresh", true, "refresh") @@ -136,7 +140,7 @@ func (c *PlanCommand) Run(args []string) int { outPath)) } - c.Ui.Output(FormatPlan(plan, nil)) + c.Ui.Output(FormatPlan(plan, c.Colorize())) return 0 } @@ -157,6 +161,8 @@ Options: -destroy If set, a plan will be generated to destroy all resources managed by the given configuration and state. + -no-color If specified, output won't contain any color. + -out=path Write a plan file to the given path. This can be used as input to the "apply" command. diff --git a/command/refresh.go b/command/refresh.go index 137aadb1c4..56a63c5727 100644 --- a/command/refresh.go +++ b/command/refresh.go @@ -14,6 +14,8 @@ import ( // RefreshCommand is a cli.Command implementation that refreshes the state // file. type RefreshCommand struct { + Meta + ContextOpts *terraform.ContextOpts Ui cli.Ui } @@ -21,6 +23,8 @@ type RefreshCommand struct { func (c *RefreshCommand) Run(args []string) int { var statePath, stateOutPath string + args = c.Meta.process(args) + cmdFlags := flag.NewFlagSet("refresh", flag.ContinueOnError) cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path") cmdFlags.StringVar(&stateOutPath, "state-out", "", "path") @@ -121,6 +125,8 @@ Usage: terraform refresh [options] [dir] Options: + -no-color If specified, output won't contain any color. + -state=path Path to read and save state (unless state-out is specified). Defaults to "terraform.tfstate". diff --git a/command/show.go b/command/show.go index 0d5ebce592..c70e2b2ff4 100644 --- a/command/show.go +++ b/command/show.go @@ -13,11 +13,15 @@ import ( // ShowCommand is a Command implementation that reads and outputs the // contents of a Terraform plan or state file. type ShowCommand struct { + Meta + ContextOpts *terraform.ContextOpts Ui cli.Ui } func (c *ShowCommand) Run(args []string) int { + args = c.Meta.process(args) + cmdFlags := flag.NewFlagSet("show", flag.ContinueOnError) cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } if err := cmdFlags.Parse(args); err != nil { @@ -72,11 +76,11 @@ func (c *ShowCommand) Run(args []string) int { } if plan != nil { - c.Ui.Output(FormatPlan(plan, nil)) + c.Ui.Output(FormatPlan(plan, c.Colorize())) return 0 } - c.Ui.Output(FormatState(state, nil)) + c.Ui.Output(FormatState(state, c.Colorize())) return 0 } @@ -87,6 +91,10 @@ Usage: terraform show [options] path Reads and outputs a Terraform state or plan file in a human-readable form. +Options: + + -no-color If specified, output won't contain any color. + ` return strings.TrimSpace(helpText) }