Better var file type detection (#1881)

Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
Christian Mesh 2024-08-02 07:29:40 -04:00 committed by GitHub
parent 131c2cadda
commit ce24a6b961
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 91 additions and 2 deletions

View File

@ -32,8 +32,11 @@ const DefaultPluginVendorDir = "terraform.d/plugins/" + pluginMachineName
// DefaultStateFilename is the default filename used for the state file.
const DefaultStateFilename = "terraform.tfstate"
// DefaultVarsExtension is the default file extension used for vars
const DefaultVarsExtension = ".tfvars"
// DefaultVarsFilename is the default filename used for vars
const DefaultVarsFilename = "terraform.tfvars"
const DefaultVarsFilename = "terraform" + DefaultVarsExtension
// DefaultBackupExtension is added to the state file to form the path
const DefaultBackupExtension = ".backup"

View File

@ -182,7 +182,15 @@ func (m *Meta) addVarsFromFile(filename string, sourceType tofu.ValueSourceType,
loader.Parser().ForceFileSource(filename, src)
var f *hcl.File
if strings.HasSuffix(filename, ".json") {
extJSON := strings.HasSuffix(filename, ".json")
extTfvars := strings.HasSuffix(filename, DefaultVarsExtension)
// Only try json detection if ambiguous
// Ex: -var-file=<(./scripts/vars.sh)
detectJSON := !extJSON && !extTfvars && strings.HasPrefix(strings.TrimSpace(string(src)), "{")
if extJSON || detectJSON {
var hclDiags hcl.Diagnostics
f, hclDiags = hcljson.Parse(src, filename)
diags = diags.Append(hclDiags)

View File

@ -0,0 +1,78 @@
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package command
import (
"os"
"path/filepath"
"testing"
"github.com/opentofu/opentofu/internal/backend"
"github.com/opentofu/opentofu/internal/tofu"
)
func TestMeta_addVarsFromFile(t *testing.T) {
d := t.TempDir()
defer testChdir(t, d)()
hclData := `foo = "bar"`
jsonData := `{"foo": "bar"}`
cases := []struct {
filename string
contents string
errors bool
}{
{
filename: "input.tfvars",
contents: hclData,
errors: false,
},
{
filename: "input.json",
contents: jsonData,
errors: false,
},
{
filename: "input_a.unknown",
contents: hclData,
errors: false,
},
{
filename: "input_b.unknown",
contents: jsonData,
errors: false,
},
{
filename: "mismatch.tfvars",
contents: jsonData,
errors: true,
},
{
filename: "mismatch.json",
contents: hclData,
errors: true,
},
}
for _, tc := range cases {
t.Run(tc.filename, func(t *testing.T) {
target := filepath.Join(d, tc.filename)
err := os.WriteFile(target, []byte(tc.contents), 0600)
if err != nil {
t.Fatalf("err: %s", err)
}
m := new(Meta)
to := make(map[string]backend.UnparsedVariableValue)
diags := m.addVarsFromFile(target, tofu.ValueFromAutoFile, to)
if tc.errors != diags.HasErrors() {
t.Log(diags.Err())
t.Errorf("Expected: %v, got %v", tc.errors, diags.HasErrors())
}
})
}
}