HCL is the HashiCorp configuration language.

Overview

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.

Comments
  • add PoC cmd converting HCL to JSON

    add PoC cmd converting HCL to JSON

    This adds an hcl2json command which reads HCL from STDIN and writes indented JSON to STDOUT.

    At the moment it is not friendly at all, and probably is only useful for people who are testing HCL code changes. Before merging, it should be a friendly tool to allow people who :heart: HCL to use it in environments where importing this package is unwieldy.

    Some things it should probably do:

    • [x] hcl2json, hcl2json -h should print usage
    • [x] hcl2json foo.hcl should read from foo.hcl
    • [x] hcl2json - should read from STDIN
    • [x] refactor to extract a CLI struct for testing
    • [x] add tests for the above functionality
    • build through gox?

    Fixes https://github.com/hashicorp/hcl/issues/32

    opened by josephholsten 28
  • HCL2 <-> JSON Transformer?

    HCL2 <-> JSON Transformer?

    Hi all!

    I was wondering if there was anything in the works for a library that could convert HCL2 to JSON and back again, similar to https://github.com/kvz/json2hcl

    Thanks!

    enhancement v2 
    opened by Aedalus 13
  • Fails to parse time.Duration

    Fails to parse time.Duration

    HCL Template

    App {
        PostponeExit = 5s
    }
    

    Expected behavior

    It should be able to parse Go-style time duration.

    Actual behavior

    With a struct like:

    type Conf struct {
    	App struct {
    		PostponeExit time.Duration
    	}
    
    	// ...
    }
    

    We have to use a value 5000000000 to get a 5s duration. If we use 5s as value in hcl file, we get:

    At 3:9: nested object expected: LBRACE got: ASSIGN
    

    And if we use a string like "5s", we get:

    strconv.ParseInt: parsing "5s": invalid syntax
    

    I saw issues related to this. But they were about implementing an unmarshaller interface (which I failed to figure what it is) and not unmarshalling standard duration.

    opened by dc0d 12
  • `raise()` function for custom error handling (HCL2)

    `raise()` function for custom error handling (HCL2)

    UPDATE (2): Terraform have opened a 'discuss' topic for this capability: https://discuss.hashicorp.com/t/terraform-core-research-ability-to-raise-an-error/35818

    UPDATE: CI Tests are now passing, PR is ready for review and feedback.

    This is my first contribution to Terraform and HCL. Comments, suggestions, and guidance are all welcome.

    Essentially, this update adds a new raise function which Terraform developers can leverage to improve error handling and messaging to users.

    Usage:

    locals {
      progress = 50
      of_total_a = 0
      of_total_b = null
      of_total_c = 100
    }
    locals {
      #raises a custom error using if/then/else syntax:
      my_value = local.of_total_a = null ? raise("invalid denominator") : local.progress / local.of_total_a
    
      #raises a custom error using try():
      my_value = try(local.progress / local.of_total_a, raise("invalid denominator"))
    
      #raises a custom error using coalesce() if value is null:
      my_value = local.progress / coalesce(local.of_total_b, raise("denominator is null"))
    
      # succeeds (no error)
      my_value = try(local.progress / local.of_total_c, raise("(will not be reached)"))
    }
    

    NOTE: This change also requires a change to the Terraform repo, tracked here: https://github.com/hashicorp/terraform/pull/25088

    Resolves https://github.com/hashicorp/terraform/issues/24269

    opened by aaronsteers 11
  • cannot find package

    cannot find package "github.com/hashicorp/hcl/v2"

    I am trying to write a provide following the tutorial on link.[https://www.terraform.io/docs/extend/writing-custom-providers.html]

    When I try to do go get github.com/hashicorp/terraform-plugin-sdk/plugin I have the below error:

    package github.com/hashicorp/hcl/v2: cannot find package "github.com/hashicorp/hcl/v2" in any of:
    	/usr/local/go/src/github.com/hashicorp/hcl/v2 (from $GOROOT)
    	/Users/federicoolivieri/go/src/github.com/hashicorp/hcl/v2 (from $GOPATH)
    package github.com/hashicorp/hcl/v2/hclsyntax: cannot find package "github.com/hashicorp/hcl/v2/hclsyntax" in any of:
    	/usr/local/go/src/github.com/hashicorp/hcl/v2/hclsyntax (from $GOROOT)
    	/Users/federicoolivieri/go/src/github.com/hashicorp/hcl/v2/hclsyntax (from $GOPATH)
    

    I then tried go get github.com/hashicorp/hcl/v2but I have pretty much the same error.

    opened by lvrfrc87 11
  • Add support for indented HEREDOC terminators

    Add support for indented HEREDOC terminators

    This PR adds support for the style of HEREDOC often used in Ruby which allows the terminating marker to be indented if the HEREDOC is started with the sequence "<<-" rather than the usual "<<". This allows users to express documents with more natural indentation:

    resource "template_file" "test" {
        template = <<-HEREDOC
            First Line
            Second Line
        HEREDOC
    }
    

    Note that this does not attempt to add any semantics around removing hanging indent from the actual text of the document, so extra indentation would still be present. We could make use of the canonical style for HCL herre to remove the hanging indent in the style of Ruby which would probably be more predictable for users.

    Fixes https://github.com/hashicorp/hcl/issues/9

    cc @phinze, @mitchellh

    opened by jen20 11
  • Multi-line string

    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.

    opened by arr-dev 11
  • CLI to convert JSON to/from HCL

    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?

    opened by drnic 11
  • No write support for HCL?

    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.

    opened by rubenv 11
  • Feature request:  better multi-line string formatting

    Feature request: better multi-line string formatting

    Coming from a terraform perspective, I have noticed that code readability deteriorates when column lengths get really long. This problem tends to crop-up frequently with argument string values inside resources, and unfortunately the current syntax options (HEREDOC or newlines inside interpolation functions) are limiting. I'm still learning the internals of HCL, but I think one / both of the following options might work for this:

    1. Multi-line string literal with white-space trimming. Similar to the Python triple-quote ("""):
    tags {
      Name = """${var.foo}-${var.bar}-
                my-application-elb-${var.baz}"""
    }
    
    1. String concatenation operators (and a new-line escape like bash?), similar to (how I do it) in Python:
    tags {
      Name = "${var.foo}-${var.bar}-" + \
             "my-application-elb-${var.baz}"
    }
    

    See previous issue under terraform for background: https://github.com/hashicorp/terraform/issues/8210

    Thoughts?

    enhancement 
    opened by adampats 10
  • Colon assign

    Colon assign

    implements colon assignment. Doesn't implement deep assignment yet, so hcl/test-fixtures/assign_colon.hcl still fails.

    I implemented this primarily in the parser because I prefer stupid lexers. It would be quite easy to just have a ":" be token EQUAL, so it might be better to implement it that way.

    opened by josephholsten 10
  • fuzz: add oss-fuzz build script

    fuzz: add oss-fuzz build script

    google/oss-fuzz runs continuous fuzzing on HCL, using a build script stored in the oss-fuzz repository.

    This PR (and https://github.com/google/oss-fuzz/pull/7907) will move the build script from https://github.com/google/oss-fuzz/blob/master/projects/hcl/build.sh into this repository, so we can maintain it more easily, as suggested by oss-fuzz maintainers.

    oss-fuzz runs this script in a container, after cloning the HCL repository, to build a libFuzzer target from the HCL fuzzers.

    Please note that this PR does not make the script work, which is the aim of the next PR.

    opened by kmoe 0
  • HCL2 spec ambiguity around binary and unary operations.

    HCL2 spec ambiguity around binary and unary operations.

    The current spec appears to suggest that chaining arithmetic operations is not possible without nesting each pair in parenthesis:

    Operation = unaryOp | binaryOp;
    unaryOp = ("-" | "!") ExprTerm;
    binaryOp = ExprTerm binaryOperator ExprTerm;
    binaryOperator = compareOperator | arithmeticOperator | logicOperator;
    compareOperator = "==" | "!=" | "<" | ">" | "<=" | ">=";
    arithmeticOperator = "+" | "-" | "*" | "/" | "%";
    logicOperator = "&&" | "||" | "!";
    
    ExprTerm = (
        LiteralValue |
        CollectionValue |
        TemplateExpr |
        VariableExpr |
        FunctionCall |
        ForExpr |
        ExprTerm Index |
        ExprTerm GetAttr |
        ExprTerm Splat |
        "(" Expression ")"
    );
    

    This seems to imply that an expression such as x + y / z is not a valid Operation, but (x + y) / z is.

    Running Terraform 1.2.9, it appears that the former is valid:

    locals {
      x = 1
      y = 2
      z = 3
      abc = local.x + local.y / local.z
    }
    
    resource "null_resource" "result" {
      triggers = {
        id = uuid()
      }
    
      provisioner "local-exec" {
        interpreter = ["/usr/bin/env", "sh", "-c"]
        command = "echo '${local.abc}'"
      }
    }
    
    (.venv) ➜  hcl-test terraform version
    Terraform v1.2.9
    on linux_amd64
    + provider registry.terraform.io/hashicorp/null v3.1.1
    (.venv) ➜  hcl-test terraform apply -auto-approve
    null_resource.result: Refreshing state... [id=4532689630753613577]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
    -/+ destroy and then create replacement
    
    Terraform will perform the following actions:
    
      # null_resource.result must be replaced
    -/+ resource "null_resource" "result" {
          ~ id       = "4532689630753613577" -> (known after apply)
          ~ triggers = {
              - "id" = "57b28aab-2d89-2c7b-5f86-95393921ce85"
            } -> (known after apply) # forces replacement
        }
    
    Plan: 1 to add, 0 to change, 1 to destroy.
    null_resource.result: Destroying... [id=4532689630753613577]
    null_resource.result: Destruction complete after 0s
    null_resource.result: Creating...
    null_resource.result: Provisioning with 'local-exec'...
    null_resource.result (local-exec): Executing: ["/usr/bin/env" "sh" "-c" "echo '1.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666668'"]
    null_resource.result (local-exec): 1.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666668
    null_resource.result: Creation complete after 0s [id=5999965405986185361]
    
    Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
    

    If this is not correct (and I am not just misunderstanding something), I think a grammar that more accurately represents the behaviour for the implementation. This would address the following issues:

    • Operator issue (this ticket)
    • Existing grammar does not communicate operator precedence very well, instead a table is provided and the grammar has to be rewritten as per that table.
    • Conditional (ternary) operator does not communicate associativity very well, and currently would result in an infinite loop on the first term, which makes it unsuitable for grammar generators such as ANTLR without modification.
    • #550
    Expression = orOp , "?" , Expression , ":" , Expression
               | orOp
               ;
    
    orOp       = andOp , "||" , orOp
               | andOp
               ;
    
    andOp      = eqOp , "&&" , andOp
               | eqOp
               ;
    
    eqOp       = compOp , "==" , eqOp
               | compOp , "!=" , eqOp
               | compOp
               ;
    
    compOp     = addOp , "<"  , compOp
               | addOp , "<=" , compOp
               | addOp , ">"  , compOp
               | addOp , ">=" , compOp
               | addOp
               ;
    
    addOp      = mulOp , "+" , addOp
               | mulOp , "-" , addOp
               | mulOp
               ;
     
    mulOp      = unaryOp , "*" , mulOp
               | unaryOp , "/" , mulOp
               | unaryOp , "%" , mulOp
               | unaryOp
               ;
    
    unaryOp    = "-" , unaryOp
               | "!" , unaryOp
               | ExprTerm
               ;
    

    While this is more verbose, I think it provides a few additional benefits:

    • Grammar is more deterministic, making it easier to port to parser generators
    • Conditional is now handled as part of operations, meaning the conditional and operation production can now be removed, making it a little less confusing to handle.
    • Operator precedence is now clear from the grammar rather than needing an additional table.
    • Operators can be chained (e.g. x + y / z) clearly.
    • Ternary conditional operator no longer produces an infinite loop on the first term, and communicates left associativity.

    Hope this doesn't feel too pedantic and that I am not stepping on anyones toes or anything with this suggestion, I am currently attempting to write an HCL2 parser from this spec for Java 17, but these issues are a few that I have encountered while working on the project.

    opened by ascopes 0
  • Incorrect `srcRange` for files starting with a multiline comment

    Incorrect `srcRange` for files starting with a multiline comment

    When a HCL file starts with a multiline comment, the SrcRange of the hclsyntax.Body starts after the multiline comment.

    Test data

    Example file starting with a multiline comment:

    /********************************
     Some comment
    ********************************/
    
    data "google_project" "project" {
      project_id = var.project_id
    }
    
    

    Example code for parsing the file:

    f, _ := hclsyntax.ParseConfig(src, filename, pos)
    body, _ := f.Body.(*hclsyntax.Body)
    fmt.Println(body.Range())
    

    Full example here: https://gist.github.com/dbanck/83e0e7936556eab2184d5d89e9d1feac

    Expected behavior

    SrcRange for the example file should be main.tf:1,1-8,1

    Actual behavior

    SrcRange for the example file is reported as main.tf:3,34-8,1

    bug 
    opened by dbanck 0
  • Update spec.md to avoid suggesting ! is a binary operator

    Update spec.md to avoid suggesting ! is a binary operator

    The current spec appears to suggest that the bang is a binary operator, which would enable expressions such as foo ! bar.

    https://github.com/hashicorp/hcl/blob/main/hclsyntax/parser.go#L1070 seems to suggest this is only a unary operator.

    opened by ascopes 1
  • json: Walk expressions like `hclsyntax.Walk`

    json: Walk expressions like `hclsyntax.Walk`

    In the context of static analysis, there is a use case where you want to visit all expressions in a JSON body. Imagine getting an expression for a string containing a reference to terraform.workspace from the following configuration:

    {
      "resource": {
        "null_resource": {
          "a": {
            "triggers": {
              "w": "${terraform.workspace}"
            }
          }
        }
      }
    }
    

    If you know the schema of this configuration, you can get the exact "${terraform.workspace}" expression, but if you don't know the schema, it's a difficult problem. With the following way, an expression larger than the original expression will be obtained:

    package main
    
    import (
    	"fmt"
    	"os"
    
    	"github.com/hashicorp/hcl/v2/json"
    )
    
    func main() {
    	src, err := os.ReadFile("config.tf.json")
    	if err != nil {
    		panic(err)
    	}
    	file, diags := json.Parse(src, "config.tf.json")
    	if diags.HasErrors() {
    		panic(diags)
    	}
    	attributes, diags := file.Body.JustAttributes()
    	if diags.HasErrors() {
    		panic(diags)
    	}
    	fmt.Println(attributes["resource"].Expr.Range()) // => config.tf.json:2,15-10,4
    }
    

    The HCL native syntax provides the hclsyntax.Walk to solve the issue, but the json.Walk in the JSON syntax does not exist. Is it possible to provide such an API?

    Proposal

    If you add json.Walk, the interface will look like this:

    type Walker interface {
    	Enter(node json.node) hcl.Diagnostics
    	Exit(node json.node) hcl.Diagnostics
    }
    
    func Walk(node json.node, w Walker) hcl.Diagnostics
    

    In this case, the challenge is that json.node is private. I remember that exposing these structures was negative in previous discussions https://github.com/hashicorp/hcl/issues/332#issuecomment-570682405

    My idea is to provide an interface that depends on the hcl.Body and hcl.Expression instead of json.node:

    type ExpressionWalker interface {
    	Enter(expr hcl.Expression) hcl.Diagnostics
    	Exit(expr hcl.Expression) hcl.Diagnostics
    }
    
    func WalkExpressions(node hcl.Body, w ExpressionWalker) hcl.Diagnostics
    

    In the above interface, there is a problem that you can pass an unintended body such as hclsyntax.Body, but in that case, it halts walking and reports diagnostics.

    Refer to expr.Variables() for the behavior of walking all expressions. In this way, the expression is recursively created from the value and passed to the walker. In addition to this, it should be enough to consider the numberVal, booleanVal, and nullVal. https://github.com/hashicorp/hcl/blob/v2.13.0/json/structure.go#L513-L555

    In addition to these, we need utilities to determine the type of expression. I believe this can provide interfaces like IsJSONObjectExpression,IsJSONArrayExpression like IsJSONExpression. https://github.com/hashicorp/hcl/blob/v2.13.0/json/is.go#L7-L31

    How about the above proposal? If there is no problem, I would like to work with the implementation. Thank you.

    References

    • https://github.com/terraform-linters/tflint/issues/1257
    • https://github.com/hashicorp/hcl/blob/v2.13.0/hclsyntax/walk.go
    • https://github.com/hashicorp/hcl/blob/v2.13.0/json/structure.go#L513-L555
    • https://github.com/hashicorp/hcl/blob/v2.13.0/json/is.go#L7-L31
    opened by wata727 2
Releases(v2.14.1)
  • v2.14.1(Sep 23, 2022)

    Bugs Fixed

    • ext/typeexpr: Type convert defaults for optional object attributes when applying them. This prevents crashes in certain cases when the objects in question are part of a collection. (#555)
    Source code(tar.gz)
    Source code(zip)
  • v2.14.0(Sep 1, 2022)

    Enhancements

    • ext/typeexpr: Added support for optional object attributes to TypeConstraint. Attributes can be wrapped in the special optional(…) modifier, allowing the attribute to be omitted while still meeting the type constraint. For more information, cty's documentation on conversion between object types. (#549)
    • ext/typeexpr: New function: TypeConstraintWithDefaults. In this mode, the optional(…) modifier accepts a second argument which can be used as the default value for omitted object attributes. The function returns both a cty.Type and associated Defaults, the latter of which has an Apply method to apply defaults to a given value. (#549)
    Source code(tar.gz)
    Source code(zip)
  • v2.12.0(Apr 22, 2022)

    Enhancements

    • hclsyntax: Evaluation of conditional expressions will now produce more precise error messages about inconsistencies between the types of the true and false result expressions, particularly in cases where both are of the same structural type kind but differ in their nested elements. (#530)
    • hclsyntax: The lexer will no longer allocate a small object on the heap for each token. Instead, in that situation it will allocate only when needed to return a diagnostic message with source location information. (#490)
    • hclwrite: New functions TokensForTuple, TokensForObject, and TokensForFunctionCall allow for more easily constructing the three constructs which are supported for static analysis and which HCL-based languages typically use in contexts where an expression is used only for its syntax, and not evaluated to produce a real value. For example, these new functions together are sufficient to construct all valid type constraint expressions from the Type Expressions Extension, which is the basis of variable type constraints in the Terraform language at the time of writing. (#502)
    • json: New functions IsJSONExpression and IsJSONBody to determine if a given expression or body was created by the JSON syntax parser. In normal situations it's better not to worry about what syntax a particular expression/body originated in, but this can be useful in some trickier cases where an application needs to shim for backwards-compatibility or for static analysis that needs to have special handling of the JSON syntax's embedded expression/template conventions. (#524)

    Bugs Fixed

    • gohcl: Fix docs about supported types for blocks. (#507)
    Source code(tar.gz)
    Source code(zip)
  • v2.11.1(Dec 1, 2021)

  • v2.11.0(Dec 1, 2021)

    v2.11.0

    Enhancements

    • hclsyntax: Various error messages related to unexpectedly reaching end of file while parsing a delimited subtree will now return specialized messages describing the opening tokens as "unclosed", instead of returning a generic diagnostic that just happens to refer to the empty source range at the end of the file. This gives better feedback when error messages are being presented alongside a source code snippet, as is common in HCL-based applications, because it shows which innermost container the parser was working on when it encountered the error. (#492)

    Bugs Fixed

    • hclsyntax: Upgrading an unknown single value to a list using a splat expression must return unknown (#493)
    Source code(tar.gz)
    Source code(zip)
  • v2.10.1(Jul 21, 2021)

    v2.10.1 (July 21, 2021)

    • dynblock: Decode unknown dynamic blocks in order to obtain any diagnostics even though the decoded value is not used (#476)
    • hclsyntax: Calling functions is now more robust in the face of an incorrectly-implemented function which returns a function.ArgError whose argument index is out of range for the length of the arguments. Previously this would often lead to a panic, but now it'll return a less-precice error message instead. Functions that return out-of-bounds argument indices still ought to be fixed so that the resulting error diagnostics can be as precise as possible. (#472)
    • hclsyntax: Ensure marks on unknown values are maintained when processing string templates. (#478)
    • hcl: Improved error messages for various common error situtions in hcl.Index and hcl.GetAttr. These are part of the implementation of indexing and attribute lookup in the native syntax expression language too, so the new error messages will apply to problems using those operators. (#474)
    Source code(tar.gz)
    Source code(zip)
  • v2.10.0(Apr 20, 2021)

    v2.10.0 (April 20, 2021)

    Enhancements

    • dynblock,hcldec: Using dynblock in conjunction with hcldec can now decode blocks with unknown dynamic for_each arguments as entirely unknown values (#461)
    • hclsyntax: Some syntax errors during parsing of the inside of ${ ... } template interpolation sequences will now produce an extra hint message about the need to escape as $${ when trying to include interpolation syntax for other languages like shell scripting, AWS IAM policies, etc. (#462)
    Source code(tar.gz)
    Source code(zip)
  • v2.9.1(Mar 10, 2021)

  • v2.8.2(Jan 6, 2021)

    Bugs Fixed

    • hclsyntax: Fix panic for marked collection splat. (#436)
    • hclsyntax: Fix panic for marked template loops. (#437)
    • hclsyntax: Fix for expression marked conditional.(#438)
    • hclsyntax: Mark objects with keys that are sensitive. (#440)
    Source code(tar.gz)
    Source code(zip)
  • v2.8.1(Dec 17, 2020)

    Bugs Fixed

    • hclsyntax: Fix panic when expanding marked function arguments. (#429)
    • hclsyntax: Error when attempting to use a marked value as an object key. (#434)
    • hclsyntax: Error when attempting to use a marked value as an object key in expressions. (#433)
    Source code(tar.gz)
    Source code(zip)
  • v2.8.0(Dec 7, 2020)

    Enhancements

    • hclsyntax: Expression grouping parentheses will now be reflected by an explicit node in the AST, whereas before they were only considered during parsing. (#426)

    Bugs Fixed

    • hclwrite: The parser will now correctly include the ( and ) tokens when an expression is surrounded by parentheses. Previously it would incorrectly recognize those tokens as being extraneous tokens outside of the expression. (#426)
    • hclwrite: The formatter will now remove (rather than insert) spaces between the ! (unary boolean "not") operator and its subsequent operand. (#403)
    • hclsyntax: Unmark conditional values in expressions before checking their truthfulness (#427)
    Source code(tar.gz)
    Source code(zip)
  • v2.7.2(Nov 30, 2020)

    Bugs Fixed

    • gohcl: Fix panic when decoding into type containing value slices. (#335)
    • hclsyntax: The unusual expression null[*] was previously always returning an unknown value, even though the rules for [*] normally call for it to return an empty tuple when applied to a null. As well as being a surprising result, it was particularly problematic because it violated the rule that a calling application may assume that an expression result will always be known unless the application itself introduces unknown values via the evaluation context. null[*] will now produce an empty tuple. (#416)
    • hclsyntax: Fix panic when traversing a list, tuple, or map with cty "marks" (#424)
    Source code(tar.gz)
    Source code(zip)
  • v2.7.1(Nov 18, 2020)

  • v2.7.0(Oct 14, 2020)

    Enhancements

    • json: There is a new function ParseWithStartPos, which allows overriding the starting position for parsing in case the given JSON bytes are a fragment of a larger document, such as might happen when decoding with encoding/json into a json.RawMessage. (#389)
    • json: There is a new function ParseExpression, which allows parsing a JSON string directly in expression mode, whereas previously it was only possible to parse a JSON string in body mode. (#381)
    • hclwrite: Block type now supports SetType and SetLabels, allowing surgical changes to the type and labels of an existing block without having to reconstruct the entire block. (#340)

    Bugs Fixed

    • hclsyntax: Fix confusing error message for bitwise OR operator (#380)
    • hclsyntax: Several bug fixes for using HCL with values containing cty "marks" (#404, #406, #407)
    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(Jun 4, 2020)

    Enhancements

    • hcldec: Add a new Spec, ValidateSpec, which allows custom validation of values at decode-time. (#387)

    Bugs Fixed

    • hclsyntax: Fix panic with combination of sequences and null arguments (#386)
    • hclsyntax: Fix handling of unknown values and sequences (#386)
    Source code(tar.gz)
    Source code(zip)
  • v2.5.1(May 14, 2020)

  • v2.5.0(May 6, 2020)

  • v2.4.0(Apr 13, 2020)

    v2.4.0 (Apr 13, 2020)

    Enhancements

    • The Unicode data tables that HCL uses to produce user-perceived "column" positions in diagnostics and other source ranges are now updated to Unicode 12.0.0, which will cause HCL to produce more accurate column numbers for combining characters introduced to Unicode since Unicode 9.0.0.

    Bugs Fixed

    • json: Fix panic when parsing malformed JSON. (#358)
    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Jan 3, 2020)

    Enhancements

    • ext/tryfunc: Optional functions try and can to include in your hcl.EvalContext when evaluating expressions, which allow users to make decisions based on the success of expressions. (#330)
    • ext/typeexpr: Now has an optional function convert which you can include in your hcl.EvalContext when evaluating expressions, allowing users to convert values to specific type constraints using the type constraint expression syntax. (#330)
    • ext/typeexpr: A new cty capsule type typeexpr.TypeConstraintType which, when used as either a type constraint for a function parameter or as a type constraint for a hcldec attribute specification will cause the given expression to be interpreted as a type constraint expression rather than a value expression. (#330)
    • ext/customdecode: An optional extension that allows overriding the static decoding behavior for expressions either in function arguments or hcldec attribute specifications. (#330)
    • ext/customdecode: New cty capsuletypes customdecode.ExpressionType and customdecode.ExpressionClosureType which, when used as either a type constraint for a function parameter or as a type constraint for a hcldec attribute specification will cause the given expression (and, for the closure type, also the hcl.EvalContext it was evaluated in) to be captured for later analysis, rather than immediately evaluated. (#330)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Jan 3, 2020)

    Enhancements

    • hcldec: Attribute evaluation (as part of AttrSpec or BlockAttrsSpec) now captures expression evaluation metadata in any errors it produces during type conversions, allowing for better feedback in calling applications that are able to make use of this metadata when printing diagnostic messages. (#329)

    Bugs Fixed

    • hclsyntax: IndexExpr, SplatExpr, and RelativeTraversalExpr will now report a source range that covers all of their child expression nodes. Previously they would report only the operator part, such as ["foo"], [*], or .foo, which was problematic for callers using source ranges for code analysis. (#328)
    • hclwrite: Parser will no longer panic when the input includes index, splat, or relative traversal syntax. (#328)
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Nov 20, 2019)

    Enhancements

    • gohcl: When decoding into a struct value with some fields already populated, those values will be retained if not explicitly overwritten in the given HCL body, with similar overriding/merging behavior as json.Unmarshal in the Go standard library.
    • hclwrite: New interface to set the expression for an attribute to be a raw token sequence, with no special processing. This has some caveats, so if you intend to use it please refer to the godoc comments. (#320)

    Bugs Fixed

    • hclwrite: The Body.Blocks method was returing the blocks in an indefined order, rather than preserving the order of declaration in the source input. (#313)
    • hclwrite: The TokensForTraversal function (and thus in turn the Body.SetAttributeTraversal method) was not correctly handling index steps in traversals, and thus producing invalid results. (#319)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Jan 3, 2020)

    Initial release of HCL 2, which is a new implementation combining the HCL 1 language with the HIL expression language to produce a single language supporting both nested configuration structures and arbitrary expressions.

    HCL 2 has an entirely new Go library API and so is not a drop-in upgrade relative to HCL 1. It's possible to import both versions of HCL into a single program using Go's semantic import versioning mechanism:

    import (
        hcl1 "github.com/hashicorp/hcl"
        hcl2 "github.com/hashicorp/hcl/v2"
    )
    
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0-alpha.1(Jan 3, 2020)

Owner
HashiCorp
Consistent workflows to provision, secure, connect, and run any infrastructure for any application.
HashiCorp
Graph-based Declarative Configuration Language

Virgo Configuration Language Most configuration problems reduce to graphs, e.g. Dockerfiles and Makefiles But there are no graph-based configuration l

Matt Rickard 113 Aug 13, 2022
✨Clean and minimalistic environment configuration reader for Golang

Clean Env Minimalistic configuration reader Overview This is a simple configuration reading tool. It just does the following: reads and parses configu

Ilya Kaznacheev 732 Sep 21, 2022
12 factor configuration as a typesafe struct in as little as two function calls

Config Manage your application config as a typesafe struct in as little as two function calls. type MyConfig struct { DatabaseUrl string `config:"DAT

Jeremy Loy 317 Sep 2, 2022
JSON or YAML configuration wrapper with convenient access methods.

Config Package config provides convenient access methods to configuration stored as JSON or YAML. This is a fork of the original version. This version

Oleg Lebedev 254 Sep 26, 2022
Configure is a Go package that gives you easy configuration of your project through redundancy

Configure Configure is a Go package that gives you easy configuration of your project through redundancy. It has an API inspired by negroni and the fl

Harrison Shoebridge 56 Sep 21, 2022
An opinionated configuration loading framework for Containerized and Cloud-Native applications.

Opinionated configuration loading framework for Containerized and 12-Factor compliant applications. Read configurations from Environment Variables, an

Sherif Abdel-Naby 81 Sep 25, 2022
Load configuration in cascade from multiple backends into a struct

Confita is a library that loads configuration from multiple backends and stores it in a struct. Supported backends Environment variables JSON files Ya

Heetch 455 Sep 15, 2022
Small library to read your configuration from environment variables

envconfig envconfig is a library which allows you to parse your configuration from environment variables and fill an arbitrary struct. See the example

Vincent Rischmann 226 Sep 16, 2022
A minimalist Go configuration library

fig fig is a tiny library for loading an application's config file and its environment into a Go struct. Individual fields can have default values def

null 232 Sep 21, 2022
go-up! A simple configuration library with recursive placeholders resolution and no magic.

go-up! A simple configuration library with placeholders resolution and no magic. go-up provides a simple way to configure an application from multiple

Francesco 37 Mar 23, 2022
goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configuration file.

goconfig goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configur

Go Sidekick 0 May 30, 2022
Go configuration made easy!

gofigure Go configuration made easy! Just define a struct and call Gofigure Supports strings, ints/uints/floats, slices and nested structs Supports en

Ian Kent 65 Sep 26, 2022
Harvest configuration, watch and notify subscriber

Harvester Harvester is a configuration library which helps setting up and monitoring configuration values in order to dynamically reconfigure your app

Beat Labs 119 Sep 28, 2022
go implementation of lightbend's HOCON configuration library https://github.com/lightbend/config

HOCON (Human-Optimized Config Object Notation) Configuration library for working with the Lightbend's HOCON format. HOCON is a human-friendly JSON sup

Gürkan Kaymak 49 Sep 26, 2022
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP

config A small configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP. Example func main() {

Josh Betz 215 Sep 20, 2022
Golang library for managing configuration data from environment variables

envconfig import "github.com/kelseyhightower/envconfig" Documentation See godoc Usage Set some environment variables: export MYAPP_DEBUG=false export

Kelsey Hightower 4.3k Sep 27, 2022
Light weight, extensible configuration management library for Go. Built in support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

koanf (pronounced conf; a play on the Japanese Koan) is a library for reading configuration from different sources in different formats in Go applicat

Kailash Nadh 1.2k Sep 30, 2022
A golang package for parsing ini-style configuration files

Mini Mini is a simple ini configuration file parser. The ini syntax supported includes: The standard name=value Comments on new lines starting with #

Stephen Asbury 31 Jul 7, 2022
A dead simple configuration manager for Go applications

Store Store is a dead simple configuration manager for Go applications. I didn't like existing configuration management solutions like globalconf, tac

Ian P Badtrousers 263 Sep 26, 2022