From e9128769b5424f471af7378660baba8c7fc90693 Mon Sep 17 00:00:00 2001 From: Dan Carley Date: Tue, 2 Feb 2016 22:10:22 +0000 Subject: [PATCH] command/fmt: Accept input from STDIN So that you can do automatic formatting from an editor. You probably want to disable the `-write` and `-list` options so that you just get the re-formatted content, e.g. cat main.tf | terraform fmt -write=false -list=false - I've added a non-exported field called `input` so that we can override this for the tests. If not specified, like in `commands.go`, then it will default to `os.Stdin` which works on the command line. --- command/fmt.go | 21 ++++++++++---- command/fmt_test.go | 29 +++++++++++++++++++ .../source/docs/commands/fmt.html.markdown | 3 +- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/command/fmt.go b/command/fmt.go index 9c9e6c22f5..f0a7bfa797 100644 --- a/command/fmt.go +++ b/command/fmt.go @@ -3,6 +3,8 @@ package command import ( "flag" "fmt" + "io" + "os" "strings" "github.com/hashicorp/hcl/hcl/fmtcmd" @@ -10,6 +12,7 @@ import ( ) const ( + stdinArg = "-" fileExtension = "tf" ) @@ -17,10 +20,15 @@ const ( // files to a canonical format and style. type FmtCommand struct { Meta - opts fmtcmd.Options + opts fmtcmd.Options + input io.Reader // STDIN if nil } func (c *FmtCommand) Run(args []string) int { + if c.input == nil { + c.input = os.Stdin + } + args = c.Meta.process(args, false) cmdFlags := flag.NewFlagSet("fmt", flag.ContinueOnError) @@ -40,15 +48,15 @@ func (c *FmtCommand) Run(args []string) int { return 1 } - var dir string + var dirs []string if len(args) == 0 { - dir = "." - } else { - dir = args[0] + dirs = []string{"."} + } else if args[0] != stdinArg { + dirs = []string{args[0]} } output := &cli.UiWriter{Ui: c.Ui} - err := fmtcmd.Run([]string{dir}, []string{fileExtension}, nil, output, c.opts) + err := fmtcmd.Run(dirs, []string{fileExtension}, c.input, output, c.opts) if err != nil { c.Ui.Error(fmt.Sprintf("Error running fmt: %s", err)) return 2 @@ -64,6 +72,7 @@ Usage: terraform fmt [options] [DIR] Rewrites all Terraform configuration files to a canonical format. If DIR is not specified then the current working directory will be used. + If DIR is "-" then content will be read from STDIN. Options: diff --git a/command/fmt_test.go b/command/fmt_test.go index b9d69fe660..de117bb2ce 100644 --- a/command/fmt_test.go +++ b/command/fmt_test.go @@ -1,6 +1,7 @@ package command import ( + "bytes" "fmt" "io/ioutil" "os" @@ -123,6 +124,34 @@ func TestFmt_directoryArg(t *testing.T) { } } +func TestFmt_stdinArg(t *testing.T) { + input := new(bytes.Buffer) + input.Write(fmtFixture.input) + + ui := new(cli.MockUi) + c := &FmtCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + input: input, + } + + args := []string{ + "-write=false", + "-list=false", + "-", + } + if code := c.Run(args); code != 0 { + t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) + } + + expected := fmtFixture.golden + if actual := ui.OutputWriter.Bytes(); !bytes.Equal(actual, expected) { + t.Fatalf("got: %q\nexpected: %q", actual, expected) + } +} + var fmtFixture = struct { filename string input, golden []byte diff --git a/website/source/docs/commands/fmt.html.markdown b/website/source/docs/commands/fmt.html.markdown index 51802784b2..9f33e98e38 100644 --- a/website/source/docs/commands/fmt.html.markdown +++ b/website/source/docs/commands/fmt.html.markdown @@ -17,7 +17,8 @@ Usage: `terraform fmt [options] [DIR]` By default, `fmt` scans the current directory for configuration files. If the `dir` argument is provided then it will scan that given directory -instead. +instead. If `dir` is a single dash (`-`) then `fmt` will read from standard +input (STDIN). The command-line flags are all optional. The list of available flags are: