Skip to content

Commit 10f56fc

Browse files
committed
Allow terraform init when only test files are present
1 parent 16a34fe commit 10f56fc

File tree

8 files changed

+88
-10
lines changed

8 files changed

+88
-10
lines changed

internal/command/init.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (c *InitCommand) Run(args []string) int {
108108
if initArgs.FromModule != "" {
109109
src := initArgs.FromModule
110110

111-
empty, err := configs.IsEmptyDir(path)
111+
empty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory)
112112
if err != nil {
113113
diags = diags.Append(fmt.Errorf("Error validating destination directory: %s", err))
114114
view.Diagnostics(diags)
@@ -148,7 +148,7 @@ func (c *InitCommand) Run(args []string) int {
148148

149149
// If our directory is empty, then we're done. We can't get or set up
150150
// the backend with an empty directory.
151-
empty, err := configs.IsEmptyDir(path)
151+
empty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory)
152152
if err != nil {
153153
diags = diags.Append(fmt.Errorf("Error checking configuration: %s", err))
154154
view.Diagnostics(diags)

internal/command/init_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"log"
1010
"os"
1111
"path/filepath"
12+
"regexp"
1213
"strings"
1314
"testing"
1415

@@ -20,6 +21,7 @@ import (
2021

2122
"github.com/hashicorp/terraform/internal/addrs"
2223
"github.com/hashicorp/terraform/internal/command/arguments"
24+
"github.com/hashicorp/terraform/internal/command/views"
2325
"github.com/hashicorp/terraform/internal/configs"
2426
"github.com/hashicorp/terraform/internal/configs/configschema"
2527
"github.com/hashicorp/terraform/internal/depsfile"
@@ -32,6 +34,25 @@ import (
3234
"github.com/hashicorp/terraform/internal/states/statemgr"
3335
)
3436

37+
// cleanString removes newlines, and redundant spaces.
38+
func cleanString(s string) string {
39+
// Replace newlines with a single space.
40+
s = strings.ReplaceAll(s, "\n", " ")
41+
42+
// Remove other special characters like \r, \t
43+
s = strings.ReplaceAll(s, "\r", "")
44+
s = strings.ReplaceAll(s, "\t", "")
45+
46+
// Replace multiple spaces with a single space.
47+
spaceRegex := regexp.MustCompile(`\s+`)
48+
s = spaceRegex.ReplaceAllString(s, " ")
49+
50+
// Trim any leading or trailing spaces.
51+
s = strings.TrimSpace(s)
52+
53+
return s
54+
}
55+
3556
func TestInit_empty(t *testing.T) {
3657
// Create a temporary working directory that is empty
3758
td := t.TempDir()
@@ -52,6 +73,42 @@ func TestInit_empty(t *testing.T) {
5273
if code := c.Run(args); code != 0 {
5374
t.Fatalf("bad: \n%s", done(t).All())
5475
}
76+
exp := views.MessageRegistry[views.OutputInitEmptyMessage].JSONValue
77+
actual := cleanString(done(t).All())
78+
if !strings.Contains(actual, cleanString(exp)) {
79+
t.Fatalf("expected output to be %q\n, got %q", exp, actual)
80+
}
81+
}
82+
83+
func TestInit_only_test_files(t *testing.T) {
84+
// Create a temporary working directory that has only test files and no tf configuration
85+
td := t.TempDir()
86+
os.MkdirAll(td, 0755)
87+
defer testChdir(t, td)()
88+
89+
if _, err := os.Create("main.tftest.hcl"); err != nil {
90+
t.Fatalf("err: %s", err)
91+
}
92+
93+
ui := new(cli.MockUi)
94+
view, done := testView(t)
95+
c := &InitCommand{
96+
Meta: Meta{
97+
testingOverrides: metaOverridesForProvider(testProvider()),
98+
Ui: ui,
99+
View: view,
100+
},
101+
}
102+
103+
args := []string{}
104+
if code := c.Run(args); code != 0 {
105+
t.Fatalf("bad: \n%s", done(t).All())
106+
}
107+
exp := views.MessageRegistry[views.OutputInitSuccessCLIMessage].JSONValue
108+
actual := cleanString(done(t).All())
109+
if !strings.Contains(actual, cleanString(exp)) {
110+
t.Fatalf("expected output to be %q\n, got %q", exp, actual)
111+
}
55112
}
56113

57114
func TestInit_multipleArgs(t *testing.T) {

internal/command/providers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (c *ProvidersCommand) Run(args []string) int {
4949

5050
var diags tfdiags.Diagnostics
5151

52-
empty, err := configs.IsEmptyDir(configPath)
52+
empty, err := configs.IsEmptyDir(configPath, "")
5353
if err != nil {
5454
diags = diags.Append(tfdiags.Sourceless(
5555
tfdiags.Error,

internal/command/test_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ func TestTest_Runs(t *testing.T) {
4141
expectedOut: []string{"1 passed, 0 failed."},
4242
code: 0,
4343
},
44+
"from-empty-dir-with-module": {
45+
expectedOut: []string{"1 passed, 0 failed."},
46+
code: 0,
47+
},
4448
"simple_pass_nested": {
4549
expectedOut: []string{"1 passed, 0 failed."},
4650
code: 0,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
variable "sample" {
2+
type = bool
3+
default = true
4+
}
5+
6+
output "name" {
7+
value = var.sample
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
run "foo" {
2+
module {
3+
source = "./fixtures"
4+
}
5+
assert {
6+
condition = output.name == true
7+
error_message = "foo"
8+
}
9+
}

internal/configs/parser_config_dir.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,21 +324,21 @@ func IsIgnoredFile(name string) bool {
324324
}
325325

326326
// IsEmptyDir returns true if the given filesystem path contains no Terraform
327-
// configuration files.
327+
// configuration or test files.
328328
//
329329
// Unlike the methods of the Parser type, this function always consults the
330330
// real filesystem, and thus it isn't appropriate to use when working with
331331
// configuration loaded from a plan file.
332-
func IsEmptyDir(path string) (bool, error) {
332+
func IsEmptyDir(path, testDir string) (bool, error) {
333333
if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
334334
return true, nil
335335
}
336336

337337
p := NewParser(nil)
338-
fs, os, _, diags := p.dirFiles(path, "")
338+
fs, os, tests, diags := p.dirFiles(path, testDir)
339339
if diags.HasErrors() {
340340
return false, diags
341341
}
342342

343-
return len(fs) == 0 && len(os) == 0, nil
343+
return len(fs) == 0 && len(os) == 0 && len(tests) == 0, nil
344344
}

internal/configs/parser_config_dir_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ func TestParserLoadConfigDirFailure(t *testing.T) {
321321
}
322322

323323
func TestIsEmptyDir(t *testing.T) {
324-
val, err := IsEmptyDir(filepath.Join("testdata", "valid-files"))
324+
val, err := IsEmptyDir(filepath.Join("testdata", "valid-files"), "")
325325
if err != nil {
326326
t.Fatalf("err: %s", err)
327327
}
@@ -331,7 +331,7 @@ func TestIsEmptyDir(t *testing.T) {
331331
}
332332

333333
func TestIsEmptyDir_noExist(t *testing.T) {
334-
val, err := IsEmptyDir(filepath.Join("testdata", "nopenopenope"))
334+
val, err := IsEmptyDir(filepath.Join("testdata", "nopenopenope"), "")
335335
if err != nil {
336336
t.Fatalf("err: %s", err)
337337
}
@@ -341,7 +341,7 @@ func TestIsEmptyDir_noExist(t *testing.T) {
341341
}
342342

343343
func TestIsEmptyDir_noConfigs(t *testing.T) {
344-
val, err := IsEmptyDir(filepath.Join("testdata", "dir-empty"))
344+
val, err := IsEmptyDir(filepath.Join("testdata", "dir-empty"), "")
345345
if err != nil {
346346
t.Fatalf("err: %s", err)
347347
}

0 commit comments

Comments
 (0)