github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/command/validate.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "strings" 7 8 "github.com/muratcelep/terraform/not-internal/command/arguments" 9 "github.com/muratcelep/terraform/not-internal/command/views" 10 "github.com/muratcelep/terraform/not-internal/terraform" 11 "github.com/muratcelep/terraform/not-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 }