Skip to content

Commit

Permalink
Merge pull request #540 from ericzbeard/fix-524
Browse files Browse the repository at this point in the history
Add Outputs to Pkl serialization, and fix formatting Pkl to Yaml with Pkl modules
  • Loading branch information
ericzbeard authored Oct 2, 2024
2 parents b96a5f6 + e71b946 commit 2b9b72d
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 30 deletions.
41 changes: 41 additions & 0 deletions cft/format/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,3 +760,44 @@ Resources:
}

}

func TestPkl(t *testing.T) {
source := `
Resources:
Bucket:
Type: AWS::S3::Bucket
Outputs:
BucketName:
Value: !Ref Bucket
`
template, err := parse.String(source)
if err != nil {
t.Fatal(err)
}

output, err := format.CftToPkl(template, false, "@cfn")
if err != nil {
t.Fatal(err)
}

expected := `amends "@cfn/template.pkl"
import "@cfn/cloudformation.pkl" as cfn
import "@cfn/aws/s3/bucket.pkl"
Resources {
["Bucket"] = new bucket.Bucket {
Type = "AWS::S3::Bucket"
}
}
Outputs {
["BucketName"] = new cfn.Output {
Value = cfn.Ref("Bucket")
}
}
`
if output != expected {
t.Fatalf("Got:\n[%s]\nExpected:\n[%s]\n", output, expected)
}
}
58 changes: 57 additions & 1 deletion cft/format/pkl.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws-cloudformation/rain/cft"
"github.com/aws-cloudformation/rain/internal/config"
"github.com/aws-cloudformation/rain/internal/node"
"github.com/aws-cloudformation/rain/internal/s11n"
"gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -134,6 +135,56 @@ func writeResource(sb *strings.Builder, name string, resource *yaml.Node, basic
return nil
}

func writeOutput(sb *strings.Builder, name string, output *yaml.Node, basic bool) error {
w(sb, " [\"%s\"] = new cfn.Output {\n", name)

for i := 0; i < len(output.Content); i += 2 {

/*
/// A stack Output exported value
open class Export {
Name: RefString
}
/// A stack output value
open class Output {
Description: RefString?
Value: RefString
Export: Export?
}
*/

attrName := output.Content[i].Value
attrValue := output.Content[i+1]

switch attrName {
case "Description":
w(sb, " Description = %s\n", attrValue.Value)
case "Value":
if attrValue.Kind == yaml.MappingNode {
w(sb, " Value = ")
writeMap(sb, attrValue, " ", basic)
} else {
w(sb, " Value = %s\n", attrValue.Value)
}
case "Export":
w(sb, " Export = new cfn.Export {\n")
_, nameNode, _ := s11n.GetMapValue(attrValue, "Name")
if nameNode == nil {
return errors.New("expected Export to have Name")
}
exportName := nameNode.Value
w(sb, " Name = %s\n", exportName)
w(sb, " }\n")
}

}

w(sb, " }\n")

return nil
}

func writeParameter(sb *strings.Builder, name string, param *yaml.Node) error {
w(sb, " [\"%s\"] {\n", name)
for j := 0; j < len(param.Content); j += 2 {
Expand Down Expand Up @@ -375,13 +426,18 @@ func addSection(section cft.Section, n *yaml.Node, sb *strings.Builder, basic bo
sb.WriteString("}\n")
case cft.Transform:
case cft.Outputs:
w(sb, "%s {\n", section)
for i := 0; i < len(n.Content); i += 2 {
writeOutput(sb, n.Content[i].Value, n.Content[i+1], basic)
}
sb.WriteString("}\n")
}

return nil
}

// CftToPkl serializes the template as pkl.
// It assumes that the user is import the cloudformation package
// It assumes that the user is importing the cloudformation package
func CftToPkl(t cft.Template, basic bool, pklPackageAlias string) (string, error) {
if t.Node == nil || len(t.Node.Content) != 1 {
return "", errors.New("expected t.Node.Content[0]")
Expand Down
16 changes: 16 additions & 0 deletions cft/format/pkl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ Resources:
Properties:
BucketName:
Ref: Name
Outputs:
BucketName:
Value: !Ref BucketName
Description: The bucket name
Export:
Name: ExportedBucketName
`

expected := `amends "@cfn/template.pkl"
Expand All @@ -38,6 +44,16 @@ Resources {
}
}
Outputs {
["BucketName"] = new cfn.Output {
Value = cfn.Ref("BucketName")
Description = The bucket name
Export = new cfn.Export {
Name = ExportedBucketName
}
}
}
`

template, err := parse.String(input)
Expand Down
28 changes: 0 additions & 28 deletions internal/cmd/fmt/fmt_test.go

This file was deleted.

4 changes: 3 additions & 1 deletion pkl/pkl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pkl

import (
"context"
"path/filepath"

"github.com/apple/pkl-go/pkl"
"github.com/aws-cloudformation/rain/internal/config"
Expand All @@ -18,7 +19,8 @@ var EvaluatorOptionsFunc = func(opts *pkl.EvaluatorOptions) {

func Yaml(filename string) (string, error) {
// Convert the template to YAML
evaluator, err := pkl.NewEvaluator(context.Background(), EvaluatorOptionsFunc)
evaluator, err := pkl.NewProjectEvaluator(
context.Background(), filepath.Dir(filename), EvaluatorOptionsFunc)
if err != nil {
return "", err
}
Expand Down
16 changes: 16 additions & 0 deletions test/pkl/pkl-out.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
amends "@cfn/template.pkl"
import "@cfn/cloudformation.pkl" as cfn
import "@cfn/aws/s3/bucket.pkl"

Resources {
["Bucket"] = new bucket.Bucket {
Type = "AWS::S3::Bucket"
}

}

Outputs {
["BucketName"] = new cfn.Output {
Value = cfn.Ref("Bucket")
}
}
9 changes: 9 additions & 0 deletions test/pkl/pkl-out.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Resources:
Bucket:
Type: AWS::S3::Bucket
Outputs:
BucketName:
Value: !Ref Bucket
Export:
Name: foo

0 comments on commit 2b9b72d

Please sign in to comment.