Skip to content

Commit 39f0716

Browse files
authored
Merge pull request #221 from oferchen/codex/refactor-terraform.go-for-attribute-sorting
Sort terraform blocks and required provider entries
2 parents e89421d + 19ff5f4 commit 39f0716

File tree

5 files changed

+117
-5
lines changed

5 files changed

+117
-5
lines changed

internal/align/terraform.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package align
33

44
import (
55
"sort"
6+
"strings"
67

78
"github.com/hashicorp/hcl/v2/hclwrite"
89
)
@@ -11,13 +12,52 @@ type terraformStrategy struct{}
1112

1213
func (terraformStrategy) Name() string { return "terraform" }
1314

15+
// Align orders attributes and nested blocks within a terraform block. Attributes
16+
// are sorted alphabetically. Nested blocks are sorted by type and labels while
17+
// preserving the ordering of their contents. If a required_providers block is
18+
// present, the provider entries inside it are also sorted alphabetically.
1419
func (terraformStrategy) Align(block *hclwrite.Block, _ *Options) error {
15-
attrs := block.Body().Attributes()
20+
body := block.Body()
21+
22+
// Sort provider entries within required_providers blocks
23+
for _, nb := range body.Blocks() {
24+
if nb.Type() == "required_providers" {
25+
attrs := nb.Body().Attributes()
26+
names := make([]string, 0, len(attrs))
27+
for name := range attrs {
28+
names = append(names, name)
29+
}
30+
sort.Strings(names)
31+
if err := reorderBlock(nb, names); err != nil {
32+
return err
33+
}
34+
}
35+
}
36+
37+
// Order top-level blocks by type then labels
38+
blocks := body.Blocks()
39+
sort.SliceStable(blocks, func(i, j int) bool {
40+
bi, bj := blocks[i], blocks[j]
41+
if bi.Type() != bj.Type() {
42+
return bi.Type() < bj.Type()
43+
}
44+
return strings.Join(bi.Labels(), "\x00") < strings.Join(bj.Labels(), "\x00")
45+
})
46+
for _, b := range body.Blocks() {
47+
body.RemoveBlock(b)
48+
}
49+
for _, b := range blocks {
50+
body.AppendBlock(b)
51+
}
52+
53+
// Gather and order attributes
54+
attrs := body.Attributes()
1655
names := make([]string, 0, len(attrs))
1756
for name := range attrs {
1857
names = append(names, name)
1958
}
2059
sort.Strings(names)
60+
2161
return reorderBlock(block, names)
2262
}
2363

tests/cases/terraform/aligned.tf

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
terraform {
2-
backend = "local"
32
required_version = ">= 1.0"
3+
4+
backend "s3" {
5+
region = "us-east-1"
6+
}
7+
8+
cloud {
9+
organization = "hashicorp"
10+
}
11+
12+
required_providers {
13+
aws = {
14+
version = "~> 4.0"
15+
source = "hashicorp/aws"
16+
}
17+
random = {
18+
source = "hashicorp/random"
19+
version = "~> 3.0"
20+
}
21+
}
422
}

tests/cases/terraform/fmt.tf

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
terraform {
2+
cloud {
3+
organization = "hashicorp"
4+
}
5+
26
required_version = ">= 1.0"
3-
backend = "local"
7+
8+
backend "s3" {
9+
region = "us-east-1"
10+
}
11+
12+
required_providers {
13+
random = {
14+
source = "hashicorp/random"
15+
version = "~> 3.0"
16+
}
17+
aws = {
18+
version = "~> 4.0"
19+
source = "hashicorp/aws"
20+
}
21+
}
422
}

tests/cases/terraform/in.tf

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
terraform {
2+
cloud {
3+
organization = "hashicorp"
4+
}
5+
26
required_version = ">= 1.0"
3-
backend = "local"
7+
8+
backend "s3" {
9+
region = "us-east-1"
10+
}
11+
12+
required_providers {
13+
random = {
14+
source = "hashicorp/random"
15+
version = "~> 3.0"
16+
}
17+
aws = {
18+
version = "~> 4.0"
19+
source = "hashicorp/aws"
20+
}
21+
}
422
}

tests/cases/terraform/out.tf

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
terraform {
2-
backend = "local"
32
required_version = ">= 1.0"
3+
4+
backend "s3" {
5+
region = "us-east-1"
6+
}
7+
8+
cloud {
9+
organization = "hashicorp"
10+
}
11+
12+
required_providers {
13+
aws = {
14+
version = "~> 4.0"
15+
source = "hashicorp/aws"
16+
}
17+
random = {
18+
source = "hashicorp/random"
19+
version = "~> 3.0"
20+
}
21+
}
422
}

0 commit comments

Comments
 (0)