mirror of
https://github.com/hashicorp/terraform.git
synced 2026-05-28 04:03:27 -04:00
command: Add vars to get command (and refactor it)
This commit is contained in:
parent
cdbd4f17f2
commit
0fa9e5b4da
3 changed files with 248 additions and 13 deletions
54
internal/command/arguments/get.go
Normal file
54
internal/command/arguments/get.go
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright IBM Corp. 2014, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package arguments
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
// Get represents the command-line arguments for the get command.
|
||||
type Get struct {
|
||||
// Vars are the variable-related flags (-var, -var-file).
|
||||
Vars *Vars
|
||||
|
||||
// Update, if true, checks already-downloaded modules for available
|
||||
// updates and installs the newest versions available.
|
||||
Update bool
|
||||
|
||||
// TestDirectory is the Terraform test directory.
|
||||
TestDirectory string
|
||||
}
|
||||
|
||||
// ParseGet processes CLI arguments, returning a Get value and diagnostics.
|
||||
// If errors are encountered, a Get value is still returned representing
|
||||
// the best effort interpretation of the arguments.
|
||||
func ParseGet(args []string) (*Get, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
get := &Get{
|
||||
Vars: &Vars{},
|
||||
}
|
||||
|
||||
cmdFlags := extendedFlagSet("get", nil, nil, get.Vars)
|
||||
cmdFlags.BoolVar(&get.Update, "update", false, "update")
|
||||
cmdFlags.StringVar(&get.TestDirectory, "test-directory", "tests", "test-directory")
|
||||
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Failed to parse command-line flags",
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
||||
args = cmdFlags.Args()
|
||||
if len(args) > 0 {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Too many command line arguments",
|
||||
"Expected no positional arguments. Did you mean to use -chdir?",
|
||||
))
|
||||
}
|
||||
|
||||
return get, diags
|
||||
}
|
||||
161
internal/command/arguments/get_test.go
Normal file
161
internal/command/arguments/get_test.go
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright IBM Corp. 2014, 2026
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package arguments
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
func TestParseGet_valid(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
args []string
|
||||
want *Get
|
||||
}{
|
||||
"defaults": {
|
||||
nil,
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
TestDirectory: "tests",
|
||||
},
|
||||
},
|
||||
"update": {
|
||||
[]string{"-update"},
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
Update: true,
|
||||
TestDirectory: "tests",
|
||||
},
|
||||
},
|
||||
"test-directory": {
|
||||
[]string{"-test-directory", "custom-tests"},
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
TestDirectory: "custom-tests",
|
||||
},
|
||||
},
|
||||
"all options": {
|
||||
[]string{
|
||||
"-update",
|
||||
"-test-directory", "custom-tests",
|
||||
},
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
Update: true,
|
||||
TestDirectory: "custom-tests",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cmpOpts := cmp.Options{cmpopts.IgnoreUnexported(Vars{})}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
got, diags := ParseGet(tc.args)
|
||||
if len(diags) > 0 {
|
||||
t.Fatalf("unexpected diags: %v", diags)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" {
|
||||
t.Fatalf("unexpected result\n got: %#v\nwant: %#v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseGet_vars(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
args []string
|
||||
want []FlagNameValue
|
||||
}{
|
||||
"var": {
|
||||
args: []string{"-var", "foo=bar"},
|
||||
want: []FlagNameValue{
|
||||
{Name: "-var", Value: "foo=bar"},
|
||||
},
|
||||
},
|
||||
"var-file": {
|
||||
args: []string{"-var-file", "cool.tfvars"},
|
||||
want: []FlagNameValue{
|
||||
{Name: "-var-file", Value: "cool.tfvars"},
|
||||
},
|
||||
},
|
||||
"both": {
|
||||
args: []string{
|
||||
"-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 := ParseGet(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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseGet_invalid(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
args []string
|
||||
want *Get
|
||||
wantDiags tfdiags.Diagnostics
|
||||
}{
|
||||
"unknown flag": {
|
||||
[]string{"-boop"},
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
TestDirectory: "tests",
|
||||
},
|
||||
tfdiags.Diagnostics{
|
||||
tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Failed to parse command-line flags",
|
||||
"flag provided but not defined: -boop",
|
||||
),
|
||||
},
|
||||
},
|
||||
"too many arguments": {
|
||||
[]string{"foo", "bar"},
|
||||
&Get{
|
||||
Vars: &Vars{},
|
||||
TestDirectory: "tests",
|
||||
},
|
||||
tfdiags.Diagnostics{
|
||||
tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Too many command line arguments",
|
||||
"Expected no positional arguments. Did you mean to use -chdir?",
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cmpOpts := cmp.Options{cmpopts.IgnoreUnexported(Vars{})}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
got, gotDiags := ParseGet(tc.args)
|
||||
if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" {
|
||||
t.Fatalf("unexpected result\n got: %#v\nwant: %#v", got, tc.want)
|
||||
}
|
||||
tfdiags.AssertDiagnosticsMatch(t, gotDiags, tc.wantDiags)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,9 @@ package command
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/arguments"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
|
|
@ -18,16 +18,26 @@ type GetCommand struct {
|
|||
}
|
||||
|
||||
func (c *GetCommand) Run(args []string) int {
|
||||
var update bool
|
||||
var testsDirectory string
|
||||
parsedArgs, diags := arguments.ParseGet(c.Meta.process(args))
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
args = c.Meta.process(args)
|
||||
cmdFlags := c.Meta.defaultFlagSet("get")
|
||||
cmdFlags.BoolVar(&update, "update", false, "update")
|
||||
cmdFlags.StringVar(&testsDirectory, "test-directory", "tests", "test-directory")
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
|
||||
loader, err := c.initConfigLoader()
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
var varDiags tfdiags.Diagnostics
|
||||
c.VariableValues, varDiags = parsedArgs.Vars.CollectValues(func(filename string, src []byte) {
|
||||
loader.Parser().ForceFileSource(filename, src)
|
||||
})
|
||||
diags = diags.Append(varDiags)
|
||||
if diags.HasErrors() {
|
||||
c.showDiagnostics(diags)
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +45,7 @@ func (c *GetCommand) Run(args []string) int {
|
|||
ctx, done := c.InterruptibleContext(c.CommandContext())
|
||||
defer done()
|
||||
|
||||
path, err := ModulePath(cmdFlags.Args())
|
||||
path, err := ModulePath(nil)
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
|
@ -43,7 +53,8 @@ func (c *GetCommand) Run(args []string) int {
|
|||
|
||||
path = c.normalizePath(path)
|
||||
|
||||
abort, diags := getModules(ctx, &c.Meta, path, testsDirectory, update)
|
||||
abort, moreDiags := getModules(ctx, &c.Meta, path, parsedArgs.TestDirectory, parsedArgs.Update)
|
||||
diags = diags.Append(moreDiags)
|
||||
c.showDiagnostics(diags)
|
||||
if abort || diags.HasErrors() {
|
||||
return 1
|
||||
|
|
@ -75,7 +86,16 @@ Options:
|
|||
|
||||
-no-color Disable text coloring in the output.
|
||||
|
||||
-test-directory=path Set the Terraform test directory, defaults to "tests".
|
||||
-test-directory=path Set the Terraform test directory, defaults to "tests".
|
||||
|
||||
-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.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
|
|
|
|||
Loading…
Reference in a new issue