diff --git a/internal/command/init.go b/internal/command/init.go index ec6fa5723c..551a4d0b8a 100644 --- a/internal/command/init.go +++ b/internal/command/init.go @@ -182,24 +182,6 @@ func (c *InitCommand) Run(args []string) int { } } - // Using loadSingleModule will allow us to get the sniffed required_version - // before trying to build the complete config. - rootMod, _ := c.loadSingleModule(path) - // We can ignore the error, since we are going to reload the full config - // again below once we know the root module constraints are valid. - if rootMod != nil { - rootCfg := &configs.Config{ - Module: rootMod, - } - // If our module version constraints are not valid, then there is no - // need to continue processing. - versionDiags := terraform.CheckCoreVersionRequirements(rootCfg) - if versionDiags.HasErrors() { - c.showDiagnostics(versionDiags) - return 1 - } - } - // With all of the modules (hopefully) installed, we can now try to load the // whole configuration tree. config, confDiags := c.loadConfig(path) @@ -207,9 +189,9 @@ func (c *InitCommand) Run(args []string) int { // incorrect version of terraform may be producing errors for configuration // constructs added in later versions. - // Check again to make sure none of the modules in the configuration - // declare that they don't support this Terraform version, so we can - // produce a version-related error message rather than + // Before we go further, we'll check to make sure none of the modules in + // the configuration declare that they don't support this Terraform + // version, so we can produce a version-related error message rather than // potentially-confusing downstream errors. versionDiags := terraform.CheckCoreVersionRequirements(config) if versionDiags.HasErrors() { diff --git a/internal/command/init_test.go b/internal/command/init_test.go index 2bf1e0e264..2d96b27b44 100644 --- a/internal/command/init_test.go +++ b/internal/command/init_test.go @@ -1611,28 +1611,54 @@ func TestInit_checkRequiredVersion(t *testing.T) { // Verify that init will error out with an invalid version constraint, even if // there are other invalid configuration constructs. func TestInit_checkRequiredVersionFirst(t *testing.T) { - td := t.TempDir() - testCopyDir(t, testFixturePath("init-check-required-version-first"), td) - defer testChdir(t, td)() + t.Run("root_module", func(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath("init-check-required-version-first"), td) + defer testChdir(t, td)() - ui := cli.NewMockUi() - view, _ := testView(t) - c := &InitCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(testProvider()), - Ui: ui, - View: view, - }, - } + ui := cli.NewMockUi() + view, _ := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } - args := []string{} - if code := c.Run(args); code != 1 { - t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String()) - } - errStr := ui.ErrorWriter.String() - if !strings.Contains(errStr, `Unsupported Terraform Core version`) { - t.Fatalf("output should point to unmet version constraint, but is:\n\n%s", errStr) - } + args := []string{} + if code := c.Run(args); code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String()) + } + errStr := ui.ErrorWriter.String() + if !strings.Contains(errStr, `Unsupported Terraform Core version`) { + t.Fatalf("output should point to unmet version constraint, but is:\n\n%s", errStr) + } + }) + t.Run("sub_module", func(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath("init-check-required-version-first-module"), td) + defer testChdir(t, td)() + + ui := cli.NewMockUi() + view, _ := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + args := []string{} + if code := c.Run(args); code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String()) + } + errStr := ui.ErrorWriter.String() + if !strings.Contains(errStr, `Unsupported Terraform Core version`) { + t.Fatalf("output should point to unmet version constraint, but is:\n\n%s", errStr) + } + }) } func TestInit_providerLockFile(t *testing.T) { diff --git a/internal/command/testdata/init-check-required-version-first-module/main.tf b/internal/command/testdata/init-check-required-version-first-module/main.tf new file mode 100644 index 0000000000..ba84684699 --- /dev/null +++ b/internal/command/testdata/init-check-required-version-first-module/main.tf @@ -0,0 +1,3 @@ +module "mod" { + source = "./mod" +} diff --git a/internal/command/testdata/init-check-required-version-first-module/mod/main.tf b/internal/command/testdata/init-check-required-version-first-module/mod/main.tf new file mode 100644 index 0000000000..ab311d0669 --- /dev/null +++ b/internal/command/testdata/init-check-required-version-first-module/mod/main.tf @@ -0,0 +1,17 @@ +terraform { + required_version = ">200.0.0" + + bad { + block = "false" + } + + required_providers { + bang = { + oops = "boom" + } + } +} + +nope { + boom {} +}