Git Product home page Git Product logo

hcl's Introduction

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.

hcl's People

Contributors

akupila avatar alisdair avatar ansgarm avatar apparentlymart avatar bduggan avatar crw avatar danielmschmidt avatar fatih avatar hashicorp-copywrite[bot] avatar hashicorp-tsccr[bot] avatar inkel avatar jbardin avatar jen20 avatar kmoe avatar langmartin avatar liamcervante avatar mdeggies avatar mildwonkey avatar minamijoyo avatar mitchellh avatar octo avatar paultyng avatar phinze avatar pselle avatar radeksimko avatar sethvargo avatar shoenig avatar vancluever avatar vladrassokhin avatar wata727 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hcl's Issues

Duplicate map keys

First off, I'm unsure if this is the expected behaviour or not.

When decoding maps it's currently not possible to detect duplicates, as HCL will overwrite (last one wins) the map key.

The HCL fix should be pretty easy, i.e. stick something like the following into decodeMap() right before
setting the value on the map:

dupKey := resultMap.MapIndex(key)
if dupKey.IsValid() {
        return fmt.Errorf(
                "%s: duplicate map key %v", name, key)
}

See for example: hashicorp/consul#1055 or generally any HCL file for that matter:

variable "foo" {
        description = "foo variable"
        default = "bar"
}

...

variable "foo" {
        description = "foo variable"
        default = "crux"
}

Could lead to interesting gotchas when depending on the defaults.

I have a patch + tests for HCL, but this probably will bubble up to HCL users that will need munging since this changes behaviour somewhat and I do not know how to best (or even if) handle that.

Feature Request: JSON Schema Integration within Config

Hi,

Since HCL compiles to JSON, using JSON schema to validate the configuration is natural. For this I suggest a feature of the sort which would look for a magic comment in the file of the form:

# json_schema_web = "https://schema-domain.com/path/to/schema-file.json"

or

# json_schema_path = "../config/service-name-config-schema.json"

Oh and if magic comments are too much magic (I feel so personally), an alternative approach could be used to specify the schema file path.

The validation can be powered by https://github.com/xeipuuv/gojsonschema

When clubbed with #24 I see a pass-through which applications in other languages can invoke so that the HCL format can be used to write config, validate it and translate it to general-purpose JSON input. This means existing apps using JSON can benefit from simpler config and added validation.

PS: This looks like a duplicate of #3 which is closed by what looks like an unrelated commit.

Add the mapping from HCL -> JSON to the README?

The mapping from HCL to JSON (and vice versa) isn't immediately clear. I haven't been able to find concrete documentation for this yet. The fixtures help, but there seems to be a mix of valid/invalid examples.

Comment standard for HCL JSON

Hey there--

So as part of building Terraframe I'm finding myself needing to occasionally need to inject a human-readable comment into the JSON output (largely for debugging). Having to strip my comments back out before feeding it into Terraform is a drag.

Maybe we could standardize on, say, any field beginning with "//" being ignored by the HCL reader? Example:

{
  "//builder": "Built by Terraframe 0.1.0.",
  "resource": {
    "aws_instance": {
      "test": {
        "//source": "test_instance.terraframe:25",
      }
    }
  }
}

It'd help with building good tooling on top of the platform, and would make my life a lot easier. :)

Thanks!

Export config as JSON

Being able to take a .tf file that uses HCL constructs and emit the equivalent JSON would help people writing tool that drive Terraform, as well as make it easier to provide both JSON and HCL equivalent examples on the website.

heredoc doesn't seem to handle tabs

After reviewing #6, I attempted to implement heredoc for user_data in terraform. I had added the following:

    user_data = <<-USER_DATA

    #cloud-config

    coreos:
      etcd:
        # multi-region and multi-cloud deployments need to use $public_ipv4
        addr: $private_ipv4:4001
        peer-addr: $private_ipv4:7001
      units:
        - name: etcd.service
          command: start
        - name: fleet.service
          command: start

    USER_DATA

This throws the following error:
Error loading config: Error parsing /my_file.tf: Line 76, column 0: syntax error

It appears hcl is not honoring the - as outlined in http://en.wikipedia.org/wiki/Here_document:

Appending a minus sign to the << has the effect that leading tabs are ignored. This allows indenting here documents in shell scripts without changing their value.

If I unindent everything and remote the - it works OK, but IMO the file becomes much harder to read since all the heredoc data needs to be completely left-aligned.

