From 0222ffe321320f01574d7a45a05e288587738150 Mon Sep 17 00:00:00 2001 From: Yevgeniy Brikman Date: Thu, 30 Nov 2023 17:37:58 -0500 Subject: [PATCH 1/2] Fix root path lookup in validate-all --- modules/git/git.go | 18 ++++++++++ modules/test-structure/test_structure.go | 44 +++++++++++++---------- modules/test-structure/validate_struct.go | 36 +++++++++++++++++++ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/modules/git/git.go b/modules/git/git.go index dbd1207ad..1afc2428d 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -2,6 +2,7 @@ package git import ( + "os" "os/exec" "strings" @@ -106,7 +107,24 @@ func GetRepoRoot(t testing.TestingT) string { // GetRepoRootE retrieves the path to the root directory of the repo. func GetRepoRootE(t testing.TestingT) (string, error) { + dir, err := os.Getwd() + if err != nil { + return "", err + } + return GetRepoRootForDirE(t, dir) +} + +// GetRepoRootForDir retrieves the path to the root directory of the repo in which dir resides +func GetRepoRootForDir(t testing.TestingT, dir string) string { + out, err := GetRepoRootForDirE(t, dir) + require.NoError(t, err) + return out +} + +// GetRepoRootForDirE retrieves the path to the root directory of the repo in which dir resides +func GetRepoRootForDirE(t testing.TestingT, dir string) (string, error) { cmd := exec.Command("git", "rev-parse", "--show-toplevel") + cmd.Dir = dir bytes, err := cmd.Output() if err != nil { return "", err diff --git a/modules/test-structure/test_structure.go b/modules/test-structure/test_structure.go index 032716e6e..4430b1090 100644 --- a/modules/test-structure/test_structure.go +++ b/modules/test-structure/test_structure.go @@ -6,6 +6,8 @@ import ( "path/filepath" "strings" + "github.com/gruntwork-io/terratest/modules/git" + go_test "testing" "github.com/gruntwork-io/terratest/modules/files" @@ -192,29 +194,35 @@ func runValidateOnAllTerraformModules( opts *ValidationOptions, validationFunc func(t *go_test.T, fileType ValidateFileType, tfOps *terraform.Options), ) { - dirsToValidate, readErr := FindTerraformModulePathsInRootE(opts) + // Find the Git root + gitRoot, err := git.GetRepoRootForDirE(t, opts.RootDir) + require.NoError(t, err) + + // Find the relative path between the root dir and the git root + relPath, err := filepath.Rel(gitRoot, opts.RootDir) + require.NoError(t, err) + + // Copy git root to tmp + testFolder := CopyTerraformFolderToTemp(t, gitRoot, relPath) + require.NotNil(t, testFolder) + + // Clone opts and override the root dir to the temp folder + clonedOpts, err := CloneWithNewRootDir(opts, testFolder) + require.NoError(t, err) + + // Find TF modules + dirsToValidate, readErr := FindTerraformModulePathsInRootE(clonedOpts) require.NoError(t, readErr) for _, dir := range dirsToValidate { dir := dir t.Run(strings.TrimLeft(dir, "/"), func(t *go_test.T) { - // Determine the absolute path to the git repository root - cwd, cwdErr := os.Getwd() - require.NoError(t, cwdErr) - gitRoot, gitRootErr := filepath.Abs(filepath.Join(cwd, "../../")) - require.NoError(t, gitRootErr) - - // Determine the relative path to the example, module, etc that is currently being considered - relativePath, pathErr := filepath.Rel(gitRoot, dir) - require.NoError(t, pathErr) - // Copy git root to tmp and supply the path to the current module to run init and validate on - testFolder := CopyTerraformFolderToTemp(t, gitRoot, relativePath) - require.NotNil(t, testFolder) - - // Run Terraform init and terraform validate on the test folder that was copied to /tmp - // to avoid any potential conflicts with tests that may not use the same copy to /tmp behavior - tfOpts := &terraform.Options{TerraformDir: testFolder} - validationFunc(t, opts.FileType, tfOpts) + t.Logf("Original root = %s, git root = %s, testFolder = %s, dir = %s", opts.RootDir, gitRoot, testFolder, dir) + + // Run the validation function on the test folder that was copied to /tmp to avoid any potential conflicts + // with tests that may not use the same copy to /tmp behavior + tfOpts := &terraform.Options{TerraformDir: dir} + validationFunc(t, clonedOpts.FileType, tfOpts) }) } } diff --git a/modules/test-structure/validate_struct.go b/modules/test-structure/validate_struct.go index 69a0555fb..0860178d0 100644 --- a/modules/test-structure/validate_struct.go +++ b/modules/test-structure/validate_struct.go @@ -42,6 +42,26 @@ type ValidationOptions struct { ExcludeDirs []string } +// CloneWithNewRootDir clones the given opts with a new root dir. Updates all include and exclude dirs to be relative +// to the new root dir. +func CloneWithNewRootDir(opts *ValidationOptions, newRootDir string) (*ValidationOptions, error) { + includeDirs, err := buildRelPathsFromFull(opts.RootDir, opts.IncludeDirs) + if err != nil { + return nil, err + } + excludeDirs, err := buildRelPathsFromFull(opts.RootDir, opts.ExcludeDirs) + if err != nil { + return nil, err + } + + out, err := NewValidationOptions(newRootDir, includeDirs, excludeDirs) + if err != nil { + return nil, err + } + out.FileType = opts.FileType + return out, nil +} + // configureBaseValidationOptions returns a pointer to a ValidationOptions struct configured with sane, override-able defaults // Note that the ValidationOptions's fields IncludeDirs and ExcludeDirs must be absolute paths, but this method will accept relative paths // and build the absolute paths when instantiating the ValidationOptions struct, making it the preferred means of configuring @@ -104,6 +124,22 @@ func NewTerragruntValidationOptions(rootDir string, includeDirs, excludeDirs []s return opts, nil } +func buildRelPathsFromFull(rootDir string, fullPaths []string) ([]string, error) { + var relPaths []string + for _, maybeFullPath := range fullPaths { + if filepath.IsAbs(maybeFullPath) { + relPath, err := filepath.Rel(rootDir, maybeFullPath) + if err != nil { + return nil, err + } + relPaths = append(relPaths, relPath) + } else { + relPaths = append(relPaths, maybeFullPath) + } + } + return relPaths, nil +} + func buildFullPathsFromRelative(rootDir string, relativePaths []string) []string { var fullPaths []string for _, maybeRelativePath := range relativePaths { From 11e2d2612437f338466d2da1611abf956b456630 Mon Sep 17 00:00:00 2001 From: Yevgeniy Brikman Date: Thu, 30 Nov 2023 17:39:38 -0500 Subject: [PATCH 2/2] Remove unnecessary log statement --- modules/test-structure/test_structure.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/test-structure/test_structure.go b/modules/test-structure/test_structure.go index 4430b1090..a80bfb222 100644 --- a/modules/test-structure/test_structure.go +++ b/modules/test-structure/test_structure.go @@ -217,8 +217,6 @@ func runValidateOnAllTerraformModules( for _, dir := range dirsToValidate { dir := dir t.Run(strings.TrimLeft(dir, "/"), func(t *go_test.T) { - t.Logf("Original root = %s, git root = %s, testFolder = %s, dir = %s", opts.RootDir, gitRoot, testFolder, dir) - // Run the validation function on the test folder that was copied to /tmp to avoid any potential conflicts // with tests that may not use the same copy to /tmp behavior tfOpts := &terraform.Options{TerraformDir: dir}