diff --git a/command/fmt.go b/command/fmt.go index 9c9e6c22f..f0a7bfa79 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 b9d69fe66..de117bb2c 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 51802784b..9f33e98e3 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: