Skip to content

Commit

Permalink
Don’t crash when packaging YAML templates without transforms (closes #32
Browse files Browse the repository at this point in the history
)
  • Loading branch information
aidansteele committed May 29, 2019
1 parent 8e23998 commit a658473
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 2 deletions.
57 changes: 55 additions & 2 deletions cmd/load_save.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ import (
"encoding/json"
"github.com/glassechidna/stackit/pkg/stackit"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
"io/ioutil"
"strings"
)

var DefaultOutputPath = "./stackit.packaged.yml"

func savePreparedOutput(prepared *stackit.PrepareOutput) error {
jsonBody, err := ensureJson(prepared.TemplateBody)
if err != nil {
return errors.Wrap(err, "ensuring template is json")
}

prettyBuf := &bytes.Buffer{}
err := json.Indent(prettyBuf, []byte(prepared.TemplateBody), "", " ")
err = json.Indent(prettyBuf, jsonBody, "", " ")
if err != nil {
return errors.Wrap(err, "pretty-printing json of template body")
}

prepared.TemplateBody = prettyBuf.String()

marshalled, err := yaml.Marshal(prepared)
Expand All @@ -42,3 +49,49 @@ func loadPreparedOutput() (*stackit.PrepareOutput, error) {

return &output, nil
}

func ensureJson(input string) ([]byte, error) {
if strings.HasPrefix(input, "{") {
return []byte(input), nil
} else {
// we assume it's yaml
node := yaml.Node{}
err := yaml.Unmarshal([]byte(input), &node)
if err != nil {
return nil, errors.Wrap(err, "unmarshalling yaml into node")
}

return json.Marshal(jsonYamlNode(node))
}
}

type jsonYamlNode yaml.Node

func (j jsonYamlNode) MarshalJSON() ([]byte, error) {
switch j.Kind {
case yaml.DocumentNode:
return json.Marshal(jsonYamlNode(*j.Content[0]))
case yaml.SequenceNode:
arr := []jsonYamlNode{}
for _, n := range j.Content {
arr = append(arr, jsonYamlNode(*n))
}
return json.Marshal(arr)
case yaml.MappingNode:
kv := map[string]jsonYamlNode{}
idx := 0
for idx < len(j.Content) {
keynode := j.Content[idx]
valnode := j.Content[idx+1]
kv[keynode.Value] = jsonYamlNode(*valnode)
idx += 2
}
return json.Marshal(kv)
case yaml.ScalarNode:
// TODO what about numerics?
return json.Marshal(j.Value)
case yaml.AliasNode:
panic("aliases not supported")
}
return nil, nil
}
20 changes: 20 additions & 0 deletions cmd/load_save_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestEnsureJson(t *testing.T) {
t.Run("input json", func(t *testing.T) {
output, err := ensureJson(`{"Hello": "world"}`)
assert.NoError(t, err)
assert.Equal(t, `{"Hello": "world"}`, string(output))
})

t.Run("input yaml", func(t *testing.T) {
output, err := ensureJson(`Hello: world`)
assert.NoError(t, err)
assert.Equal(t, `{"Hello":"world"}`, string(output))
})
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ require (
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.0-20190502103701-55513cacd4ae
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20190502103701-55513cacd4ae h1:ehhBuCxzgQEGk38YjhFv/97fMIc2JGHZAhAWMmEjmu0=
gopkg.in/yaml.v3 v3.0.0-20190502103701-55513cacd4ae/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit a658473

Please sign in to comment.