Repository: aws-cloudformation/rain
Pull request #165 (2023-06-29 15:14:04)

fix: close multi-line values even if it returns to the same indent
*Issue #161

Cannot close multi-line values when startMultilineIndent is 0.
https://github.com/aws-cloudformation/rain/blob/2d9825b646ff73e0725f109aec787faebc880069/cft/format/format.go#L66


```
$ rain fmt template.yaml
AWSTemplateFormatVersion: "2010-09-09"

Description: |
  Test template
Parameters:
  ApiNames:
    Type: String
Resources:
  DashboardTest:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardName: Test
      DashboardBody: Test
```


*Description of changes:*

Close multi-line values even if it returns to the same indent

- add: unit-test for multi-line value
- fix: terminate multi-line values even if it returns to the same indent

before
```
$ go test ./cft/format/
--- FAIL: TestFormatDefault (0.01s)
    format_test.go:395:   strings.Join({
          	"Description: |\n  An example template for testing rain fmt comman",
          	"d.\n",
        - 	"\n",
          	"Parameters:\n  Name:\n    Type: String\n",
        - 	"\n",
          	"Rules:\n  Rule1:\n    RuleCondition: !Equals\n      - !Ref Environm",
          	"ent\n      - test\n    Assertions:\n      - Assert:\n          Fn::C",
          	"ontains:\n            - - a1.medium\n            - !Ref InstanceTy",
          	"pe\n",
        - 	"\n",
          	"# Multiline comment\n# starting at indent 0\nResources:\n  Bucket2:",
          	"\n    Type: AWS::S3::Bucket\n    Properties:\n      BucketName: !Re",
          	"f Name # Ref: comment",
        - 	"\n",
          	"\n  Bucket1:\n    Type: AWS::S3::Bucket\n    Properties:\n      Buck",
          	"etName: !Sub ${Bucket2}-newer",
        - 	"\n",
          	"\n  Func1:\n    Type: AWS::Lambda::Function\n    Properties:\n      ",
          	"Role: !Sub \"arn:aws:iam::${AWS::AccountID}:role/lambda-basic\"\n  ",
          	"    Runtime: python3.7\n      Handler: index.handler\n      Code:\n",
          	`        ZipFile: "import boto3\n\ndef handler: \n  \"\"\"Example`,
          	`.\"\"\"\n\n  print('hello')\n"`,
        - 	"\n",
          	"\n  Instance1:\n    Type: AWS::EC2::Instance\n    Properties:\n     ",
          	" UserData: !Base64\n        Fn::Sub:\n          - |\n            #!",
          	... // 229 identical bytes
          }, "")
    format_test.go:395:   strings.Join({
          	... // 95 identical bytes
          	"    Value: !GetAtt Bucket2.Arn # GetAtt comment Arn comment\n\nDes",
          	"cription: |\n  An example template for testing rain fmt command.\n",
        - 	"\n",
          	"# Multiline comment\n# starting at indent 0\nResources:\n  Bucket2:",
          	"\n    Properties:\n      BucketName: !Ref Name # Ref: comment\n    ",
          	"Type: AWS::S3::Bucket\n",
        - 	"\n",
          	"  Bucket1:\n    Type: AWS::S3::Bucket\n    Properties:\n      Bucke",
          	"tName: !Sub ${Bucket2}-newer",
        - 	"\n",
          	"\n  Func1:\n    Type: AWS::Lambda::Function\n    Properties:\n      ",
          	"Role: !Sub \"arn:aws:iam::${AWS::AccountID}:role/lambda-basic\"\n  ",
          	"    Runtime: python3.7\n      Handler: index.handler\n      Code:\n",
          	`        ZipFile: "import boto3\n\ndef handler: \n  \"\"\"Example`,
          	`.\"\"\"\n\n  print('hello')\n"`,
        - 	"\n",
          	"\n  Instance1:\n    Type: AWS::EC2::Instance\n    Properties:\n     ",
          	" UserData: !Base64\n        Fn::Sub:\n          - |\n            #!",
          	... // 307 identical bytes
          }, "")
FAIL
FAIL	github.com/aws-cloudformation/rain/cft/format	0.665s
FAIL
```

after
```
$ go test ./cft/format/
ok  	github.com/aws-cloudformation/rain/cft/format
```

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.



Patch:
diff --git a/cft/format/format.go b/cft/format/format.go
index 7dbd08bd..369410b4 100644
--- a/cft/format/format.go
+++ b/cft/format/format.go
@@ -63,7 +63,7 @@ func String(t cft.Template, opt Options) string {
 		if startMultilineIndent > -1 {
 			// Note: len(part) == 0 means empty line without indentation
 			// https://github.com/aws-cloudformation/rain/issues/126
-			if indent < startMultilineIndent && len(part) != 0 {
+			if indent <= startMultilineIndent && len(part) != 0 {
 				startMultilineIndent = -1
 			} else {
 				isMultiline = true


Test patch:
diff --git a/cft/format/format_test.go b/cft/format/format_test.go
index 46ab0daf..3b32dc64 100644
--- a/cft/format/format_test.go
+++ b/cft/format/format_test.go
@@ -18,6 +18,9 @@ Outputs:
         - Bucket2
         - Arn # Arn comment
 
+Description: |
+  An example template for testing rain fmt command.
+
 # Multiline comment
 # starting at indent 0
 Resources:
@@ -68,7 +71,10 @@ Parameters:
     Type: String
 `
 
-const expectedYaml = `Parameters:
+const expectedYaml = `Description: |
+  An example template for testing rain fmt command.
+
+Parameters:
   Name:
     Type: String
 
@@ -131,6 +137,9 @@ const expectedYamlUnsorted = `Outputs:
   Bucket2: # Bucket comment
     Value: !GetAtt Bucket2.Arn # GetAtt comment Arn comment
 
+Description: |
+  An example template for testing rain fmt command.
+
 # Multiline comment
 # starting at indent 0
 Resources:
@@ -181,6 +190,7 @@ Parameters:
 `
 
 const expectedJson = `{
+    "Description": "An example template for testing rain fmt command.\n",
     "Parameters": {
         "Name": {
             "Type": "String"
@@ -295,6 +305,7 @@ const expectedUnsortedJson = `{
             }
         }
     },
+    "Description": "An example template for testing rain fmt command.\n",
     "Resources": {
         "Bucket2": {
             "Properties": {