fork of https://github.com/hashicorp/hcl because issue : https://github.com/hashicorp/hcl/issues/290 these code permit use of "nested" field decoding which is just composite struct
Go to file
James Bardin 94baef9aa6 add an ExprMap method to the mock expression
Add an ExprMethod so that the mock expressions can be handled by the
hcl.ExprMap function.

Added basic tests for both ExprList and ExprMap
2021-02-08 15:52:16 -05:00
.circleci Add win tests to CircleCI; Remove Appveyor (#435) 2020-12-16 12:09:42 -08:00
cmd Fix various stale links to spec.md 2020-01-09 11:02:20 -08:00
ext ext/userfunc: Fix the package documentation link in the README 2020-08-21 15:03:22 -07:00
gohcl Merge pull request #335 from kinvolk/fix-slice-value-decoding 2020-11-19 11:35:55 -05:00
guide Change module path to github.com/hashicorp/hcl/v2 2019-09-09 15:46:40 -07:00
hcldec hcldec: add ValidateSpec 2020-06-04 14:25:45 -07:00
hcled Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
hclparse hclparse: Go package documentation 2019-10-01 15:59:10 -07:00
hclsimple hclsimple: Simple one-shot parse/decode/evaluate API 2019-10-01 16:18:16 -07:00
hclsyntax Fix merge 2021-01-06 09:34:54 -05:00
hcltest add an ExprMap method to the mock expression 2021-02-08 15:52:16 -05:00
hclwrite hclwrite: do not add space after a boolean NOT operator 2020-12-02 16:10:12 -08:00
integrationtest ext/customdecode: Custom expression decoding extension 2019-12-17 07:51:07 -08:00
json json: Add ParseExpression function 2020-09-04 14:12:01 -07:00
specsuite Fix various stale links to spec.md 2020-01-09 11:02:20 -08:00
CHANGELOG.md Update CHANGELOG.md 2021-01-06 09:43:58 -05:00
diagnostic_text_test.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
diagnostic_text.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
diagnostic.go FIX: a couple of typos 2020-02-17 23:25:41 -08:00
didyoumean.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
doc.go hclsimple: Simple one-shot parse/decode/evaluate API 2019-10-01 16:18:16 -07:00
eval_context.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
expr_call.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
expr_list.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
expr_map.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
expr_unwrap.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
go.mod Use Unicode 12.0.0 grapheme cluster segmentation rules 2020-03-09 09:16:33 -07:00
go.sum Use Unicode 12.0.0 grapheme cluster segmentation rules 2020-03-09 09:16:33 -07:00
LICENSE Relicense under MPL, rather than MIT 2017-09-11 16:43:03 -07:00
merged_test.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
merged.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
ops_test.go Fix panic traversing marked list 2020-11-26 10:59:16 -05:00
ops.go Fix panic traversing marked list 2020-11-26 10:59:16 -05:00
pos_scanner_test.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
pos_scanner.go Use Unicode 12.0.0 grapheme cluster segmentation rules 2020-03-09 09:16:33 -07:00
pos_test.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
pos.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
README.md hcl: Fix the simple example in the README 2020-08-21 15:11:58 -07:00
schema.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
spec.md Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
static_expr.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
structure_at_pos.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
structure.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
traversal_for_expr_test.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
traversal_for_expr.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00
traversal.go Unfold the "hcl" directory up into the root 2019-09-09 16:08:19 -07:00

HCL

HCL is a toolkit for creating structured configuration languages that are both human- and machine-friendly, for use with command-line tools. Although intended to be generally useful, it is primarily targeted towards devops tools, servers, etc.

NOTE: This is major version 2 of HCL, whose Go API is incompatible with major version 1. Both versions are available for selection in Go Modules projects. HCL 2 cannot be imported from Go projects that are not using Go Modules. For more information, see our version selection guide.

HCL has both a native syntax, intended to be pleasant to read and write for humans, and a JSON-based variant that is easier for machines to generate and parse.

The HCL native syntax is inspired by libucl, nginx configuration, and others.

It includes an expression syntax that allows basic inline computation and, with support from the calling application, use of variables and functions for more dynamic configuration languages.

HCL provides a set of constructs that can be used by a calling application to construct a configuration language. The application defines which attribute names and nested block types are expected, and HCL parses the configuration file, verifies that it conforms to the expected structure, and returns high-level objects that the application can use for further processing.

package main

import (
	"log"

	"github.com/hashicorp/hcl/v2/hclsimple"
)

type Config struct {
	IOMode  string        `hcl:"io_mode"`
	Service ServiceConfig `hcl:"service,block"`
}

type ServiceConfig struct {
	Protocol   string          `hcl:"protocol,label"`
	Type       string          `hcl:"type,label"`
	ListenAddr string          `hcl:"listen_addr"`
	Processes  []ProcessConfig `hcl:"process,block"`
}

type ProcessConfig struct {
	Type    string   `hcl:"type,label"`
	Command []string `hcl:"command"`
}

func main() {
	var config Config
	err := hclsimple.DecodeFile("config.hcl", nil, &config)
	if err != nil {
		log.Fatalf("Failed to load configuration: %s", err)
	}
	log.Printf("Configuration is %#v", config)
}

A lower-level API is available for applications that need more control over the parsing, decoding, and evaluation of configuration. For more information, see the package documentation.

Why?

Newcomers to HCL often ask: why not JSON, YAML, etc?

Whereas JSON and YAML are formats for serializing data structures, HCL is a syntax and API specifically designed for building structured configuration formats.

HCL attempts to strike a compromise between generic serialization formats such as JSON and configuration formats built around full programming languages such as Ruby. HCL syntax is designed to be easily read and written by humans, and allows declarative logic to permit its use in more complex applications.

HCL is intended as a base syntax for configuration formats built around key-value pairs and hierarchical blocks whose structure is well-defined by the calling application, and this definition of the configuration structure allows for better error messages and more convenient definition within the calling application.

It can't be denied that JSON is very convenient as a lingua franca for interoperability between different pieces of software. Because of this, HCL defines a common configuration model that can be parsed from either its native syntax or from a well-defined equivalent JSON structure. This allows configuration to be provided as a mixture of human-authored configuration files in the native syntax and machine-generated files in JSON.

Information Model and Syntax

HCL is built around two primary concepts: attributes and blocks. In native syntax, a configuration file for a hypothetical application might look something like this:

io_mode = "async"

service "http" "web_proxy" {
  listen_addr = "127.0.0.1:8080"
  
  process "main" {
    command = ["/usr/local/bin/awesome-app", "server"]
  }

  process "mgmt" {
    command = ["/usr/local/bin/awesome-app", "mgmt"]
  }
}

The JSON equivalent of this configuration is the following:

{
  "io_mode": "async",
  "service": {
    "http": {
      "web_proxy": {
        "listen_addr": "127.0.0.1:8080",
        "process": {
          "main": {
            "command": ["/usr/local/bin/awesome-app", "server"]
          },
          "mgmt": {
            "command": ["/usr/local/bin/awesome-app", "mgmt"]
          },
        }
      }
    }
  }
}

Regardless of which syntax is used, the API within the calling application is the same. It can either work directly with the low-level attributes and blocks, for more advanced use-cases, or it can use one of the decoder packages to declaratively extract into either Go structs or dynamic value structures.

Attribute values can be expressions as well as just literal values:

# Arithmetic with literals and application-provided variables
sum = 1 + addend

# String interpolation and templates
message = "Hello, ${name}!"

# Application-provided functions
shouty_message = upper(message)

Although JSON syntax doesn't permit direct use of expressions, the interpolation syntax allows use of arbitrary expressions within JSON strings:

{
  "sum": "${1 + addend}",
  "message": "Hello, ${name}!",
  "shouty_message": "${upper(message)}"
}

For more information, see the detailed specifications:

Changes in 2.0

Version 2.0 of HCL combines the features of HCL 1.0 with those of the interpolation language HIL to produce a single configuration language that supports arbitrary expressions.

This new version has a completely new parser and Go API, with no direct migration path. Although the syntax is similar, the implementation takes some very different approaches to improve on some "rough edges" that existed with the original implementation and to allow for more robust error handling.

It's possible to import both HCL 1 and HCL 2 into the same program using Go's semantic import versioning mechanism:

import (
    hcl1 "github.com/hashicorp/hcl"
    hcl2 "github.com/hashicorp/hcl/v2"
)

Acknowledgements

HCL was heavily inspired by libucl, by Vsevolod Stakhov.

HCL and HIL originate in HashiCorp Terraform, with the original parsers for each written by Mitchell Hashimoto.

The original HCL parser was ported to pure Go (from yacc) by Fatih Arslan. The structure-related portions of the new native syntax parser build on that work.

The original HIL parser was ported to pure Go (from yacc) by Martin Atkins. The expression-related portions of the new native syntax parser build on that work.

HCL 2, which merged the original HCL and HIL languages into this single new language, builds on design and prototyping work by Martin Atkins in zcl.