Printer/Formatter questions

Hi, after trying to implement printer behaviour in IntelliJ-HCL plugin, I've some questions related to hcl format:
In comment_aligned.input and comment_aligned.output some properties (1-3) have equals sign aligned, but 5,6 are not aligned with each other, so I'd expect something like

    #deneme arslan
    fatih       = ["fatih"]  # yoo4
    #fatih arslan
    fatiharslan = ["arslan"] // yoo5

instead of

    #deneme arslan
    fatih = ["fatih"] # yoo4

    #fatih arslan
    fatiharslan = ["arslan"] // yoo5

As I understand one-line (with probably leading or same-line comment) properties grouped and have equals sign and same-line comment (if any) aligned. But that does not for properties with both leading and same-line comments. Looks like bug.

Also it would be nice to see some document which describes printer/formatter behaviour.

PS: Is there some communication channel to ask question about HCL/HIL instead of creating issues here?
//cc @fatih @mitchellh

Feature request: Creating a site to learn hcl

Hi,
I want to contribute to this project by creating a site like http://sassmeister.com. An online site, that helps people learn HCL more easily.
But I don't really know where to start an with tools to use, which architecture to put in place to do that :)
I opened this issue to let people throw in their ideas.
Regards
Lionel

Definition of a NUMBER and FLOAT

Hi. This is not an issue, just some questions around the HCL spec. According to the README:

Numbers are assumed to be base 10. If you prefix a number with 0x, it is treated as a hexadecimal. If it is prefixed with 0, it is treated as an octal. Numbers can be in scientific notation: "1e10".

I have couple of questions about this (where NUMBER and FLOAT are HCL tokens).

Error for trailing comma's

We had this in TF, which did not generate issues

provisioner "remote-exec" {
inline = ["foo",
"bar",
]
}

Difference between documentation and grammar about lists (arrays)

As README.md says:

Arrays can be made by wrapping it in []. Example: ["foo", "bar", 42]. Arrays can contain primitives and other arrays, but cannot contain objects. Objects must use the block syntax shown below.

At the same time in hcl/parse.y

listitem ::= number | STRING

Note list is missing here.

Please update either documentation or grammar

Also note there's difference in naming: array vs list

Unterminated braces on structures

I've noticed that you don't need to terminate a curly brace on a structure. Is this expected?

Here's a failing test case that demonstrates the problem:

