Skip to content

HCL 2.0 Transition

Martin Atkins edited this page Oct 2, 2019 · 2 revisions

NOTE: This is a historical guide showing a plan for releasing HCL 2 and for it to coexist with HCL 1 in this repository. The content here is no longer maintained and is retained here only for historical reference. For the latest information on version selection, please see the Version Selection guide.


For some time, we have been first prototyping and then building out a new implementation of HCL in the temporary repository hashicorp/hcl2. We built out this new implementation in a separate repository so that existing users of the prior HCL implementation could go on using it without disruption during development.

The new implementation, henceforth called HCL 2.0 in this document, is nearing completion and will see its first release in conjunction with the release of Terraform 0.12, which will be the first application to switch to HCL 2.0 from what we will now call HCL 1.0.

HCL 2.0 is largely compatible with HCL 1.0 from the perspective of users writing configuration -- at least, for configuration formats that follow common HCL idiom -- but 2.0 introduces an entirely new Go API with a different design approach that is intended to permit better error messages, more flexible decoding of configuration, and more robust support for the JSON syntax.

When HCL 2.0 is released, it will replace HCL 1.0 in the master branch of this repository, with HCL 1.0 instead published in a v1 branch and with tags starting at v1.0.0. Existing applications depending on HCL 1.0 will therefore need to use either vendoring or Go Modules to request 1.0 versions of HCL, rather than pulling the latest tree from the master branch.

Application codebases that are already using vendoring for HCL need not take any immediate action, since the copy of the HCL 1.0 tree within their own codebase will of course continue working as before. Codebases that are not using vendoring, or that need to upgrade to a newer version of HCL while continuing to use the 1.0 API.

We strongly encourage adding a constrained dependency on HCL for 1.0 versions soon, in order to ensure correct behavior once HCL 2.0 is published in this repository.

HCL 1.0 Constraints with dep

dep is a common tool choice for managing vendored dependencies in Go projects at the time of writing. To use HCL 1.0 in a dep-managed project, use a [[constraint]] block in Gopkg.toml:

[[constraint]]
  name = "github.com/hashicorp/hcl"
  version = "^1.0.0"

HCL 1.0 usage with Go Modules

Go 1.11 has introduced Go Modules as an experiment, with the intent of it becoming the primary dependency management approach in Go 1.12.

If your project will use Go Modules with Go 1.11, depending on the HCL 1.0 package paths is generally sufficient to remain on HCL 1.0:

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

This is sufficient because HCL 2.0 will be published as major version 2, and so it will be used via paths containing the v2 indication:

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

When using Go Modules, it is straightforward to import both versions of HCL into your program at the same time if necessary, which may for example be used to write a helper tool for migrating configuration files that may use some of the small number of HCL 1.0 structures that are not compatible with 2.0.

Vendoring with Go Modules

Go Modules in Go 1.11 can also be used as a tool for managing a vendor directory, which then allows the resulting directory to be used even When Go Modules support is unavailable or disabled.

To construct a vendor directory, run the following command from the directory where the vendor directory should be placed:

  • go mod vendor

If you commit the contents of the generated vendor directory to version control, it can then be used when Go Modules support is unavailable (older versions of Go) or disabled (e.g. working in a GOPATH on Go 1.11).

Installing HCL 1.0 with go get

The go get command in Go versions prior to Go 1.11 is not able to install specific versions of remote repositories, instead always selecting the master branch. It will therefore be impossible to use go get in these Go versions directly to install HCL 1.0 once HCL 2.0 is published.

Instead, you must either check out the repository and select a v1 tag manually, or use go get to install from the master branch and then switch branches using git commands within the created directory.

With a Modules-enabled go tool, specific versions can be selected using a new syntax for go get:

  • go get github.com/hashicorp/hcl@1.0.0