2

I am using Google's go-jsonnet library to evaluate some jsonnet files.

I have a function, like so, which renders a Jsonnet document:

// Takes a list of jsonnet files and imports each one and mixes them with "+"
func renderJsonnet(files []string, param string, prune bool) string {

  // empty slice
  jsonnetPaths := files[:0]

  // range through the files
  for _, s := range files {
    jsonnetPaths = append(jsonnetPaths, fmt.Sprintf("(import '%s')", s))
  }

  // Create a JSonnet VM
  vm := jsonnet.MakeVM()

  // Join the slices into a jsonnet compat string
  jsonnetImport := strings.Join(jsonnetPaths, "+")

  if param != "" {
    jsonnetImport = "(" + jsonnetImport + ")" + param
  }

  if prune {
    // wrap in std.prune, to remove nulls, empty arrays and hashes
    jsonnetImport = "std.prune(" + jsonnetImport + ")"
  }

  // render the jsonnet
  out, err := vm.EvaluateSnippet("file", jsonnetImport)

  if err != nil {
    log.Panic("Error evaluating jsonnet snippet: ", err)
  }

  return out

}

This function currently returns a string, because the jsonnet EvaluateSnippet function returns a string.

What I now want to do is render that result JSON using the go-prettyjson library. However, because the JSON i'm piping in is a string, it's not rendering correctly.

So, some questions:

  • Can I convert the returned JSON string to a JSON type, without knowing beforehand what struct to marshal it into
  • if not, can I render the json in a pretty manner some other way?
  • Is there an option, function or method I'm missing here to make this easier?
jaxxstorm
  • 12,422
  • 5
  • 57
  • 67

1 Answers1

3

Can I convert the returned JSON string to a JSON type, without knowing beforehand what struct to marshal it into

Yes. It's very easy:

var jsonOut interface{}
err := json.Unmarshal([]byte(out), &jsonOut)
if err != nil {
    log.Panic("Invalid json returned by jsonnet: ", err)
}
formatted, err := prettyjson.Marshal([]byte(jsonOut))
if err != nil {
    log.Panic("Failed to format jsonnet output: ", err)
}

More info here: https://blog.golang.org/json-and-go#TOC_5.

Is there an option, function or method I'm missing here to make this easier?

Yes. The go-prettyjson library has a Format function which does the unmarshalling for you:

formatted, err := prettyjson.Format([]byte(out))
if err != nil {
    log.Panic("Failed to format jsonnet output: ", err)
}

can I render the json in a pretty manner some other way?

Depends on your definition of pretty. Jsonnet normally outputs every field of an object and every array element on a separate line. This is usually considered pretty printing (as opposed to putting everything on the same line with minimal whitespace to save a few bytes). I suppose this is not good enough for you. You can write your own manifester in jsonnet which formats it to your liking (see std.manifestJson as an example).

sbarzowski
  • 2,707
  • 1
  • 20
  • 25