Skip to content

Commit c55e262

Browse files
authored
Merge pull request #660 from leinardi/strict-booleans
Add strict-booleans node style
2 parents f6a07e7 + a1fc87b commit c55e262

File tree

2 files changed

+141
-70
lines changed

2 files changed

+141
-70
lines changed

cft/format/format_test.go

Lines changed: 136 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -801,75 +801,86 @@ Outputs {
801801
}
802802
}
803803

804-
func TestAmbiguousScalarOn(t *testing.T) {
805-
input := `
806-
Resources:
807-
MyResource:
808-
Type: AWS::RDS::DBClusterParameterGroup
809-
Properties:
810-
Parameters:
811-
require_secure_transport: "ON"
812-
`
813-
// We expect the ambiguous value "ON" to remain quoted in the output.
814-
expected := `Resources:
815-
MyResource:
816-
Type: AWS::RDS::DBClusterParameterGroup
817-
Properties:
818-
Parameters:
819-
require_secure_transport: "ON"
820-
`
821-
template, err := parse.String(input)
822-
if err != nil {
823-
t.Fatal(err)
824-
}
804+
func TestAmbiguousScalars_StrictBooleans_On(t *testing.T) {
805+
// Save the original style
806+
originalStyle := format.NodeStyle
807+
// Restore after test completes
808+
defer func() {
809+
format.NodeStyle = originalStyle
810+
}()
825811

826-
actual := format.String(template, format.Options{Unsorted: true})
827-
if d := cmp.Diff(strings.TrimSpace(expected), strings.TrimSpace(actual)); d != "" {
828-
t.Fatalf("Diff: %s", d)
829-
}
830-
}
812+
// Override for this test only
813+
format.NodeStyle = "strict-booleans"
831814

832-
func TestAmbiguousScalarsInParameters(t *testing.T) {
833815
input := `
834-
Parameters:
835-
Param1:
836-
Default: "ON"
837-
Param2:
838-
Default: "OFF"
839-
Param3:
840-
Default: "Yes"
841-
Param4:
842-
Default: "No"
843-
Param5:
844-
Default: "True"
845-
Param6:
846-
Default: "False"
847-
Param7:
848-
Default: "Maybe"
816+
Param1:
817+
Default: "ON"
818+
Param2:
819+
Default: "OFF"
820+
Param3:
821+
Default: "Yes"
822+
Param4:
823+
Default: "No"
824+
Param5:
825+
Default: "True"
826+
Param6:
827+
Default: "False"
828+
Param7:
829+
Default: Maybe
830+
Param8:
831+
Default: ON
832+
Param9:
833+
Default: OFF
834+
Param10:
835+
Default: Yes
836+
Param11:
837+
Default: No
838+
Param12:
839+
Default: True
840+
Param13:
841+
Default: False
849842
`
850843
// The ambiguous values (Param1 through Param6) should be rendered with quotes,
851844
// while a non-ambiguous value (Param7) may be unquoted.
852-
expected := `Parameters:
853-
Param1:
854-
Default: "ON"
845+
expected := `
846+
Param1:
847+
Default: "ON"
848+
849+
Param2:
850+
Default: "OFF"
851+
852+
Param3:
853+
Default: "Yes"
854+
855+
Param4:
856+
Default: "No"
857+
858+
Param5:
859+
Default: "True"
855860
856-
Param2:
857-
Default: "OFF"
861+
Param6:
862+
Default: "False"
858863
859-
Param3:
860-
Default: "Yes"
864+
Param7:
865+
Default: Maybe
861866
862-
Param4:
863-
Default: "No"
867+
Param8:
868+
Default: "ON"
864869
865-
Param5:
866-
Default: "True"
870+
Param9:
871+
Default: "OFF"
867872
868-
Param6:
869-
Default: "False"
873+
Param10:
874+
Default: "Yes"
870875
871-
Param7:
872-
Default: Maybe
876+
Param11:
877+
Default: "No"
878+
879+
Param12:
880+
Default: True
881+
882+
Param13:
883+
Default: False
873884
`
874885
template, err := parse.String(input)
875886
if err != nil {
@@ -882,18 +893,76 @@ Parameters:
882893
}
883894
}
884895

885-
func TestNonAmbiguousScalar(t *testing.T) {
896+
func TestAmbiguousScalars_StrictBooleans_Off(t *testing.T) {
886897
input := `
887-
Resources:
888-
MyResource:
889-
Properties:
890-
example_value: "OnX"
898+
Param1:
899+
Default: "ON"
900+
Param2:
901+
Default: "OFF"
902+
Param3:
903+
Default: "Yes"
904+
Param4:
905+
Default: "No"
906+
Param5:
907+
Default: "True"
908+
Param6:
909+
Default: "False"
910+
Param7:
911+
Default: Maybe
912+
Param8:
913+
Default: ON
914+
Param9:
915+
Default: OFF
916+
Param10:
917+
Default: Yes
918+
Param11:
919+
Default: No
920+
Param12:
921+
Default: True
922+
Param13:
923+
Default: False
891924
`
892-
// Since "OnX" is not an ambiguous token, it can be rendered without quotes.
893-
expected := `Resources:
894-
MyResource:
895-
Properties:
896-
example_value: OnX
925+
// The ambiguous values (Param1 through Param6) should be rendered with quotes,
926+
// while a non-ambiguous value (Param7) may be unquoted.
927+
expected := `
928+
Param1:
929+
Default: ON
930+
931+
Param2:
932+
Default: OFF
933+
934+
Param3:
935+
Default: Yes
936+
937+
Param4:
938+
Default: No
939+
940+
Param5:
941+
Default: "True"
942+
943+
Param6:
944+
Default: "False"
945+
946+
Param7:
947+
Default: Maybe
948+
949+
Param8:
950+
Default: ON
951+
952+
Param9:
953+
Default: OFF
954+
955+
Param10:
956+
Default: Yes
957+
958+
Param11:
959+
Default: No
960+
961+
Param12:
962+
Default: True
963+
964+
Param13:
965+
Default: False
897966
`
898967
template, err := parse.String(input)
899968
if err != nil {

cft/format/transform.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,16 @@ func formatNode(n *yaml.Node) *yaml.Node {
119119
if n.Kind == yaml.ScalarNode {
120120
n.Style = yaml.DoubleQuotedStyle
121121
}
122-
case "":
123-
// Default style for consistent formatting:
124-
// Force double quotes on ambiguous scalar strings.
122+
case "strict-booleans":
123+
// Enforce YAML 1.2 behavior: Only `true` and `false` are booleans, all others are strings
125124
if n.Kind == yaml.ScalarNode && n.Tag == "!!str" && isAmbiguousScalar(n.Value) {
126125
n.Style = yaml.DoubleQuotedStyle
127126
} else {
128127
n.Style = 0
129128
}
129+
case "":
130+
// Default style for consistent formatting
131+
n.Style = 0
130132
default:
131133
panic("invalid --node-style: " + NodeStyle)
132134
}

0 commit comments

Comments
 (0)