Skip to content

Commit

Permalink
Merge pull request #1376 from gruntwork-io/bug/validate-all
Browse files Browse the repository at this point in the history
Fix root path lookup in validate-all
  • Loading branch information
brikis98 authored Jan 16, 2024
2 parents 28c0f43 + 11e2d26 commit 74d9df0
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 18 deletions.
18 changes: 18 additions & 0 deletions modules/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package git

import (
"os"
"os/exec"
"strings"

Expand Down Expand Up @@ -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
Expand Down
42 changes: 24 additions & 18 deletions modules/test-structure/test_structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -192,29 +194,33 @@ 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)
// 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)
})
}
}
36 changes: 36 additions & 0 deletions modules/test-structure/validate_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 74d9df0

Please sign in to comment.