github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/command/validate.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/internal/command/arguments"
     9  	"github.com/hashicorp/terraform/internal/command/views"
    10  	"github.com/hashicorp/terraform/internal/terraform"
    11  	"github.com/hashicorp/terraform/internal/tfdiags"
    12  )
    13  
    14  // ValidateCommand is a Command implementation that validates the terraform files
    15  type ValidateCommand struct {
    16  	Meta
    17  }
    18  
    19  func (c *ValidateCommand) Run(rawArgs []string) int {
    20  	// Parse and apply global view arguments
    21  	common, rawArgs := arguments.ParseView(rawArgs)
    22  	c.View.Configure(common)
    23  
    24  	// Parse and validate flags
    25  	args, diags := arguments.ParseValidate(rawArgs)
    26  	if diags.HasErrors() {
    27  		c.View.Diagnostics(diags)
    28  		c.View.HelpPrompt("validate")
    29  		return 1
    30  	}
    31  
    32  	view := views.NewValidate(args.ViewType, c.View)
    33  
    34  	// After this point, we must only produce JSON output if JSON mode is
    35  	// enabled, so all errors should be accumulated into diags and we'll
    36  	// print out a suitable result at the end, depending on the format
    37  	// selection. All returns from this point on must be tail-calls into
    38  	// view.Results in order to produce the expected output.
    39  
    40  	dir, err := filepath.Abs(args.Path)
    41  	if err != nil {
    42  		diags = diags.Append(fmt.Errorf("unable to locate module: %s", err))
    43  		return view.Results(diags)
    44  	}
    45  
    46  	// Check for user-supplied plugin path
    47  	if c.pluginPath, err = c.loadPluginPath(); err != nil {
    48  		diags = diags.Append(fmt.Errorf("error loading plugin path: %s", err))
    49  		return view.Results(diags)
    50  	}
    51  
    52  	validateDiags := c.validate(dir)
    53  	diags = diags.Append(validateDiags)
    54  
    55  	// Validating with dev overrides in effect means that the result might
    56  	// not be valid for a stable release, so we'll warn about that in case
    57  	// the user is trying to use "terraform validate" as a sort of pre-flight
    58  	// check before submitting a change.
    59  	diags = diags.Append(c.providerDevOverrideRuntimeWarnings())
    60  
    61  	return view.Results(diags)
    62  }
    63  
    64  func (c *ValidateCommand) validate(dir string) tfdiags.Diagnostics {
    65  	var diags tfdiags.Diagnostics
    66  
    67  	cfg, cfgDiags := c.loadConfig(dir)
    68  	diags = diags.Append(cfgDiags)
    69  
    70  	if diags.HasErrors() {
    71  		return diags
    72  	}
    73  
    74  	opts, err := c.contextOpts()
    75  	if err != nil {
    76  		diags = diags.Append(err)
    77  		return diags
    78  	}
    79  
    80  	tfCtx, ctxDiags := terraform.NewContext(opts)
    81  	diags = diags.Append(ctxDiags)
    82  	if ctxDiags.HasErrors() {
    83  		return diags
    84  	}
    85  
    86  	validateDiags := tfCtx.Validate(cfg)
    87  	diags = diags.Append(validateDiags)
    88  	return diags
    89  }
    90  
    91  func (c *ValidateCommand) Synopsis() string {
    92  	return "Check whether the configuration is valid"
    93  }
    94  
    95  func (c *ValidateCommand) Help() string {
    96  	helpText := `
    97  Usage: terraform [global options] validate [options]
    98  
    99    Validate the configuration files in a directory, referring only to the
   100    configuration and not accessing any remote services such as remote state,
   101    provider APIs, etc.
   102  
   103    Validate runs checks that verify whether a configuration is syntactically
   104    valid and internally consistent, regardless of any provided variables or
   105    existing state. It is thus primarily useful for general verification of
   106    reusable modules, including correctness of attribute names and value types.
   107  
   108    It is safe to run this command automatically, for example as a post-save
   109    check in a text editor or as a test step for a re-usable module in a CI
   110    system.
   111  
   112    Validation requires an initialized working directory with any referenced
   113    plugins and modules installed. To initialize a working directory for
   114    validation without accessing any configured remote backend, use:
   115        terraform init -backend=false
   116  
   117    To verify configuration in the context of a particular run (a particular
   118    target workspace, input variable values, etc), use the 'terraform plan'
   119    command instead, which includes an implied validation check.
   120  
   121  Options:
   122  
   123    -json        Produce output in a machine-readable JSON format, suitable for
   124                 use in text editor integrations and other automated systems.
   125                 Always disables color.
   126  
   127    -no-color    If specified, output won't contain any color.
   128  `
   129  	return strings.TrimSpace(helpText)
   130  }