Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package terragrunt for openSUSE:Factory checked in at 2025-05-30 14:36:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/terragrunt (Old) and /work/SRC/openSUSE:Factory/.terragrunt.new.25440 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "terragrunt" Fri May 30 14:36:31 2025 rev:230 rq:1281062 version:0.80.3 Changes: -------- --- /work/SRC/openSUSE:Factory/terragrunt/terragrunt.changes 2025-05-23 14:32:17.448979155 +0200 +++ /work/SRC/openSUSE:Factory/.terragrunt.new.25440/terragrunt.changes 2025-05-30 17:27:38.533014455 +0200 @@ -1,0 +2,72 @@ +Thu May 29 05:39:25 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- Update to version 0.80.3: + * Performance Improvements + - Significant performance improvements for run --all + The performance of run --all has been improved in two + significant ways: + 1. Performance for named includes has improved. + Backwards compatibility for bare includes required that + Terragrunt do some inefficient work internally to handle + both named includes and bare includes by doing an + in-memory rewrite of Terragrunt configurations. An + optimization has been introduced to avoid this behavior + when users use named includes. This optimization does not + extend to users that are using bare includes. + Users are advised to avoid using bare includes whenever + possible for maximum performance. A strict control has + been introduced to enforce usage of named includes. + In a future minor release, a warning will be emitted, + instructing users to stop using bare includes. Maintainers + will avoid breaking support for bare includes until at + least 2.0. + For more information on how to benefit from this + optimization, see the migration guide. + 2. The check for OpenTofu/Terraform code has been optimized. + To provide helpful error messages when users don't have + OpenTofu/Terraform code for Terragrunt to run, Terragrunt + checks for the presence of OpenTofu/Terraform + configuration files (e.g. *.tf, *.tofu). This check has + been optimized to improve performance. + In a micro-benchmark on an M3 Max, using the + BenchmarkManyEmptyTerragruntInits benchmark, which tests the + performance of a Terragrunt run --all init across 1000 inits, + the following performance gains were released: + 42% speed improvement. + 43% memory reduction. + More optimizations of this sort are planned for future + releases. + - Size reduction of compiled binaries + The size of compiled binaries will be reduced due to the + stripping of debug symbols from the final executable. As an + example, this drops the size of the compiled Linux AMD64 + binary from 99MB to 70MB. + This can be a small improvement to download times for + environments where Terragrunt is downloaded frequently. + * Bug Fixes + - Fixed -detailed-exitcode behavior in run --all + An unintended side-effect of addressing a different bug for + Terragrunt’s handling of the -detailed-exitcode flag in + OpenTofu/Terraform in retries was that any run in a run --all + could override the exit code of the entire run --all. + This has been fixed. The exit code of the run --all -- plan + -detailed-exitcode command will now properly aggregate exit + codes from all runs in a run --all, only reseting the exit + code for an individual unit if it properly recovers after a + retry. + * What's Changed + - docs: Documenting deprecation of bare includes (#4346) + - fix: Fixing discrepency betwen Jekyl docs and Starlight docs + for validate (#4359) + - fix: Adjusting tf check so that it's easier to update (#4360) + - fix: Setting of right exit code in case of detailed-exitcode + (#4357) + - perf: Deprecating bare includes (#4340) + - perf: Adding optimized tf code check (#4339) + - fix: Removing unnecessary input on flake dispatch [skip ci] + (#4337) + - fix: Get way more aggressive with cleanup (#4342) + - fix: Reverting to defer (#4344) + - chore: reduce size of produced executable (#4341) + +------------------------------------------------------------------- Old: ---- terragrunt-0.80.2.obscpio New: ---- terragrunt-0.80.3.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ terragrunt.spec ++++++ --- /var/tmp/diff_new_pack.dzsbuY/_old 2025-05-30 17:27:39.849069112 +0200 +++ /var/tmp/diff_new_pack.dzsbuY/_new 2025-05-30 17:27:39.849069112 +0200 @@ -17,7 +17,7 @@ Name: terragrunt -Version: 0.80.2 +Version: 0.80.3 Release: 0 Summary: Thin wrapper for Terraform for working with multiple Terraform modules License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.dzsbuY/_old 2025-05-30 17:27:39.909071604 +0200 +++ /var/tmp/diff_new_pack.dzsbuY/_new 2025-05-30 17:27:39.909071604 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/gruntwork-io/terragrunt</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.80.2</param> + <param name="revision">v0.80.3</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.dzsbuY/_old 2025-05-30 17:27:39.937072767 +0200 +++ /var/tmp/diff_new_pack.dzsbuY/_new 2025-05-30 17:27:39.941072933 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/gruntwork-io/terragrunt</param> - <param name="changesrevision">e629ad9a755991b9a4e2eca3e6636b6e5095f8c8</param></service></servicedata> + <param name="changesrevision">e000a44f60aaeb19cd07676b14f82a47d0ad494e</param></service></servicedata> (No newline at EOF) ++++++ terragrunt-0.80.2.obscpio -> terragrunt-0.80.3.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/.circleci/config.yml new/terragrunt-0.80.3/.circleci/config.yml --- old/terragrunt-0.80.2/.circleci/config.yml 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/.circleci/config.yml 2025-05-27 17:52:10.000000000 +0200 @@ -21,7 +21,7 @@ <<: *defaults steps: - checkout - - run: build-go-binaries --app-name terragrunt --dest-path bin --ld-flags "-X github.com/gruntwork-io/go-commons/version.Version=$CIRCLE_TAG -extldflags '-static'" + - run: build-go-binaries --app-name terragrunt --dest-path bin --ld-flags "-s -w -X github.com/gruntwork-io/go-commons/version.Version=$CIRCLE_TAG -extldflags '-static'" - persist_to_workspace: root: . paths: [bin] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/Makefile new/terragrunt-0.80.3/Makefile --- old/terragrunt-0.80.2/Makefile 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/Makefile 2025-05-27 17:52:10.000000000 +0200 @@ -33,7 +33,7 @@ -o \( -type f -name '*.go' -print \) ) set -xe ;\ vtag_maybe_extra=$$(git describe --tags --abbrev=12 --dirty --broken) ;\ - go build -o $@ -ldflags "-X github.com/gruntwork-io/go-commons/version.Version=$${vtag_maybe_extra} -extldflags '-static'" . + go build -o $@ -ldflags "-s -w -X github.com/gruntwork-io/go-commons/version.Version=$${vtag_maybe_extra} -extldflags '-static'" . clean: rm -f terragrunt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/cli/commands/run/run.go new/terragrunt-0.80.3/cli/commands/run/run.go --- old/terragrunt-0.80.2/cli/commands/run/run.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/cli/commands/run/run.go 2025-05-27 17:52:10.000000000 +0200 @@ -5,6 +5,7 @@ "encoding/json" "fmt" "io" + "io/fs" "os" "path/filepath" "regexp" @@ -22,7 +23,6 @@ "github.com/gruntwork-io/go-commons/collections" "github.com/hashicorp/go-multierror" - "github.com/mattn/go-zglob" "maps" @@ -485,6 +485,10 @@ return err } else { terragruntOptions.Logger.Infof("Encountered an error eligible for retrying. Sleeping %v before retrying.\n", terragruntOptions.RetrySleepInterval) + // Reset the exit code to success so that we can retry the command + if exitCode := tf.DetailedExitCodeFromContext(ctx); exitCode != nil { + exitCode.ResetSuccess() + } select { case <-time.After(terragruntOptions.RetrySleepInterval): // try again @@ -532,44 +536,57 @@ return nil } +// CheckFolderContainsTerraformCode checks if the folder contains Terraform/OpenTofu code func CheckFolderContainsTerraformCode(terragruntOptions *options.TerragruntOptions) error { - files := []string{} - - hclFiles, err := zglob.Glob(terragruntOptions.WorkingDir + "/**/*.tf") - if err != nil { - return errors.New(err) - } + found := false - files = append(files, hclFiles...) + err := filepath.WalkDir(terragruntOptions.WorkingDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } - tofuHclFiles, err := zglob.Glob(terragruntOptions.WorkingDir + "/**/*.tofu") - if err != nil { - return errors.New(err) - } + if d.IsDir() { + return nil + } - files = append(files, tofuHclFiles...) + if isTofuFile(path) { + found = true - jsonFiles, err := zglob.Glob(terragruntOptions.WorkingDir + "/**/*.tf.json") - if err != nil { - return errors.New(err) - } + return filepath.SkipAll + } - files = append(files, jsonFiles...) + return nil + }) - tofuJSONFiles, err := zglob.Glob(terragruntOptions.WorkingDir + "/**/*.tofu.json") if err != nil { - return errors.New(err) + return err } - files = append(files, tofuJSONFiles...) - - if len(files) == 0 { + if !found { return errors.New(NoTerraformFilesFound(terragruntOptions.WorkingDir)) } return nil } +// isTofuFile checks if a given file is an OpenTofu/Terraform file +func isTofuFile(path string) bool { + suffixes := []string{ + ".tf", + ".tofu", + ".tf.json", + ".tofu.json", + } + + for _, suffix := range suffixes { + if strings.HasSuffix(path, suffix) { + return true + } + } + + return false +} + // Check that the specified Terraform code defines a backend { ... } block and return an error if doesn't func checkTerraformCodeDefinesBackend(opts *options.TerragruntOptions, backendType string) error { terraformBackendRegexp, err := regexp.Compile(fmt.Sprintf(`backend[[:blank:]]+"%s"`, backendType)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/config/config.go new/terragrunt-0.80.3/config/config.go --- old/terragrunt-0.80.2/config/config.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/config/config.go 2025-05-27 17:52:10.000000000 +0200 @@ -3,6 +3,7 @@ import ( "context" + "encoding/json" "fmt" "io" "net/url" @@ -104,11 +105,27 @@ writer.WithMsgSeparator(logMsgSeparator), ) - return []hclparse.Option{ + parseOpts := []hclparse.Option{ hclparse.WithDiagnosticsWriter(writer, opts.Logger.Formatter().DisabledColors()), - hclparse.WithFileUpdate(updateBareIncludeBlock), hclparse.WithLogger(opts.Logger), } + + strictControl := opts.StrictControls.Find(controls.BareInclude) + + // If we can't find the strict control, we're probably in a test + // where the option is being hand written. In that case, + // we'll assume we're not in strict mode. + if strictControl != nil { + strictControl.SuppressWarning() + + if err := strictControl.Evaluate(context.Background()); err != nil { + return parseOpts + } + } + + parseOpts = append(parseOpts, hclparse.WithFileUpdate(updateBareIncludeBlock)) + + return parseOpts } DefaultGenerateBlockIfDisabledValueStr = codegen.DisabledSkipStr @@ -1384,6 +1401,58 @@ return false } +// detectBareIncludeUsage detects if an identifier matching include.foo is used in the given HCL file. +// +// This is deprecated functionality, so we look for this to determine if we should throw an error or warning. +func detectBareIncludeUsage(file *hclparse.File) bool { + switch filepath.Ext(file.ConfigPath) { + case ".json": + var data map[string]interface{} + if err := json.Unmarshal(file.File.Bytes, &data); err != nil { + // If JSON is invalid, it can't be a valid bare include structure. + // The main parser will handle the invalid JSON error. + return false + } + + includeBlockUntyped, exists := data[MetadataInclude] + if !exists { + return false + } + + switch includeBlockTyped := includeBlockUntyped.(type) { + case map[string]interface{}: + // Delegate to the logic from include.go, which checks if the map + // represents a bare include block (e.g., only known include attributes). + return jsonIsIncludeBlock(includeBlockTyped) + case []interface{}: + // A bare include in JSON array form must have exactly one element, + // and that element must be an include block. + if len(includeBlockTyped) == 1 { + if firstElement, ok := includeBlockTyped[0].(map[string]interface{}); ok { + return jsonIsIncludeBlock(firstElement) + } + } + + return false + default: + return false + } + default: + body, ok := file.Body.(*hclsyntax.Body) + if !ok { + return false + } + + for _, block := range body.Blocks { + if block.Type == MetadataInclude && len(block.Labels) == 0 { + return true + } + } + + return false + } +} + // iamRoleCache - store for cached values of IAM roles var iamRoleCache = cache.NewCache[options.IAMRoleOptions](iamRoleCacheName) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/config/include.go new/terragrunt-0.80.3/config/include.go --- old/terragrunt-0.80.2/config/include.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/config/include.go 2025-05-27 17:52:10.000000000 +0200 @@ -804,6 +804,12 @@ // // Returns the updated contents, a boolean indicated whether anything changed, and an error (if any). func updateBareIncludeBlock(file *hclparse.File) error { + // To save us from doing a lot of extra work, first going to check to see if the file has a naked include, first. + // If it doesn't, we aren't going to bother fully parsing the file. + if !detectBareIncludeUsage(file) { + return nil + } + var ( codeWasUpdated bool content []byte diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs/_docs/04_reference/05-strict-mode.md new/terragrunt-0.80.3/docs/_docs/04_reference/05-strict-mode.md --- old/terragrunt-0.80.2/docs/_docs/04_reference/05-strict-mode.md 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs/_docs/04_reference/05-strict-mode.md 2025-05-27 17:52:10.000000000 +0200 @@ -132,6 +132,7 @@ - [terragrunt-prefix-env-vars](#terragrunt-prefix-env-vars) - [default-command](#default-command) - [cli-redesign](#cli-redesign) + - [bare-include](#bare-include) - [Control Categories](#control-categories) - [deprecated-commands](#deprecated-commands) - [deprecated-flags](#deprecated-flags) @@ -240,6 +241,12 @@ **Reason**: These commands have been deprecated in favor of more consistent and intuitive commands as part of the CLI redesign. For more information, see the [CLI Redesign Migration Guide](/docs/migrate/cli-redesign/). +### bare-include + +Throw an error when using a bare include. + +**Reason**: Backwards compatibility for supporting bare includes results in a performance penalty for Terragrunt, and deprecating support provides a significant performance improvement. For more information, see the [Bare Include Migration Guide](/docs/migrate/bare-include/). + ## Control Categories Certain strict controls are grouped into categories to make it easier to enable multiple strict controls at once. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs/_docs/06_migration_guides/03-cli-redesign.md new/terragrunt-0.80.3/docs/_docs/06_migration_guides/03-cli-redesign.md --- old/terragrunt-0.80.2/docs/_docs/06_migration_guides/03-cli-redesign.md 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs/_docs/06_migration_guides/03-cli-redesign.md 2025-05-27 17:52:10.000000000 +0200 @@ -5,7 +5,7 @@ categories_url: migrate excerpt: Migration guide to adopt changes from RFC 3445 tags: ["migration", "community"] -order: 503 +order: 603 nav_title: Documentation nav_title_link: /docs/ slug: cli-redesign diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs/_docs/06_migration_guides/04-terragrunt-stacks.md new/terragrunt-0.80.3/docs/_docs/06_migration_guides/04-terragrunt-stacks.md --- old/terragrunt-0.80.2/docs/_docs/06_migration_guides/04-terragrunt-stacks.md 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs/_docs/06_migration_guides/04-terragrunt-stacks.md 2025-05-27 17:52:10.000000000 +0200 @@ -5,7 +5,7 @@ categories_url: migrate excerpt: Migration guide to rewrite configurations to use Terragrunt Stacks tags: ["migration", "community"] -order: 503 +order: 604 nav_title: Documentation nav_title_link: /docs/ slug: terragrunt-stacks diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs/_docs/06_migration_guides/05-bare-include.md new/terragrunt-0.80.3/docs/_docs/06_migration_guides/05-bare-include.md --- old/terragrunt-0.80.2/docs/_docs/06_migration_guides/05-bare-include.md 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/docs/_docs/06_migration_guides/05-bare-include.md 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,56 @@ +--- +layout: collection-browser-doc +title: Bare Include +category: migrate +categories_url: migrate +excerpt: Migration guide to rewrite configurations to avoid using bare includes +tags: ["migration", "community"] +order: 605 +nav_title: Documentation +nav_title_link: /docs/ +slug: bare-include +--- + +## Migrating from bare includes + +The earliest form of include support in Terragrunt was a bare include. + +e.g. + +```hcl +include { + path = find_in_parent_folders("root.hcl") +} +``` + +Once Terragrunt supported the ability to define multiple includes, and to expose the values in includes as variables, users could optionally use named includes instead of a bare include. + +e.g. + +```hcl +include "root" { + path = find_in_parent_folders("root.hcl") +} +``` + +HCL parsing does not support the ability to parse HCL configuration and accept that a configuration block has zero or more attributes, so a workaround in Terragrunt internals was to parse the configuration, then rewrite it internally to avoid breaking backwards compatibility for bare includes. + +e.g. + +```hcl +include { + path = find_in_parent_folders("root.hcl") +} +``` + +becomes: + +```hcl +include "" { + path = find_in_parent_folders("root.hcl") +} +``` + +Especially on large projects, this extra work is not worth the performance penalty, and Terragrunt has deprecated support for bare includes. + +In a future version of Terragrunt, users will be required to use named includes for all includes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/content/docs/04-reference/02-cli/02-commands/hcl/0902-lint.md new/terragrunt-0.80.3/docs-starlight/src/content/docs/04-reference/02-cli/02-commands/hcl/0902-lint.md --- old/terragrunt-0.80.2/docs-starlight/src/content/docs/04-reference/02-cli/02-commands/hcl/0902-lint.md 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/content/docs/04-reference/02-cli/02-commands/hcl/0902-lint.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ ---- -title: lint -description: Lint Terragrunt HCL configuration. -slug: docs/reference/cli/commands/hcl/lint -sidebar: - order: 902 ---- - -<!-- This page is intentionally empty. Commands are defined in `src/pages/docs/reference/cli/commands/[...slug.astro] --> -<!-- This file is a placeholder to ensure that other pages see commands in their sidebars, and so that the data is accessible in the docs collection. --> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/content/docs/04-reference/03-strict-controls.mdx new/terragrunt-0.80.3/docs-starlight/src/content/docs/04-reference/03-strict-controls.mdx --- old/terragrunt-0.80.2/docs-starlight/src/content/docs/04-reference/03-strict-controls.mdx 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/content/docs/04-reference/03-strict-controls.mdx 2025-05-27 17:52:10.000000000 +0200 @@ -207,6 +207,12 @@ **Reason**: These commands have been deprecated in favor of more consistent and intuitive commands as part of the CLI redesign. For more information, see the [CLI Redesign Migration Guide](/docs/migrate/cli-redesign/). +### bare-include + +Throw an error when using a bare include. + +**Reason**: Backwards compatibility for supporting bare includes results in a performance penalty for Terragrunt, and deprecating support provides a significant performance improvement. For more information, see the [Bare Include Migration Guide](/docs/migrate/bare-include/). + ## Control Categories Certain strict controls are grouped into categories to make it easier to enable multiple strict controls at once. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/content/docs/06-migrate/05-bare-include.md new/terragrunt-0.80.3/docs-starlight/src/content/docs/06-migrate/05-bare-include.md --- old/terragrunt-0.80.2/docs-starlight/src/content/docs/06-migrate/05-bare-include.md 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/docs-starlight/src/content/docs/06-migrate/05-bare-include.md 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,59 @@ +--- +title: Bare Include +description: Migration guide to avoid using bare includes +slug: docs/migrate/bare-include +sidebar: + order: 5 +--- + +## Migrating from bare includes + +The earliest form of include support in Terragrunt was a bare include. + +e.g. + +```hcl +# terragrunt.hcl + +include { + path = find_in_parent_folders("root.hcl") +} +``` + +Once Terragrunt supported the ability to define multiple includes, and to expose the values in includes as variables, users could optionally use named includes instead of a bare include. + +e.g. + +```hcl +# terragrunt.hcl + +include "root" { + path = find_in_parent_folders("root.hcl") +} +``` + +HCL parsing does not support the ability to parse HCL configuration and accept that a configuration block has zero or more attributes, so a workaround in Terragrunt internals was to parse the configuration, then rewrite it internally to avoid breaking backwards compatibility for bare includes. + +e.g. + +```hcl +# terragrunt.hcl + +include { + path = find_in_parent_folders("root.hcl") +} +``` + +becomes: + +```hcl +# terragrunt.hcl + +include "" { + path = find_in_parent_folders("root.hcl") +} +``` + +Especially on large projects, this extra work is not worth the performance penalty, and Terragrunt has deprecated support for bare includes. + +In a future version of Terragrunt, users will be required to use named includes for all includes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/commands/hcl/lint.mdx new/terragrunt-0.80.3/docs-starlight/src/data/commands/hcl/lint.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/commands/hcl/lint.mdx 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/data/commands/hcl/lint.mdx 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ ---- -name: lint -path: hcl/lint -category: configuration -sidebar: - order: 902 -description: Lint Terragrunt HCL configuration. -usage: | - Lint Terragrunt HCL configuration. -examples: - - description: Lint all HCL files in the current directory. - code: | - terragrunt hcl lint - - description: Throw an error if any variables are not set by the module a unit provisions. - code: | - terragrunt hcl lint --inputs - - description: Throw an error if any inputs are set that are not defined in the module. - code: | - terragrunt hcl lint --inputs --strict - -flags: - - hcl-lint-inputs - - hcl-lint-strict ---- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/commands/hcl/validate.mdx new/terragrunt-0.80.3/docs-starlight/src/data/commands/hcl/validate.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/commands/hcl/validate.mdx 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/data/commands/hcl/validate.mdx 2025-05-27 17:52:10.000000000 +0200 @@ -14,4 +14,6 @@ flags: - hcl-validate-json - hcl-validate-show-config-path + - hcl-validate-inputs + - hcl-validate-strict --- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-lint-inputs.mdx new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-lint-inputs.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-lint-inputs.mdx 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-lint-inputs.mdx 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ ---- -name: inputs -description: Validate that all variables are set by the module a unit provisions. -type: bool -env: - - TG_INPUTS ---- - -When enabled, Terragrunt will validate that all variables are set by the module a unit provisions. - -Example: - -```bash -terragrunt hcl lint --inputs -``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-lint-strict.mdx new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-lint-strict.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-lint-strict.mdx 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-lint-strict.mdx 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ ---- -name: strict -description: Throw an error if any inputs are set that are not defined in the module that a unit provisions. -type: bool -env: - - TG_STRICT ---- - -When enabled, Terragrunt will throw an error if any inputs are set that are not defined in the module that a unit provisions. - -Example: - -```bash -terragrunt hcl lint --inputs --strict -``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-validate-inputs.mdx new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-validate-inputs.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-validate-inputs.mdx 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-validate-inputs.mdx 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,15 @@ +--- +name: inputs +description: Validate that all variables are set by the module a unit provisions. +type: bool +env: + - TG_INPUTS +--- + +When enabled, Terragrunt will validate that all variables are set by the module a unit provisions. + +Example: + +```bash +terragrunt hcl validate --inputs +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-validate-strict.mdx new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-validate-strict.mdx --- old/terragrunt-0.80.2/docs-starlight/src/data/flags/hcl-validate-strict.mdx 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/docs-starlight/src/data/flags/hcl-validate-strict.mdx 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,15 @@ +--- +name: strict +description: Throw an error if any inputs are set that are not defined in the module that a unit provisions. +type: bool +env: + - TG_STRICT +--- + +When enabled, Terragrunt will throw an error if any inputs are set that are not defined in the module that a unit provisions. + +Example: + +```bash +terragrunt hcl validate --inputs --strict +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/internal/strict/controls/controls.go new/terragrunt-0.80.3/internal/strict/controls/controls.go --- old/terragrunt-0.80.2/internal/strict/controls/controls.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/internal/strict/controls/controls.go 2025-05-27 17:52:10.000000000 +0200 @@ -46,6 +46,9 @@ // CLIRedesign is the control that prevents the use of commands deprecated as part of the CLI Redesign. CLIRedesign = "cli-redesign" + + // BareInclude is the control that prevents the use of the `include` block without a label. + BareInclude = "bare-include" ) //nolint:lll @@ -173,6 +176,12 @@ Description: "Prevents the deprecated validate-all command from being used.", Category: stageCategory, }, + &Control{ + Name: BareInclude, + Description: "Prevents the use of the `include` block without a label.", + Category: stageCategory, + Error: errors.New("Using an `include` block without a label is deprecated. Please use the `include` block with a label instead."), + }, } return controls.Sort() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/pkg/log/format/format.go new/terragrunt-0.80.3/pkg/log/format/format.go --- old/terragrunt-0.80.2/pkg/log/format/format.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/pkg/log/format/format.go 2025-05-27 17:52:10.000000000 +0200 @@ -8,8 +8,8 @@ "strings" "github.com/gruntwork-io/terragrunt/internal/errors" - . "github.com/gruntwork-io/terragrunt/pkg/log/format/options" //nolint:stylecheck,revive - . "github.com/gruntwork-io/terragrunt/pkg/log/format/placeholders" //nolint:stylecheck,revive + . "github.com/gruntwork-io/terragrunt/pkg/log/format/options" //nolint:revive + . "github.com/gruntwork-io/terragrunt/pkg/log/format/placeholders" //nolint:revive ) const ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/test/fixtures/strict-bare-include/parent.hcl new/terragrunt-0.80.3/test/fixtures/strict-bare-include/parent.hcl --- old/terragrunt-0.80.2/test/fixtures/strict-bare-include/parent.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/test/fixtures/strict-bare-include/parent.hcl 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,3 @@ +locals { + greeting = "hello" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/test/fixtures/strict-bare-include/terragrunt.hcl new/terragrunt-0.80.3/test/fixtures/strict-bare-include/terragrunt.hcl --- old/terragrunt-0.80.2/test/fixtures/strict-bare-include/terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.80.3/test/fixtures/strict-bare-include/terragrunt.hcl 2025-05-27 17:52:10.000000000 +0200 @@ -0,0 +1,3 @@ +include { + path = "parent.hcl" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/test/integration_docs_aws_test.go new/terragrunt-0.80.3/test/integration_docs_aws_test.go --- old/terragrunt-0.80.2/test/integration_docs_aws_test.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/test/integration_docs_aws_test.go 2025-05-27 17:52:10.000000000 +0200 @@ -33,13 +33,11 @@ tmpEnvPath := helpers.CopyEnvironment(t, stepPath) rootPath := util.JoinPath(tmpEnvPath, stepPath) - t.Cleanup(func() { - helpers.DeleteS3Bucket(t, region, s3BucketName) - }) - t.Cleanup(func() { + defer helpers.DeleteS3Bucket(t, region, s3BucketName) + defer func() { _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt destroy -auto-approve --non-interactive --working-dir "+rootPath) require.NoError(t, err) - }) + }() rootTerragruntConfigPath := util.JoinPath(rootPath, config.DefaultTerragruntConfigPath) helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region) @@ -59,13 +57,11 @@ tmpEnvPath := helpers.CopyEnvironment(t, stepPath) rootPath := util.JoinPath(tmpEnvPath, stepPath) - t.Cleanup(func() { - helpers.DeleteS3Bucket(t, region, s3BucketName) - }) - t.Cleanup(func() { + defer helpers.DeleteS3Bucket(t, region, s3BucketName) + defer func() { _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve") require.NoError(t, err) - }) + }() rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl") helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region) @@ -85,13 +81,11 @@ tmpEnvPath := helpers.CopyEnvironment(t, stepPath) rootPath := util.JoinPath(tmpEnvPath, stepPath) - t.Cleanup(func() { - helpers.DeleteS3Bucket(t, region, s3BucketName) - }) - t.Cleanup(func() { + defer helpers.DeleteS3Bucket(t, region, s3BucketName) + defer func() { _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve") require.NoError(t, err) - }) + }() rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl") helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region) @@ -111,13 +105,11 @@ tmpEnvPath := helpers.CopyEnvironment(t, stepPath) rootPath := util.JoinPath(tmpEnvPath, stepPath) - t.Cleanup(func() { - helpers.DeleteS3Bucket(t, region, s3BucketName) - }) - t.Cleanup(func() { + defer helpers.DeleteS3Bucket(t, region, s3BucketName) + defer func() { _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve") require.NoError(t, err) - }) + }() rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl") helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region) @@ -137,13 +129,11 @@ tmpEnvPath := helpers.CopyEnvironment(t, stepPath) rootPath := util.JoinPath(tmpEnvPath, stepPath) - t.Cleanup(func() { - helpers.DeleteS3Bucket(t, region, s3BucketName) - }) - t.Cleanup(func() { + defer helpers.DeleteS3Bucket(t, region, s3BucketName) + defer func() { _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt run --all --non-interactive --working-dir "+rootPath+" -- destroy -auto-approve") require.NoError(t, err) - }) + }() rootTerragruntConfigPath := util.JoinPath(rootPath, "root.hcl") helpers.CopyTerragruntConfigAndFillPlaceholders(t, rootTerragruntConfigPath, rootTerragruntConfigPath, s3BucketName, "not-used", region) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/test/integration_strict_test.go new/terragrunt-0.80.3/test/integration_strict_test.go --- old/terragrunt-0.80.2/test/integration_strict_test.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/test/integration_strict_test.go 2025-05-27 17:52:10.000000000 +0200 @@ -10,6 +10,10 @@ "github.com/stretchr/testify/require" ) +const ( + testFixtureStrictBareInclude = "fixtures/strict-bare-include" +) + // TestStrictMode uses globally mutated state to determine if strict mode has already // been triggered, so we don't run it in parallel. // @@ -130,3 +134,62 @@ }) } } + +// TestBareIncludeStrictMode uses globally mutated state to determine if strict mode has already +// been triggered, so we don't run it in parallel. +// +//nolint:paralleltest,tparallel +func TestBareIncludeStrictMode(t *testing.T) { + helpers.CleanupTerraformFolder(t, testFixtureStrictBareInclude) + + testCases := []struct { + expectedError error + name string + controls []string + strictMode bool + }{ + { + name: "bare include with no strict mode or control", + controls: []string{}, + strictMode: false, + expectedError: nil, + }, + { + name: "bare include with bare-include strict control", + controls: []string{"bare-include"}, + strictMode: false, + expectedError: errors.New("Missing name for include; All include blocks must have 1 labels (name)."), + }, + { + name: "bare include with strict mode", + controls: []string{}, + strictMode: true, + expectedError: errors.New("Missing name for include; All include blocks must have 1 labels (name)."), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tmpEnvPath := helpers.CopyEnvironment(t, testFixtureStrictBareInclude) + rootPath := util.JoinPath(tmpEnvPath, testFixtureStrictBareInclude) + + args := "init --non-interactive --log-level trace --working-dir " + rootPath + if tc.strictMode { + args = "--strict-mode " + args + } + + for _, control := range tc.controls { + args = " --strict-control " + control + " " + args + } + + _, _, err := helpers.RunTerragruntCommandWithOutput(t, "terragrunt "+args) + + if tc.expectedError != nil { + require.Error(t, err) + require.ErrorContains(t, err, tc.expectedError.Error()) + } else { + require.NoError(t, err) + } + }) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/test/integration_test.go new/terragrunt-0.80.3/test/integration_test.go --- old/terragrunt-0.80.2/test/integration_test.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/test/integration_test.go 2025-05-27 17:52:10.000000000 +0200 @@ -233,6 +233,32 @@ assert.Equal(t, 2, exitCode.Get()) } +func TestDetailedExitCodeChangesUnit(t *testing.T) { + t.Parallel() + + testFixturePath := filepath.Join(testFixtureDetailedExitCode, "changes") + + helpers.CleanupTerraformFolder(t, testFixturePath) + tmpEnvPath := helpers.CopyEnvironment(t, testFixturePath) + rootPath := util.JoinPath(tmpEnvPath, testFixturePath) + ctx := t.Context() + + _, _, err := helpers.RunTerragruntCommandWithOutputWithContext(t, ctx, "terragrunt run --all --log-level trace --non-interactive --working-dir "+rootPath+" -- apply") + require.NoError(t, err) + + // delete example.txt from rootPath/app1 to have changes in one unit + err = os.Remove(filepath.Join(rootPath, "app1", "example.txt")) + require.NoError(t, err) + + // check that the exit code is 2 when there are changes in one unit + var exitCode tf.DetailedExitCode + ctx = tf.ContextWithDetailedExitCode(ctx, &exitCode) + + _, _, err = helpers.RunTerragruntCommandWithOutputWithContext(t, ctx, "terragrunt run --all --log-level trace --non-interactive --working-dir "+rootPath+" -- plan -detailed-exitcode") + require.NoError(t, err) + assert.Equal(t, 2, exitCode.Get()) +} + func TestDetailedExitCodeFailOnFirstRun(t *testing.T) { t.Parallel() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/tf/detailed_exitcode.go new/terragrunt-0.80.3/tf/detailed_exitcode.go --- old/terragrunt-0.80.2/tf/detailed_exitcode.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/tf/detailed_exitcode.go 2025-05-27 17:52:10.000000000 +0200 @@ -4,13 +4,18 @@ "sync" ) +const ( + DetailedExitCodeSuccess = 0 + DetailedExitCodeError = 1 +) + // DetailedExitCode is the TF detailed exit code. https://opentofu.org/docs/cli/commands/plan/ type DetailedExitCode struct { Code int mu sync.RWMutex } -// Get returns exit code. +// Get return exit code. func (coder *DetailedExitCode) Get() int { coder.mu.RLock() defer coder.mu.RUnlock() @@ -18,13 +23,30 @@ return coder.Code } +// ResetSuccess resets the exit code to success (0). +func (coder *DetailedExitCode) ResetSuccess() { + coder.mu.Lock() + defer coder.mu.Unlock() + + coder.Code = DetailedExitCodeSuccess +} + // Set updates the exit code following OpenTofu's exit code convention: // - 0 = Success // - 1 = Error // - 2 = Success with changes pending +// The method only updates if: +// - The current code is not 1 (error state) +// - The new code is greater than current OR equals 1 func (coder *DetailedExitCode) Set(newCode int) { coder.mu.Lock() defer coder.mu.Unlock() - coder.Code = newCode + if coder.Code == DetailedExitCodeError { + return + } + + if coder.Code < newCode || newCode == DetailedExitCodeError { + coder.Code = newCode + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.80.2/tf/run_cmd.go new/terragrunt-0.80.3/tf/run_cmd.go --- old/terragrunt-0.80.2/tf/run_cmd.go 2025-05-22 19:56:25.000000000 +0200 +++ new/terragrunt-0.80.3/tf/run_cmd.go 2025-05-27 17:52:10.000000000 +0200 @@ -74,10 +74,6 @@ if code != 1 { return output, nil } - } else { - if exitCode := DetailedExitCodeFromContext(ctx); exitCode != nil { - exitCode.Set(0) - } } return output, err ++++++ terragrunt.obsinfo ++++++ --- /var/tmp/diff_new_pack.dzsbuY/_old 2025-05-30 17:27:41.101121003 +0200 +++ /var/tmp/diff_new_pack.dzsbuY/_new 2025-05-30 17:27:41.105121169 +0200 @@ -1,5 +1,5 @@ name: terragrunt -version: 0.80.2 -mtime: 1747936585 -commit: e629ad9a755991b9a4e2eca3e6636b6e5095f8c8 +version: 0.80.3 +mtime: 1748361130 +commit: e000a44f60aaeb19cd07676b14f82a47d0ad494e ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/terragrunt/vendor.tar.gz /work/SRC/openSUSE:Factory/.terragrunt.new.25440/vendor.tar.gz differ: char 13, line 1