hcl/cmd/hcldec
Martin Atkins b82170e941 hcldec: Handle or forbid cty.DynamicPseudoType attributes in nested blocks
Our BlockList, BlockSet, and BlockMap specs all produce cty collection
values, which require all elements to have a homogeneous type. If the
nested spec contained an attribute of type cty.DynamicPseudoType, that
would create the risk of each element having a different type, which would
previously have caused decoding to panic.

Now we either handle this during decode (BlockList, BlockSet) or forbid
it outright (BlockMap) to prevent that crash. BlockMap could _potentially_
also handle this during decode, but that would require a more significant
reorganization of its implementation than I want to take on right now,
and decoding dynamically-typed values inside collections is an edge case
anyway.
2018-08-22 11:52:40 -07:00
..
examples cmd/hcldec: Command-line tool for converting HCL config to JSON 2018-02-03 15:37:11 -08:00
diags_json.go cmd/hcldec: opt-in JSON-formatted diagnostics 2018-08-09 18:10:14 -07:00
main.go cmd/hclspecsuite: basic runner functionality for successful cases 2018-08-10 08:49:43 -07:00
README.md cmd/hcldec: Command-line tool for converting HCL config to JSON 2018-02-03 15:37:11 -08:00
spec_funcs.go cmd/hcldec: make cty stdlib functions available to specs 2018-02-04 10:33:35 -08:00
spec-format.md hcldec: BlockAttrsSpec spec type 2018-08-09 16:53:16 -07:00
spec.go hcldec: Handle or forbid cty.DynamicPseudoType attributes in nested blocks 2018-08-22 11:52:40 -07:00
type_expr.go cmd/hcldec: Command-line tool for converting HCL config to JSON 2018-02-03 15:37:11 -08:00
vars.go cmd/hcldec: Command-line tool for converting HCL config to JSON 2018-02-03 15:37:11 -08:00

hcldec

hcldec is a command line tool that transforms HCL input into JSON output using a decoding specification given by the user.

This tool is intended as a "glue" tool, with use-cases like the following:

  • Define a HCL-based configuration format for a third-party tool that takes JSON as input, and then translate the HCL configuration into JSON before running the tool. (See the npm-package example.)

  • Use HCL from languages where a HCL parser/decoder is not yet available. At the time of writing, that's any language other than Go.

  • In particular, define a HCL-based configuration format for a shell script and then use jq to load the result into environment variables for further processing. (See the sh-config-file example.)

Installation

If you have a working Go development environment, you can install this tool with go get in the usual way:

$ go get -u github.com/hashicorp/hcl2/cmd/hcldec

This will install hcldec in $GOPATH/bin, which usually places it into your shell PATH so you can then run it as hcldec.

Usage

usage: hcldec --spec=<spec-file> [options] [hcl-file ...]
  -o, --out string          write to the given file, instead of stdout
  -s, --spec string         path to spec file (required)
  -V, --vars json-or-file   provide variables to the given configuration file(s)
  -v, --version             show the version number and immediately exit

The most important step in using hcldec is to write the specification that defines how to interpret the given configuration files and translate them into JSON. The following is a simple specification that creates a JSON object from two top-level attributes in the input configuration:

object {
  attr "name" {
    type     = string
    required = true
  }
  attr "is_member" {
    type = bool
  }
}

Specification files are conventionally kept in files with a .hcldec extension. We'll call this one example.hcldec.

With the above specification, the following input file example.conf is valid:

name = "Raul"

The spec and the input file can then be provided to hcldec to extract a JSON representation:

$ hcldec --spec=example.hcldec example.conf
{"name": "Raul"}

The specification defines both how to map the input into a JSON data structure and what input is valid. The required = true specified for the name allows hcldec to detect and raise an error when an attribute of that name is not provided:

$ hcldec --spec=example.hcldec typo.conf
Error: Unsupported attribute

  on example.conf line 1:
   1: namme = "Juan"

An attribute named "namme" is not expected here. Did you mean "name"?

Error: Missing required attribute

  on example.conf line 2:

The attribute "name" is required, but no definition was found.

Further Reading

For more details on the .hcldec specification file format, see the spec file documentation.