diff --git a/config/module/detect_file.go b/config/module/detect_file.go index 2b8dbacbe6f2..859739f95489 100644 --- a/config/module/detect_file.go +++ b/config/module/detect_file.go @@ -2,6 +2,7 @@ package module import ( "fmt" + "os" "path/filepath" "runtime" ) @@ -20,8 +21,27 @@ func (d *FileDetector) Detect(src, pwd string) (string, bool, error) { "relative paths require a module with a pwd") } + // Stat the pwd to determine if its a symbolic link. If it is, + // then the pwd becomes the original directory. Otherwise, + // `filepath.Join` below does some weird stuff. + // + // We just ignore if the pwd doesn't exist. That error will be + // caught later when we try to use the URL. + if fi, err := os.Lstat(pwd); !os.IsNotExist(err) { + if err != nil { + return "", true, err + } + if fi.Mode()&os.ModeSymlink != 0 { + pwd, err = os.Readlink(pwd) + if err != nil { + return "", true, err + } + } + } + src = filepath.Join(pwd, src) } + return fmtFileURL(src), true, nil } diff --git a/config/module/test-fixtures/basic-parent/a/a.tf b/config/module/test-fixtures/basic-parent/a/a.tf new file mode 100644 index 000000000000..b9b44f464037 --- /dev/null +++ b/config/module/test-fixtures/basic-parent/a/a.tf @@ -0,0 +1,3 @@ +module "b" { + source = "../c" +} diff --git a/config/module/test-fixtures/basic-parent/c/c.tf b/config/module/test-fixtures/basic-parent/c/c.tf new file mode 100644 index 000000000000..fec56017dc1b --- /dev/null +++ b/config/module/test-fixtures/basic-parent/c/c.tf @@ -0,0 +1 @@ +# Hello diff --git a/config/module/test-fixtures/basic-parent/main.tf b/config/module/test-fixtures/basic-parent/main.tf new file mode 100644 index 000000000000..2326ee22acca --- /dev/null +++ b/config/module/test-fixtures/basic-parent/main.tf @@ -0,0 +1,3 @@ +module "a" { + source = "./a" +} diff --git a/config/module/tree_test.go b/config/module/tree_test.go index d8a75352259e..9ac0c582da00 100644 --- a/config/module/tree_test.go +++ b/config/module/tree_test.go @@ -94,6 +94,44 @@ func TestTreeLoad_duplicate(t *testing.T) { } } +func TestTreeLoad_parentRef(t *testing.T) { + storage := testStorage(t) + tree := NewTree("", testConfig(t, "basic-parent")) + + if tree.Loaded() { + t.Fatal("should not be loaded") + } + + // This should error because we haven't gotten things yet + if err := tree.Load(storage, GetModeNone); err == nil { + t.Fatal("should error") + } + + if tree.Loaded() { + t.Fatal("should not be loaded") + } + + // This should get things + if err := tree.Load(storage, GetModeGet); err != nil { + t.Fatalf("err: %s", err) + } + + if !tree.Loaded() { + t.Fatal("should be loaded") + } + + // This should no longer error + if err := tree.Load(storage, GetModeNone); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(tree.String()) + expected := strings.TrimSpace(treeLoadParentStr) + if actual != expected { + t.Fatalf("bad: \n\n%s", actual) + } +} + func TestTreeLoad_subdir(t *testing.T) { storage := testStorage(t) tree := NewTree("", testConfig(t, "basic-subdir")) @@ -239,6 +277,11 @@ root foo ` +const treeLoadParentStr = ` +root + a + b +` const treeLoadSubdirStr = ` root foo