Skip to content

Commit

Permalink
fix #2072 make sure the generated code is formatted before writing …
Browse files Browse the repository at this point in the history
…it to a file. (#3917)
  • Loading branch information
wakeful authored Feb 24, 2025
1 parent be02d45 commit 4a36f3f
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 3 deletions.
26 changes: 23 additions & 3 deletions codegen/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsimple"

"github.com/hashicorp/hcl/v2/hclwrite"
ctyjson "github.com/zclconf/go-cty/cty/json"

Expand Down Expand Up @@ -87,6 +86,7 @@ type GenerateConfig struct {
Contents string `cty:"contents"`
DisableSignature bool `cty:"disable_signature"`
Disable bool `cty:"disable"`
HclFmt *bool `cty:"hcl_fmt"`
}

// WriteToFile will generate a new file at the given target path with the given contents. If a file already exists at
Expand Down Expand Up @@ -135,10 +135,30 @@ func WriteToFile(terragruntOptions *options.TerragruntOptions, basePath string,
prefix = fmt.Sprintf("%s%s\n", config.CommentPrefix, TerragruntGeneratedSignature)
}

contentsToWrite := fmt.Sprintf("%s%s", prefix, config.Contents)
fmtGeneratedCode := false

if config.HclFmt == nil {
var fmtExt = map[string]struct{}{
".hcl": {},
".tf": {},
".tofu": {},
}

ext := filepath.Ext(config.Path)
if _, ok := fmtExt[ext]; ok {
fmtGeneratedCode = true
}
} else {
fmtGeneratedCode = *config.HclFmt
}

contentsToWrite := []byte(fmt.Sprintf("%s%s", prefix, config.Contents))
if fmtGeneratedCode {
contentsToWrite = hclwrite.Format(contentsToWrite)
}

const ownerWriteGlobalReadPerms = 0644
if err := os.WriteFile(targetPath, []byte(contentsToWrite), ownerWriteGlobalReadPerms); err != nil {
if err := os.WriteFile(targetPath, contentsToWrite, ownerWriteGlobalReadPerms); err != nil {
return errors.New(err)
}

Expand Down
76 changes: 76 additions & 0 deletions codegen/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package codegen_test
import (
"bytes"
"fmt"
"os"
"testing"

"github.com/gruntwork-io/terragrunt/codegen"
Expand Down Expand Up @@ -144,6 +145,81 @@ func TestRemoteStateConfigToTerraformCode(t *testing.T) {
}
}

func TestFmtGeneratedFile(t *testing.T) {
t.Parallel()

testDir := t.TempDir()

bTrue := true
bFalse := false

tc := []struct {
name string
disabled bool
fmt *bool
path string
contents string
expected string
ifExists codegen.GenerateConfigExists
}{
{
name: "fmt-simple-hcl-file",
fmt: &bTrue,
path: fmt.Sprintf("%s/%s", testDir, "fmt_simple.hcl"),
contents: "variable \"msg\"{\ntype=string\n default=\"hello\"\n}\n",
expected: "variable \"msg\" {\n type = string\n default = \"hello\"\n}\n",
ifExists: codegen.ExistsError,
},
{
name: "fmt-hcl-file-by-default",
path: fmt.Sprintf("%s/%s", testDir, "fmt_hcl_file_by_default.hcl"),
contents: "variable \"msg\"{\ntype=string\n default=\"hello\"\n}\n",
expected: "variable \"msg\" {\n type = string\n default = \"hello\"\n}\n",
ifExists: codegen.ExistsError,
},
{
name: "ignore-hcl-fmt",
fmt: &bFalse,
path: fmt.Sprintf("%s/%s", testDir, "ignore_hcl_fmt.hcl"),
contents: "variable \"msg\"{\ntype=string\n default=\"hello\"\n}\n",
expected: "variable \"msg\"{\ntype=string\n default=\"hello\"\n}\n",
ifExists: codegen.ExistsError,
},
}

for _, tt := range tc {
tt := tt

t.Run(tt.name, func(t *testing.T) {
t.Parallel()

config := codegen.GenerateConfig{
Path: tt.path,
IfExists: tt.ifExists,
CommentPrefix: "",
DisableSignature: true,
Contents: tt.contents,
Disable: tt.disabled,
HclFmt: tt.fmt,
}

opts, err := options.NewTerragruntOptionsForTest("mock-path-for-test.hcl")
require.NoError(t, err)
assert.NotNil(t, opts)

err = codegen.WriteToFile(opts, "", config)
require.NoError(t, err)

assert.True(t, util.FileExists(tt.path))

fileContent, err := os.ReadFile(tt.path)
require.NoError(t, err)

assert.Equal(t, tt.expected, string(fileContent))
})
}
}

func TestGenerateDisabling(t *testing.T) {
t.Parallel()

Expand Down
2 changes: 2 additions & 0 deletions docs/_docs/04_reference/04-config-blocks-and-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,8 @@ The `generate` block supports the following arguments:
`false`. Optional.
- `contents` (attribute): The contents of the generated file.
- `disable` (attribute): Disables this generate block.
- `hcl_fmt` (attribute): Unless disabled (set to `false`), files with `.hcl`, `.tf`, and `.tofu` extensions will be formatted before being written to disk.
If explicitly set to `true`, formatting will be applied to the generated files.

Example:

Expand Down

0 comments on commit 4a36f3f

Please # to comment.