From bb75d4c32d8d4060aa6fd622b74fdf691df2a262 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Fri, 20 Mar 2026 16:41:24 +0000 Subject: [PATCH] backport of commit 33ef3dc5169d78f0f4f53398f7c5c019f9190608 --- internal/command/modules_test.go | 130 ++++++++++++++++++ .../.terraform/modules/modules.json | 14 ++ .../.terraform/terraform.tfstate | 18 +++ .../main.tf | 17 +++ .../modules/example/main.tf | 2 + 5 files changed, 181 insertions(+) create mode 100644 internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/modules/modules.json create mode 100644 internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/terraform.tfstate create mode 100644 internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/modules/example/main.tf diff --git a/internal/command/modules_test.go b/internal/command/modules_test.go index a75e5d48c3..efec69bb0f 100644 --- a/internal/command/modules_test.go +++ b/internal/command/modules_test.go @@ -15,6 +15,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/cli" + "github.com/hashicorp/terraform/internal/backend" + backendInit "github.com/hashicorp/terraform/internal/backend/init" + backendCloud "github.com/hashicorp/terraform/internal/cloud" "github.com/hashicorp/terraform/internal/moduleref" ) @@ -183,6 +186,133 @@ func TestModules_uninstalledModules(t *testing.T) { } } +func TestModules_constVariable(t *testing.T) { + t.Run("missing value", func(t *testing.T) { + wd := tempWorkingDirFixture(t, "dynamic-module-sources/command-with-const-var") + t.Chdir(wd.RootModuleDir()) + + ui := cli.NewMockUi() + view, done := testView(t) + + cmd := &ModulesCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + WorkingDir: wd, + }, + } + + args := []string{} + code := cmd.Run(args) + if code == 0 { + t.Fatalf("expected error, got 0") + } + + output := done(t).All() + if !strings.Contains(output, "No value for required variable") { + t.Fatalf("expected missing variable error, got: %s", output) + } + }) + + t.Run("value via cli", func(t *testing.T) { + wd := tempWorkingDirFixture(t, "dynamic-module-sources/command-with-const-var") + t.Chdir(wd.RootModuleDir()) + + ui := cli.NewMockUi() + view, done := testView(t) + + cmd := &ModulesCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + WorkingDir: wd, + }, + } + + args := []string{} + code := cmd.Run(append(args, "-var", "module_name=child")) + if code != 0 { + t.Fatalf("Got a non-zero exit code: %d\n%s", code, done(t).All()) + } + + actual := done(t).All() + + expectedOutputHuman := ` +Modules declared by configuration: +. +└── "child"[./modules/child] + +` + if runtime.GOOS == "windows" { + expectedOutputHuman = ` +Modules declared by configuration: +. +└── "child"[.\modules\child] + +` + } + + if diff := cmp.Diff(expectedOutputHuman, actual); diff != "" { + t.Fatalf("unexpected output:\n%s\n", diff) + } + }) + + t.Run("value via backend", func(t *testing.T) { + server := cloudTestServerWithVars(t) + defer server.Close() + d := testDisco(server) + + previousBackend := backendInit.Backend("cloud") + backendInit.Set("cloud", func() backend.Backend { return backendCloud.New(d) }) + defer backendInit.Set("cloud", previousBackend) + + wd := tempWorkingDirFixture(t, "dynamic-module-sources/command-with-const-var-cloud-backend") + t.Chdir(wd.RootModuleDir()) + + ui := cli.NewMockUi() + view, done := testView(t) + + cmd := &ModulesCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + WorkingDir: wd, + Services: d, + }, + } + + args := []string{} + code := cmd.Run(args) + if code != 0 { + t.Fatalf("Got a non-zero exit code: %d\n%s", code, done(t).All()) + } + + actual := done(t).All() + + expectedOutputHuman := ` +Modules declared by configuration: +. +└── "child"[./modules/example] + +` + if runtime.GOOS == "windows" { + expectedOutputHuman = ` +Modules declared by configuration: +. +└── "child"[.\modules\example] + +` + } + + if diff := cmp.Diff(expectedOutputHuman, actual); diff != "" { + t.Fatalf("unexpected output:\n%s\n", diff) + } + }) +} + func compareJSONOutput(t *testing.T, got string, want string) { var expected, actual moduleref.Manifest diff --git a/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/modules/modules.json b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/modules/modules.json new file mode 100644 index 0000000000..41c20b6d4e --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/modules/modules.json @@ -0,0 +1,14 @@ +{ + "Modules": [ + { + "Key": "", + "Source": "", + "Dir": "." + }, + { + "Key": "child", + "Source": "./modules/example", + "Dir": "modules/example" + } + ] +} diff --git a/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/terraform.tfstate b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/terraform.tfstate new file mode 100644 index 0000000000..bc5581ba3b --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/.terraform/terraform.tfstate @@ -0,0 +1,18 @@ +{ + "version": 3, + "terraform_version": "1.15.0", + "backend": { + "type": "cloud", + "config": { + "hostname": null, + "organization": "hashicorp", + "token": null, + "workspaces": { + "name": "test", + "project": null, + "tags": null + } + }, + "hash": 1816475682 + } +} diff --git a/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/main.tf b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/main.tf new file mode 100644 index 0000000000..abe6a9b218 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/main.tf @@ -0,0 +1,17 @@ +terraform { + cloud { + organization = "hashicorp" + workspaces { + name = "test" + } + } +} + +variable "module_name" { + type = string + const = true +} + +module "child" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/modules/example/main.tf new file mode 100644 index 0000000000..74c9b66518 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/command-with-const-var-cloud-backend/modules/example/main.tf @@ -0,0 +1,2 @@ +resource "test_instance" "test" { +}