diff --git a/.strict.golangci.yml b/.strict.golangci.yml index 56403bf07..b79c801f9 100644 --- a/.strict.golangci.yml +++ b/.strict.golangci.yml @@ -10,6 +10,8 @@ output: print-linter-name: true linters-settings: + lll: + line-length: 140 staticcheck: checks: - all diff --git a/cli/commands/terraform/download_source.go b/cli/commands/terraform/download_source.go index 1d01a400e..eb866f170 100644 --- a/cli/commands/terraform/download_source.go +++ b/cli/commands/terraform/download_source.go @@ -25,6 +25,8 @@ const ModuleInitRequiredFile = ".terragrunt-init-required" const tfLintConfig = ".tflint.hcl" +const fileURIScheme = "file://" + // 1. Download the given source URL, which should use Terraform's module source syntax, into a temporary folder // 2. Check if module directory exists in temporary folder // 3. Copy the contents of terragruntOptions.WorkingDir into the temporary folder. @@ -227,7 +229,16 @@ func updateGetters(terragruntOptions *options.TerragruntOptions, terragruntConfi // Download the code from the Canonical Source URL into the Download Folder using the go-getter library func downloadSource(terraformSource *terraform.Source, terragruntOptions *options.TerragruntOptions, terragruntConfig *config.TerragruntConfig) error { - terragruntOptions.Logger.Infof("Downloading Terraform configurations from %s into %s", terraformSource.CanonicalSourceURL, terraformSource.DownloadDir) + canonicalSourceURL := terraformSource.CanonicalSourceURL.String() + + // Since we convert abs paths to rel in logs, `file://../../path/to/dir` doesn't look good, + // so it's better to get rid of it. + canonicalSourceURL = strings.TrimPrefix(canonicalSourceURL, fileURIScheme) + + terragruntOptions.Logger.Infof( + "Downloading Terraform configurations from %s into %s", + canonicalSourceURL, + terraformSource.DownloadDir) if err := getter.GetAny(terraformSource.DownloadDir, terraformSource.CanonicalSourceURL.String(), updateGetters(terragruntOptions, terragruntConfig)); err != nil { return errors.WithStackTrace(err) diff --git a/pkg/log/hooks/relative_path.go b/pkg/log/hooks/relative_path.go index ab78bb7b7..23366b4e8 100644 --- a/pkg/log/hooks/relative_path.go +++ b/pkg/log/hooks/relative_path.go @@ -2,6 +2,7 @@ package hooks import ( + "fmt" "os" "path/filepath" "regexp" @@ -51,7 +52,9 @@ func NewRelativePathHook(baseDir string) (*RelativePathHook, error) { reversIndex-- relPaths[reversIndex] = relPath - absPathsReg[reversIndex] = regexp.MustCompile(regexp.QuoteMeta(absPath) + `([` + regexp.QuoteMeta(pathSeparator) + `"'\s]|$)`) + + regStr := fmt.Sprintf(`(^|[^%[1]s\w])%[2]s([%[1]s"'\s]|$)`, regexp.QuoteMeta(pathSeparator), regexp.QuoteMeta(absPath)) + absPathsReg[reversIndex] = regexp.MustCompile(regStr) } return &RelativePathHook{ @@ -91,7 +94,7 @@ func (hook *RelativePathHook) Fire(entry *logrus.Entry) error { func (hook *RelativePathHook) replaceAbsPathsWithRel(text string) string { for i, absPath := range hook.absPathsReg { - text = absPath.ReplaceAllString(text, hook.relPaths[i]+"$1") + text = absPath.ReplaceAllString(text, "$1"+hook.relPaths[i]+"$2") } return text diff --git a/test/fixtures/log-formatter/app/main.tf b/test/fixtures/log/formatter/app/main.tf similarity index 100% rename from test/fixtures/log-formatter/app/main.tf rename to test/fixtures/log/formatter/app/main.tf diff --git a/test/fixtures/log-formatter/app/terragrunt.hcl b/test/fixtures/log/formatter/app/terragrunt.hcl similarity index 100% rename from test/fixtures/log-formatter/app/terragrunt.hcl rename to test/fixtures/log/formatter/app/terragrunt.hcl diff --git a/test/fixtures/log-formatter/dep/main.tf b/test/fixtures/log/formatter/dep/main.tf similarity index 100% rename from test/fixtures/log-formatter/dep/main.tf rename to test/fixtures/log/formatter/dep/main.tf diff --git a/test/fixtures/log-formatter/dep/terragrunt.hcl b/test/fixtures/log/formatter/dep/terragrunt.hcl similarity index 100% rename from test/fixtures/log-formatter/dep/terragrunt.hcl rename to test/fixtures/log/formatter/dep/terragrunt.hcl diff --git a/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/module-b/terragrunt.hcl b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/module-b/terragrunt.hcl new file mode 100644 index 000000000..2772a4f5c --- /dev/null +++ b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/module-b/terragrunt.hcl @@ -0,0 +1,8 @@ +dependency "databricks_workspace" { + config_path = "../workspace" + skip_outputs = true +} + +terraform { + source = "../../../..//tf" +} diff --git a/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/workspace/terragrunt.hcl b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/workspace/terragrunt.hcl new file mode 100644 index 000000000..95ab8d053 --- /dev/null +++ b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/aaa/bbb/ccc/workspace/terragrunt.hcl @@ -0,0 +1,3 @@ +terraform { + source = "../../../..//tf" +} diff --git a/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/tf/main.tf b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/tf/main.tf new file mode 100644 index 000000000..78c912595 --- /dev/null +++ b/test/fixtures/log/rel-paths/duplicate-dir-names/workspace/one/two/tf/main.tf @@ -0,0 +1,6 @@ +resource "null_resource" "this" { +} + +output "dummy" { + value = "dummy" +} diff --git a/test/integration_test.go b/test/integration_test.go index 7fe118f27..13e2d6c4d 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -75,7 +75,8 @@ const ( testFixtureInitOnce = "fixtures/init-once" testFixtureInputs = "fixtures/inputs" testFixtureInputsFromDependency = "fixtures/inputs-from-dependency" - testFixtureLogFormatter = "fixtures/log-formatter" + testFixtureLogFormatter = "fixtures/log/formatter" + testFixtureLogRelPaths = "fixtures/log/rel-paths" testFixtureMissingDependence = "fixtures/missing-dependencies/main" testFixtureModulePathError = "fixtures/module-path-in-error" testFixtureNoColor = "fixtures/no-color" @@ -149,6 +150,45 @@ func TestLogWithAbsPath(t *testing.T) { } } +func TestLogWithRelPath(t *testing.T) { + t.Parallel() + + cleanupTerraformFolder(t, testFixtureLogRelPaths) + tmpEnvPath := copyEnvironment(t, testFixtureLogRelPaths) + rootPath := util.JoinPath(tmpEnvPath, testFixtureLogRelPaths) + + testCases := []struct { + workingDir string + assertFn func(t *testing.T, stdout, stderr string) + }{ + { + workingDir: "duplicate-dir-names/workspace/one/two/aaa", // dir `workspace` duplicated twice in path + assertFn: func(t *testing.T, _, stderr string) { + t.Helper() + + assert.Contains(t, stderr, "Module ./bbb/ccc/workspace") + assert.Contains(t, stderr, "Module ./bbb/ccc/module-b") + assert.Contains(t, stderr, "Downloading Terraform configurations from .. into ./bbb/ccc/workspace/.terragrunt-cache") + assert.Contains(t, stderr, "[bbb/ccc/workspace]") + assert.Contains(t, stderr, "[bbb/ccc/module-b]") + }, + }, + } + + for i, testCase := range testCases { + workingDir := filepath.Join(rootPath, testCase.workingDir) + + t.Run(fmt.Sprintf("testCase-%d", i), func(t *testing.T) { + t.Parallel() + + stdout, stderr, err := runTerragruntCommandWithOutput(t, "terragrunt run-all init --terragrunt-log-level debug --terragrunt-non-interactive --terragrunt-disable-log-formatting=false -no-color --terragrunt-no-color --terragrunt-working-dir "+workingDir) + require.NoError(t, err) + + testCase.assertFn(t, stdout, stderr) + }) + } +} + func TestLogFormatterPrettyOutput(t *testing.T) { t.Parallel()