HCL是一种用于创建人类和机器友好型的结构化配置语言的工具包,可与命令行工具一起使用。尽管打算通常有用,但主要针对DevOps工具,服务器等。
注意:这是HCL的主要版本2,其GO API与主要版本1不兼容。这两个版本都可以在GO模块项目中进行选择。 HCl 2不能从不使用GO模块的GO项目中导入。有关更多信息,请参阅我们的版本选择指南。
HCL既具有本地语法,旨在为人类阅读和写作令人愉快,也是一个基于JSON的变体,可以使机器更容易生成和解析。
HCl本地语法的灵感来自libucl,nginx配置等。
它包括一个表达式语法,该语法允许基本的内联计算,并在调用应用程序的支持下,将变量和功能用于更动态的配置语言。
HCL提供了一组构造,可以通过调用应用程序将其用于构造配置语言。该应用程序定义了预期的属性名称和嵌套块类型,HCL解析了配置文件,验证其符合预期结构的内容,并返回该应用程序可以用于进一步处理的高级对象。
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 )
}
可用于更低级别的API,用于需要对配置的解析,解码和评估进行更多控制的应用程序。有关更多信息,请参阅包装文档。
HCL的新来者经常问:为什么不JSON,YAML等?
JSON和YAML是用于序列化数据结构的格式,而HCl是一种专门设计用于构建结构化配置格式的语法和API。
HCL试图在通用序列化格式(例如JSON和围绕Ruby等完整编程语言)建立的配置格式等通用序列化格式之间进行妥协。 HCL语法旨在容易被人类读取和撰写,并允许声明的逻辑允许其在更复杂的应用程序中使用。
HCl旨在作为围绕键值对和层次块构建的配置格式的基本语法,其结构由调用应用程序很好地定义,并且配置结构的这种定义允许在调用应用程序中提供更好的错误消息和更方便的定义。
不能否认JSON作为通用语言非常方便,可以在不同的软件之间进行互操作。因此,HCL定义了一个常见的配置模型,该模型可以从其本地语法或明确定义的等效JSON结构中解析。这允许将配置作为本机语法中的人为构成配置文件的混合物和JSON中的机器生成的文件提供。
HCL围绕两个主要概念建立:属性和块。在本机语法中,假设应用程序的配置文件可能看起来像这样:
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 " ]
}
}
JSON等效于此配置:以下内容:
{
"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 " ]
},
}
}
}
}
}
无论使用哪种语法,调用应用程序中的API都是相同的。对于更高级的用例,它可以直接与低级属性和块一起使用,或者可以使用一个解码器软件包来声明地提取到GO结构或动态值结构。
属性值可以是表达方式,也可以是文字值:
# Arithmetic with literals and application-provided variables
sum = 1 + addend
# String interpolation and templates
message = " Hello, ${ name } ! "
# Application-provided functions
shouty_message = upper (message)
尽管JSON语法不允许直接使用表达式,但插值语法允许在JSON字符串中使用任意表达式:
{
"sum" : " ${1 + addend} " ,
"message" : " Hello, ${name}! " ,
"shouty_message" : " ${upper(message)} "
}
有关更多信息,请参阅详细规范:
HCL的2.0版将HCL 1.0的功能与插值语言HIL的功能结合在一起,以产生支持任意表达式的单一配置语言。
这个新版本具有全新的解析器和GO API,没有直接迁移路径。尽管语法是相似的,但实现采用了一些非常不同的方法来改进原始实现中存在的一些“粗糙边缘”,并允许更强大的错误处理。
可以使用GO的语义导入版本机制将HCL 1和HCL 2同时导入到同一程序中:
import (
hcl1 "github.com/hashicorp/hcl"
hcl2 "github.com/hashicorp/hcl/v2"
)
HCL受到Vsevolod Stakhov的Libucl的启发。
HCL和HIL起源于Hashicorp Terraform,Mitchell Hashimoto撰写的每种解析器。
Fatih Arslan最初的HCL解析器被移植到Pure Go(从YACC)移植。新的本机语法解析器的结构相关部分构建了该作品。
马丁·阿特金斯(Martin Atkins)将原始的Hil Parser移植到Pure Go(从Yacc)移植。新的本机语法解析器的表达相关部分构建在该作品的基础上。
HCL 2将原始的HCL和HIL语言融合到了这种单一的新语言中,它基于Martin Atkins在ZCL的设计和原型制作作品。