command: introduce Meta and "-no-color" option

This commit is contained in:
Mitchell Hashimoto 2014-07-12 20:21:46 -07:00
parent dbc1c63d79
commit 6c736bd3c4
9 changed files with 114 additions and 11 deletions

View File

@ -13,6 +13,8 @@ import (
// ApplyCommand is a Command implementation that applies a Terraform // ApplyCommand is a Command implementation that applies a Terraform
// configuration and actually builds or changes infrastructure. // configuration and actually builds or changes infrastructure.
type ApplyCommand struct { type ApplyCommand struct {
Meta
ShutdownCh <-chan struct{} ShutdownCh <-chan struct{}
ContextOpts *terraform.ContextOpts ContextOpts *terraform.ContextOpts
Ui cli.Ui Ui cli.Ui
@ -22,6 +24,8 @@ func (c *ApplyCommand) Run(args []string) int {
var init bool var init bool
var statePath, stateOutPath string var statePath, stateOutPath string
args = c.Meta.process(args)
cmdFlags := flag.NewFlagSet("apply", flag.ContinueOnError) cmdFlags := flag.NewFlagSet("apply", flag.ContinueOnError)
cmdFlags.BoolVar(&init, "init", false, "init") cmdFlags.BoolVar(&init, "init", false, "init")
cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path") cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path")
@ -139,6 +143,8 @@ Options:
to prevent accidentally spinning up a new to prevent accidentally spinning up a new
infrastructure. infrastructure.
-no-color If specified, output won't contain any color.
-state=path Path to read and save state (unless state-out -state=path Path to read and save state (unless state-out
is specified). Defaults to "terraform.tfstate". is specified). Defaults to "terraform.tfstate".

View File

@ -7,11 +7,24 @@ import (
"github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/mitchellh/colorstring"
) )
// DefaultStateFilename is the default filename used for the state file. // DefaultStateFilename is the default filename used for the state file.
const DefaultStateFilename = "terraform.tfstate" 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( func ContextArg(
path string, path string,
statePath string, statePath string,

View File

@ -17,10 +17,7 @@ func FormatState(s *terraform.State, c *colorstring.Colorize) string {
} }
if c == nil { if c == nil {
c = &colorstring.Colorize{ c = Colorize()
Colors: colorstring.DefaultColors,
Reset: false,
}
} }
buf := new(bytes.Buffer) buf := new(bytes.Buffer)

View File

@ -97,10 +97,7 @@ func (h *UiHook) PreRefresh(
func (h *UiHook) init() { func (h *UiHook) init() {
if h.Colorize == nil { if h.Colorize == nil {
h.Colorize = &colorstring.Colorize{ h.Colorize = Colorize()
Colors: colorstring.DefaultColors,
Reset: true,
}
} }
// Wrap the ui so that it is safe for concurrency regardless of the // Wrap the ui so that it is safe for concurrency regardless of the

35
command/meta.go Normal file
View File

@ -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
}

35
command/meta_test.go Normal file
View File

@ -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")
}
}

View File

@ -15,6 +15,8 @@ import (
// PlanCommand is a Command implementation that compares a Terraform // PlanCommand is a Command implementation that compares a Terraform
// configuration to an actual infrastructure and shows the differences. // configuration to an actual infrastructure and shows the differences.
type PlanCommand struct { type PlanCommand struct {
Meta
ContextOpts *terraform.ContextOpts ContextOpts *terraform.ContextOpts
Ui cli.Ui Ui cli.Ui
} }
@ -23,6 +25,8 @@ func (c *PlanCommand) Run(args []string) int {
var destroy, refresh bool var destroy, refresh bool
var outPath, statePath string var outPath, statePath string
args = c.Meta.process(args)
cmdFlags := flag.NewFlagSet("plan", flag.ContinueOnError) cmdFlags := flag.NewFlagSet("plan", flag.ContinueOnError)
cmdFlags.BoolVar(&destroy, "destroy", false, "destroy") cmdFlags.BoolVar(&destroy, "destroy", false, "destroy")
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh") cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
@ -136,7 +140,7 @@ func (c *PlanCommand) Run(args []string) int {
outPath)) outPath))
} }
c.Ui.Output(FormatPlan(plan, nil)) c.Ui.Output(FormatPlan(plan, c.Colorize()))
return 0 return 0
} }
@ -157,6 +161,8 @@ Options:
-destroy If set, a plan will be generated to destroy all resources -destroy If set, a plan will be generated to destroy all resources
managed by the given configuration and state. 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 -out=path Write a plan file to the given path. This can be used as
input to the "apply" command. input to the "apply" command.

View File

@ -14,6 +14,8 @@ import (
// RefreshCommand is a cli.Command implementation that refreshes the state // RefreshCommand is a cli.Command implementation that refreshes the state
// file. // file.
type RefreshCommand struct { type RefreshCommand struct {
Meta
ContextOpts *terraform.ContextOpts ContextOpts *terraform.ContextOpts
Ui cli.Ui Ui cli.Ui
} }
@ -21,6 +23,8 @@ type RefreshCommand struct {
func (c *RefreshCommand) Run(args []string) int { func (c *RefreshCommand) Run(args []string) int {
var statePath, stateOutPath string var statePath, stateOutPath string
args = c.Meta.process(args)
cmdFlags := flag.NewFlagSet("refresh", flag.ContinueOnError) cmdFlags := flag.NewFlagSet("refresh", flag.ContinueOnError)
cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path") cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path")
cmdFlags.StringVar(&stateOutPath, "state-out", "", "path") cmdFlags.StringVar(&stateOutPath, "state-out", "", "path")
@ -121,6 +125,8 @@ Usage: terraform refresh [options] [dir]
Options: Options:
-no-color If specified, output won't contain any color.
-state=path Path to read and save state (unless state-out -state=path Path to read and save state (unless state-out
is specified). Defaults to "terraform.tfstate". is specified). Defaults to "terraform.tfstate".

View File

@ -13,11 +13,15 @@ import (
// ShowCommand is a Command implementation that reads and outputs the // ShowCommand is a Command implementation that reads and outputs the
// contents of a Terraform plan or state file. // contents of a Terraform plan or state file.
type ShowCommand struct { type ShowCommand struct {
Meta
ContextOpts *terraform.ContextOpts ContextOpts *terraform.ContextOpts
Ui cli.Ui Ui cli.Ui
} }
func (c *ShowCommand) Run(args []string) int { func (c *ShowCommand) Run(args []string) int {
args = c.Meta.process(args)
cmdFlags := flag.NewFlagSet("show", flag.ContinueOnError) cmdFlags := flag.NewFlagSet("show", flag.ContinueOnError)
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
if err := cmdFlags.Parse(args); err != nil { if err := cmdFlags.Parse(args); err != nil {
@ -72,11 +76,11 @@ func (c *ShowCommand) Run(args []string) int {
} }
if plan != nil { if plan != nil {
c.Ui.Output(FormatPlan(plan, nil)) c.Ui.Output(FormatPlan(plan, c.Colorize()))
return 0 return 0
} }
c.Ui.Output(FormatState(state, nil)) c.Ui.Output(FormatState(state, c.Colorize()))
return 0 return 0
} }
@ -87,6 +91,10 @@ Usage: terraform show [options] path
Reads and outputs a Terraform state or plan file in a human-readable Reads and outputs a Terraform state or plan file in a human-readable
form. form.
Options:
-no-color If specified, output won't contain any color.
` `
return strings.TrimSpace(helpText) return strings.TrimSpace(helpText)
} }