From c28c6c6d6451d1aae9dd0599f3d515e87b3bd2e7 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Wed, 11 Mar 2026 15:08:08 +0100 Subject: [PATCH] command: Add vars to providers schema command --- .../command/arguments/providers_schema.go | 9 ++- .../arguments/providers_schema_test.go | 64 +++++++++++++++++-- internal/command/providers_schema.go | 24 ++++++- 3 files changed, 90 insertions(+), 7 deletions(-) diff --git a/internal/command/arguments/providers_schema.go b/internal/command/arguments/providers_schema.go index 15afa0acfc..6e7029fa1a 100644 --- a/internal/command/arguments/providers_schema.go +++ b/internal/command/arguments/providers_schema.go @@ -9,6 +9,9 @@ import "github.com/hashicorp/terraform/internal/tfdiags" // schema command. type ProvidersSchema struct { JSON bool + + // Vars are the variable-related flags (-var, -var-file). + Vars *Vars } // ParseProvidersSchema processes CLI arguments, returning a ProvidersSchema @@ -16,9 +19,11 @@ type ProvidersSchema struct { // still returned representing the best effort interpretation of the arguments. func ParseProvidersSchema(args []string) (*ProvidersSchema, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - providersSchema := &ProvidersSchema{} + providersSchema := &ProvidersSchema{ + Vars: &Vars{}, + } - cmdFlags := defaultFlagSet("providers schema") + cmdFlags := extendedFlagSet("providers schema", nil, nil, providersSchema.Vars) cmdFlags.BoolVar(&providersSchema.JSON, "json", false, "produce JSON output") if err := cmdFlags.Parse(args); err != nil { diff --git a/internal/command/arguments/providers_schema_test.go b/internal/command/arguments/providers_schema_test.go index 8f6df7220c..9cb3d3c2c2 100644 --- a/internal/command/arguments/providers_schema_test.go +++ b/internal/command/arguments/providers_schema_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/hashicorp/terraform/internal/tfdiags" ) @@ -19,17 +20,20 @@ func TestParseProvidersSchema_valid(t *testing.T) { []string{"-json"}, &ProvidersSchema{ JSON: true, + Vars: &Vars{}, }, }, } + cmpOpts := cmpopts.IgnoreUnexported(Vars{}) + for name, tc := range testCases { t.Run(name, func(t *testing.T) { got, diags := ParseProvidersSchema(tc.args) if len(diags) > 0 { t.Fatalf("unexpected diags: %v", diags) } - if diff := cmp.Diff(tc.want, got); diff != "" { + if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" { t.Fatalf("unexpected result\n%s", diff) } }) @@ -44,7 +48,9 @@ func TestParseProvidersSchema_invalid(t *testing.T) { }{ "missing json": { nil, - &ProvidersSchema{}, + &ProvidersSchema{ + Vars: &Vars{}, + }, tfdiags.Diagnostics{ tfdiags.Sourceless( tfdiags.Error, @@ -57,6 +63,7 @@ func TestParseProvidersSchema_invalid(t *testing.T) { []string{"-json", "extra"}, &ProvidersSchema{ JSON: true, + Vars: &Vars{}, }, tfdiags.Diagnostics{ tfdiags.Sourceless( @@ -68,7 +75,9 @@ func TestParseProvidersSchema_invalid(t *testing.T) { }, "unknown flag and missing json": { []string{"-wat"}, - &ProvidersSchema{}, + &ProvidersSchema{ + Vars: &Vars{}, + }, tfdiags.Diagnostics{ tfdiags.Sourceless( tfdiags.Error, @@ -84,13 +93,60 @@ func TestParseProvidersSchema_invalid(t *testing.T) { }, } + cmpOpts := cmpopts.IgnoreUnexported(Vars{}) + for name, tc := range testCases { t.Run(name, func(t *testing.T) { got, gotDiags := ParseProvidersSchema(tc.args) - if diff := cmp.Diff(tc.want, got); diff != "" { + if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" { t.Fatalf("unexpected result\n%s", diff) } tfdiags.AssertDiagnosticsMatch(t, gotDiags, tc.wantDiags) }) } } + +func TestParseProvidersSchema_vars(t *testing.T) { + testCases := map[string]struct { + args []string + want []FlagNameValue + }{ + "var": { + args: []string{"-json", "-var", "foo=bar"}, + want: []FlagNameValue{ + {Name: "-var", Value: "foo=bar"}, + }, + }, + "var-file": { + args: []string{"-json", "-var-file", "cool.tfvars"}, + want: []FlagNameValue{ + {Name: "-var-file", Value: "cool.tfvars"}, + }, + }, + "both": { + args: []string{ + "-json", + "-var", "foo=bar", + "-var-file", "cool.tfvars", + "-var", "boop=beep", + }, + want: []FlagNameValue{ + {Name: "-var", Value: "foo=bar"}, + {Name: "-var-file", Value: "cool.tfvars"}, + {Name: "-var", Value: "boop=beep"}, + }, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + got, diags := ParseProvidersSchema(tc.args) + if len(diags) > 0 { + t.Fatalf("unexpected diags: %v", diags) + } + if vars := got.Vars.All(); !cmp.Equal(vars, tc.want) { + t.Fatalf("unexpected vars: %#v", vars) + } + }) + } +} diff --git a/internal/command/providers_schema.go b/internal/command/providers_schema.go index 6af9b75f3a..33541806d5 100644 --- a/internal/command/providers_schema.go +++ b/internal/command/providers_schema.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform/internal/backend/backendrun" "github.com/hashicorp/terraform/internal/command/arguments" "github.com/hashicorp/terraform/internal/command/jsonprovider" + "github.com/hashicorp/terraform/internal/tfdiags" ) // ProvidersCommand is a Command implementation that prints out information @@ -27,7 +28,7 @@ func (c *ProvidersSchemaCommand) Synopsis() string { } func (c *ProvidersSchemaCommand) Run(args []string) int { - _, diags := arguments.ParseProvidersSchema(c.Meta.process(args)) + parsedArgs, diags := arguments.ParseProvidersSchema(c.Meta.process(args)) if diags.HasErrors() { c.showDiagnostics(diags) return 1 @@ -78,6 +79,16 @@ func (c *ProvidersSchemaCommand) Run(args []string) int { return 1 } + var varDiags tfdiags.Diagnostics + opReq.Variables, varDiags = parsedArgs.Vars.CollectValues(func(filename string, src []byte) { + opReq.ConfigLoader.Parser().ForceFileSource(filename, src) + }) + diags = diags.Append(varDiags) + if diags.HasErrors() { + c.showDiagnostics(diags) + return 1 + } + // Get the context lr, _, ctxDiags := local.LocalRun(opReq) diags = diags.Append(ctxDiags) @@ -108,4 +119,15 @@ Usage: terraform [global options] providers schema -json Prints out a json representation of the schemas for all providers used in the current configuration. + +Options: + + -var 'foo=bar' Set a value for one of the input variables in the root + module of the configuration. Use this option more than + once to set more than one variable. + + -var-file=filename Load variable values from the given file, in addition + to the default files terraform.tfvars and *.auto.tfvars. + Use this option more than once to include more than one + variables file. `