github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/command/fmt.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"flag"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"strings"
    10  
    11  	"github.com/hashicorp/hcl/hcl/fmtcmd"
    12  	"github.com/mitchellh/cli"
    13  )
    14  
    15  const (
    16  	stdinArg      = "-"
    17  	fileExtension = "tf"
    18  )
    19  
    20  // FmtCommand is a Command implementation that rewrites Terraform config
    21  // files to a canonical format and style.
    22  type FmtCommand struct {
    23  	Meta
    24  	opts  fmtcmd.Options
    25  	check bool
    26  	input io.Reader // STDIN if nil
    27  }
    28  
    29  func (c *FmtCommand) Run(args []string) int {
    30  	if c.input == nil {
    31  		c.input = os.Stdin
    32  	}
    33  
    34  	args, err := c.Meta.process(args, false)
    35  	if err != nil {
    36  		return 1
    37  	}
    38  
    39  	cmdFlags := flag.NewFlagSet("fmt", flag.ContinueOnError)
    40  	cmdFlags.BoolVar(&c.opts.List, "list", true, "list")
    41  	cmdFlags.BoolVar(&c.opts.Write, "write", true, "write")
    42  	cmdFlags.BoolVar(&c.opts.Diff, "diff", false, "diff")
    43  	cmdFlags.BoolVar(&c.check, "check", false, "check")
    44  	cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
    45  
    46  	if err := cmdFlags.Parse(args); err != nil {
    47  		return 1
    48  	}
    49  
    50  	args = cmdFlags.Args()
    51  	if len(args) > 1 {
    52  		c.Ui.Error("The fmt command expects at most one argument.")
    53  		cmdFlags.Usage()
    54  		return 1
    55  	}
    56  
    57  	var dirs []string
    58  	if len(args) == 0 {
    59  		dirs = []string{"."}
    60  	} else if args[0] == stdinArg {
    61  		c.opts.List = false
    62  		c.opts.Write = false
    63  	} else {
    64  		dirs = []string{args[0]}
    65  	}
    66  
    67  	var output io.Writer
    68  	list := c.opts.List // preserve the original value of -list
    69  	if c.check {
    70  		// set to true so we can use the list output to check
    71  		// if the input needs formatting
    72  		c.opts.List = true
    73  		c.opts.Write = false
    74  		output = &bytes.Buffer{}
    75  	} else {
    76  		output = &cli.UiWriter{Ui: c.Ui}
    77  	}
    78  
    79  	err = fmtcmd.Run(dirs, []string{fileExtension}, c.input, output, c.opts)
    80  	if err != nil {
    81  		c.Ui.Error(fmt.Sprintf("Error running fmt: %s", err))
    82  		return 2
    83  	}
    84  
    85  	if c.check {
    86  		buf := output.(*bytes.Buffer)
    87  		ok := buf.Len() == 0
    88  		if list {
    89  			io.Copy(&cli.UiWriter{Ui: c.Ui}, buf)
    90  		}
    91  		if ok {
    92  			return 0
    93  		} else {
    94  			return 3
    95  		}
    96  	}
    97  
    98  	return 0
    99  }
   100  
   101  func (c *FmtCommand) Help() string {
   102  	helpText := `
   103  Usage: terraform fmt [options] [DIR]
   104  
   105  	Rewrites all Terraform configuration files to a canonical format.
   106  
   107  	If DIR is not specified then the current working directory will be used.
   108  	If DIR is "-" then content will be read from STDIN.
   109  
   110  Options:
   111  
   112    -list=true       List files whose formatting differs (always false if using STDIN)
   113  
   114    -write=true      Write result to source file instead of STDOUT (always false if using STDIN or -check)
   115  
   116    -diff=false      Display diffs of formatting changes
   117  
   118    -check=false     Check if the input is formatted. Exit status will be 0 if all input is properly formatted and non-zero otherwise.
   119  
   120  `
   121  	return strings.TrimSpace(helpText)
   122  }
   123  
   124  func (c *FmtCommand) Synopsis() string {
   125  	return "Rewrites config files to canonical format"
   126  }