diff --git a/decoder_test.go b/decoder_test.go
index c02bb57..f92776b 100644
--- a/decoder_test.go
+++ b/decoder_test.go
@@ -225,6 +225,12 @@ func TestDecode_interface(t *testing.T) {
                },

                {
+                       "structure_unterminated_brace.hcl",
+                       true,
+                       nil,
+               },
+
+               {
                        "nested_block_comment.hcl",
                        false,
                        map[string]interface{}{
diff --git a/test-fixtures/structure_unterminated_brace.hcl b/test-fixtures/structure_unterminated_brace.hcl
new file mode 100644
index 0000000..091e9e6
--- /dev/null
+++ b/test-fixtures/structure_unterminated_brace.hcl
@@ -0,0 +1,3 @@
+foo "baz" {
+       key = 7
+       foo = "bar"

Emacs mode?

It would be nice to have an emacs code that can keep indentation right, etc. Anyone use emacs? Is some pre-existing mode a good enough match?

JSON parser fails on true, false, and null

The JSON parser fails on the values true, false, and null.

This can be tested by adding these values to json/test-fixtures/types.json and running go test in json/.

{
    "foo": "bar",
    "bar": 7,
    "baz": [1,2,3],
    "foo": -12,
    "bar": 3.14159,
    "foo": true
}
$ go test
--- FAIL: TestParse (0.00 seconds)
    parse_test.go:40: Input: types.json

        Error: Line 7, column 9: syntax error
FAIL
exit status 1
FAIL    github.com/hashicorp/hcl/json   0.011s

Support TextUnmarshaler

With TextUnmarshaller own data types can be defined, such as a wrapper for time.Duration, etc.

Support Unmarshaler-ish interface

I might be completely missing something, but for my application I'm missing a way to have something like the Unmarshaler interface from encoding/json (without having to go through the "raw" object).

Just using Decode() does 90% of the work for me correctly, but I have a few fields where I want to convert the input before it goes into my data structure (for example "1d" to int(86400)).

Empty block formatting

Currently, hclfmt doesn't seem to allow the following formatting:

variable "foobar" {}

Instead, this will be changed to:

variable "foobar" {
}

This seems odd to me and I'm not sure if this is intentional.

Can't get ObjectList.Filter to filter multiple keys

I have some hcl like so:

a = "test"
b = "test2"
c {
   d = "test3"
}
buf := ... // Assuming hcl is in buffer

root, err := hcl.Parse(buf.String()) // Parse

list, _ := root.Node.(*ast.ObjectList) // Turn it to an ObjectList

fmt.Println(len(list.Filter("a").Items)) // 1
fmt.Println(len(list.Filter("a", "b").Items)) // 0
fmt.Println(len(list.Filter("a", "b", "c").Items)) // 0

As can be seen above, if I filter for 1 key, it finds it, however, if I attempt to filter for multiple keys, it always finds nothing.

Did expand tag go away?

Just updated to the latest hcl code and will no longer expand hcl object into slice of structs

var deploy struct {
    Services []service.Config `hcl:"service,expand"`
}

This used to work.

String escape rules changed with new HCL parser

Probably best solved with documentation or better error messages, but the rules to escape quotes inside a quoted string literal has changed in the new HCL parser:

Old parser:

resource "template_file" "kafka" {
  filename = "/dev/null"
  vars {
    broker_list = "${join(\",\", formatlist(\"%s:%d\", aws_route53_record.kafka.*.name, 9092))}"
    zookeeper_list = "${join(\",\", formatlist(\"%s:%d\", aws_route53_record.kafka.*.name, 2181))}"
  }
}

New parser:

resource "template_file" "kafka" {
  filename = "/dev/null"
  vars {
    broker_list = "${join(",", formatlist("%s:%d", aws_route53_record.kafka.*.name, 9092))}"
    zookeeper_list = "${join(",", formatlist("%s:%d", aws_route53_record.kafka.*.name, 2181))}"
  }
}

Relevant code in HCL scanner: https://github.com/hashicorp/hcl/blob/master/hcl/scanner/scanner.go#L455

This could be an issue with unsuspecting Terraform users upgrading to 0.6.7 and suddenly seeing syntax errors.

As a side-effect, the change also brakes syntax highlighting in Sublime Text but not in vim.

The new syntax is easier to write and read, but it is a breaking change so I wanted to make sure it was addressed before downstream releases.

Expressions and Functions.

I'm very curious if you plan to enable expression and functions and to what extent you plan to build out the configuration language.

Environment variables

Is it possible to interpolate environment variables in HCL config?
An example would be very helpful.

Decode into pointer fields in-place.

It would be nice if decodePtr() would operate on the thing being pointed to rather than decoding into a new concrete value and assigning its address to the pointer.

I've found this behaviour handy using encoding/json, for example. Say I have a struct prepopulated with defaults. The struct corresponds to options nested under a key in a config file. I can create an instance of an anonymous struct with a field whose name refers to that key and value is a pointer to my original struct. I can then decode into the anonymous struct instance, and only fields present in the config file data will be updated, leaving the default fields intact.

decoder_test is incorrect

err = Decode(&i2, string(d2))

Decode is being used to decode expected JSON file, which is:

{
    "name": "terraform-test-app",
    "config_vars": {
        "FOO": "bar"
    }
}

This JSON file should create structure like this (native JSON decoder from "encoding/json"):

map[string]interface {}{
  "name": "terraform-test-app",
  "config_vars": map[string]interface {}{
    "FOO":"bar"
  }
}

But, in fact, we have:

map[string]interface {}{
  "name": "terraform-test-app",
  "config_vars": []map[string]interface {}{
    map[string]interface {}{
      "FOO":"bar"
    }
  }
}

No write support for HCL?

It feels like a strange omission not to include write-support for HCL. This decision was probably made with very good reasons but I have yet to discover them.

Making HCL read-only makes it an all-or-nothing thing: either a human writes the entire configuration file in HCL or the server writes it entirely in JSON (which renders it uneditable, or at least very clumsy, for a human).

The typical scenario I have in mind is a server that has a big configuration file with lots of bells and whistles. Some of these options are editable in the UI, while others are considered advanced and aren't exposed in the UI (because only 1% of the users would need them).

I don't see a way to make some variables machine-editable while maintaining an easy configuration language (for humans) for the more advanced options. One example of a configuration format that does support writing (and is reasonably readable) is the git configuration format.

Advice and recommendations are highly welcome. Let me know if none of this makes any sense, I'll happily clarify.

Perhaps what I'm doing just isn't part of the scope of HCL. I'd be cool with that too, I'll look for an alternative.

Bad Input Causes hcl.Decode to hang

Embarrassing bug discovery. Because hcl.Decode() takes a string I accidentally passed an absolute file path into HCL at which point it just seems to hang here: https://github.com/hashicorp/hcl/blob/master/hcl/scanner/scanner.go#L123. An example that should replicate this would be:

bar := &bar{}
err := hcl.Decode(bar, "/go/src/github.com/hashicorp/hcl/scanner/scanner.go")

I had to go all the way down the rabbit hole to find out I was doing this because nothing was bubbling back up the trace. Not sure how to fix it, but wasted the better part of a day trying to find this as sad as it may seem.

Decoding non-pointer struct fields

Is it the case that decoding non-pointer struct fields of a container struct is not supported? Given the following input:

test {
    a = "hello"
    b {
        c = 1
        d = 2
    }
}

Decoded into:

map[string]*A

With types:

type B struct {
    c int     `json:"c"`
    d int     `json:"d"`
}

type A struct {
    a string  `json:"a"`
    b B       `json:"b"` // not a pointer
}

The *A is decoded partially correctly, its field a, a string is correct, but the non-pointer struct field b has a zero value. I get the equivalent of:

test {
    a = "hello"
    b {
        c = 0 // wrong
        d = 0 // wrong
    }
}

Decoding that same input into:

map[string]interface{}

Yields exactly the result I would expect, all the nested fields are present and have the correct keys.

Is this simply not supported or is it a bug? I'll note that the standard library JSON unmarshaler has no problem with unmarshaling into the same structure.

CLI to convert JSON to/from HCL

There seems to be support for JSON <--> HCL; a CLI that makes it easy to convert JSON into HCL would make it easy to integrate HCL into other tool chains?

Multi-line string

I have a rather long command as a string in hcl.

provisioner "local-exec" {
  command = "knife solo bootstrap -N ${self.name} -j '{\"mysql\": {\"server_root_password\": \"${var.mysql_root_password}\"}}' --no-berkshelf --no-host-key-verify -i ${var.pvt_key} -r ${var.run_list.db} ${var.remote_user}@${self.ipv4_address} | tee -a ${self.name}.log
}

Is there a way to break it and still keep it decoded as a single string?
I can't find anything in test fixtures regarding this.

Implementing fmt sub-commands for Terraform/etc

Hi,

I'm looking at implementing a variant of @fatih's hclfmt with the differences that it would:

  • be implemented as sub-commands/verbs in the utilities that use HCL e.g. terraform fmt. So that it would be easily available to users of those utilities without building/installing an additional binary
  • follow the semantics of go fmt and gofmt a bit more closely, in that terraform fmt would rewrite all config files in your current PWD, but you could also provide list/write/diff/stdin arguments to change the behaviour
  • configurable file extensions, e.g. .hcl or .tf

The intention is that most of the code would be implemented in the HCL project but wouldn't be specific to CLI. Then other utilities, such as Terraform and Nomad, could implement the CLI flags and pass over the necessary file extensions and options. The HCL project could also provide an hclfmt binary that works on .hcl files.

Does this sound sensible and useful? Would you like me to finish writing tests and submit a PR for this project and Terraform?

Support other boolean values?

Unless I'm reading the parser incorrectly, despite that the README says hcl supports other types of boolean values (yes, no, on, off), I don't think it actually does. Either the README or the lexer should be changed.

The python implementation does support these alternative boolean values.

Support Embedded Struct Pointers

For my use case this works by simply adding && fieldKind != reflect.Ptr to

hcl/decoder.go

Line 458 in cc08d3d

if fieldKind != reflect.Struct {
. Embedded structs pointers are considered anonymous, but this works just fine if that conditional is relaxed a bit (at least in my tests).

Anonymous struct fields

It'd be nice with support for anonymous struct fields similar to what encoding/json does.

HCL Top Level Object Array

Unfortunately due to a lack of pinning, I don't know exactly when this changed, but decoding a top level array of objects no longer works. Any suggestions on how to fix or get around this?

Example:

type Template struct {
    Source string
    Destination string
    Command string
}

templates := struct {
    Templates []*Template `hcl:"template"`
}

err := hcl.Decode(&templates, `
template {
    source = "blah"
    destination = "foo"
    command = "baz"
}

template {
    source = "blahblah"
    destination = "foofoo"
    command = "bazbaz"
}`)

Currently it fails with: Error: root.template[0]: not an object type for struct (*ast.LiteralType)

Interoperability with HOCON

hcl sounds almost exactly the same as HOCON, which I've contributed to in the past. They both have very JSON-like file formats and there's quite a bit of overlap. They both support types like 1kb even! It'd be cool if maybe the two could work together to define a common spec.

Right now HOCON is used by a lot of Scala & Java projects since Typesafe authored the original client. Puppet has also created a Ruby version that they're using.

Hocon supports some features that hcl doesn't such as importing files and having types for durations, which I think could be added to hcl fairly easily I think. I'm not super fluent in yacc, but it looks like hocon and hcl may handle variables slightly differently, so it's pretty similar as both support syntax like ${aws_instance.web.id}. The Terraform docs seem to have more details on this than the hcl README, so that might be a good place to look.

Not sure if this is worth the effort, but thought it was worth making you guys aware of each other's projects in case there is anything that does make sense.

CC @havocp - maintainer of hocon

"Index out of range" panic when decoding malformed input

The following HCL causes an "index out of range" panic when you try to decode it:

section {
        subsection {
        }
}
section "subsection" {
}

Test program:

package main

import (
        "github.com/hashicorp/hcl"
)

var hclText = `
section {
        subsection {
        }
}
section "subsection" {
}
`

func main () {
        var shadow interface{}
        hcl.Decode(&shadow, hclText)
}

Backtrace:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/hashicorp/hcl.(*decoder).decodeMap(0xc820087e60, 0xc82000ab40, 0xf, 0x7f36c08a11c0, 0xc82000e8e0, 0x4ebfe0, 0xc820036078, 0xd5, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:301 +0x1081
github.com/hashicorp/hcl.(*decoder).decode(0xc820087e60, 0xc82000ab40, 0xf, 0x7f36c08a12f0, 0xc820020360, 0x4ebfe0, 0xc820036078, 0xd5, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:83 +0x69c
github.com/hashicorp/hcl.(*decoder).decodeSlice(0xc820087e60, 0xc82000aae0, 0xc, 0x7f36c08a11c0, 0xc82000e8a0, 0x4e44c0, 0xc82000e840, 0x57, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:395 +0x5c6
github.com/hashicorp/hcl.(*decoder).decode(0xc820087e60, 0xc82000aae0, 0xc, 0x7f36c08a11c0, 0xc82000e8a0, 0x4eba20, 0xc82000ab00, 0xd4, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:87 +0x774
github.com/hashicorp/hcl.(*decoder).decodeMap(0xc820087e60, 0x5405e0, 0x4, 0x7f36c08a11c0, 0xc82000e5c0, 0x4ebfe0, 0xc820010510, 0x15, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:330 +0xf1d
github.com/hashicorp/hcl.(*decoder).decode(0xc820087e60, 0x5405e0, 0x4, 0x7f36c08a11c0, 0xc82000e5c0, 0x4eba20, 0xc82000a4b0, 0xd4, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:83 +0x69c
github.com/hashicorp/hcl.(*decoder).decodeInterface(0xc820087e60, 0x5405e0, 0x4, 0x7f36c08a11c0, 0xc82000e5c0, 0x4eba20, 0xc82000a4b0, 0xd4, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:249 +0x384
github.com/hashicorp/hcl.(*decoder).decode(0xc820087e60, 0x5405e0, 0x4, 0x7f36c08a11c0, 0xc82000e5c0, 0x4eba20, 0xc82000a4b0, 0xd4, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:81 +0x628
github.com/hashicorp/hcl.DecodeObject(0x4df000, 0xc82000a4b0, 0x7f36c08a11c0, 0xc82000e5c0, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:43 +0x25f
github.com/hashicorp/hcl.Decode(0x4df000, 0xc82000a4b0, 0x56ae60, 0x37, 0x0, 0x0)
    gopath/src/github.com/hashicorp/hcl/decoder.go:26 +0xb9
main.main()
    crash_hcl.go:18 +0x5f

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.