HCL es un kit de herramientas para crear lenguajes de configuración estructurados que son compatibles con las herramientas de línea de comandos humanos y de línea humana y máquina. Aunque está destinado a ser generalmente útil, se dirige principalmente a las herramientas, servidores, etc. DevOps, etc.
Nota: Esta es la versión 2 principal de HCL, cuya API GO es incompatible con la versión principal 1. Ambas versiones están disponibles para la selección de proyectos de módulos GO. HCL 2 cannot be imported from Go projects that are not using Go Modules. Para obtener más información, consulte nuestra Guía de selección de versión.
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.
La sintaxis nativa de HCL está inspirada en Libucl, Nginx Configuration y otros.
Incluye una sintaxis de expresión que permite el cálculo básico en línea y, con el soporte de la aplicación de llamada, el uso de variables y funciones para lenguajes de configuración más dinámicos.
HCL proporciona un conjunto de construcciones que pueden ser utilizadas por una aplicación de llamada para construir un lenguaje de configuración. La aplicación define qué nombres de atributos y tipos de bloques anidados se esperan, y HCL analiza el archivo de configuración, verifica que se ajuste a la estructura esperada y devuelve objetos de alto nivel que la aplicación puede usar para un procesamiento adicional.
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 )
}
Una API de nivel inferior está disponible para aplicaciones que necesitan más control sobre el análisis, la decodificación y la evaluación de la configuración. Para obtener más información, consulte la documentación del paquete.
Los recién llegados a HCL a menudo preguntan: ¿Por qué no JSON, YAML, etc.?
Mientras que JSON y YAML son formatos para serializar estructuras de datos, HCL es una sintaxis y una API específicamente diseñada para construir formatos de configuración estructurados.
HCL intenta lograr un compromiso entre los formatos de serialización genéricos como JSON y los formatos de configuración construidos alrededor de lenguajes de programación completos como 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 se pretende como una sintaxis base para formatos de configuración creados en torno a pares de valores clave y bloques jerárquicos cuya estructura está bien definida por la aplicación de llamada, y esta definición de la estructura de configuración permite mejores mensajes de error y una definición más conveniente dentro de la aplicación de llamadas .
It can't be denied that JSON is very convenient as a lingua franca for interoperability between different pieces of software. Debido a esto, HCl define un modelo de configuración común que se puede analizar desde su sintaxis nativa o de una estructura JSON equivalente bien definida. Esto permite que la configuración se proporcione como una mezcla de archivos de configuración autorizados por humanos en la sintaxis nativa y los archivos generados por la máquina en JSON.
HCL se basa en dos conceptos principales: atributos y bloques . En la sintaxis nativa, un archivo de configuración para una aplicación hipotética podría verse algo así:
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 " ]
}
}
El equivalente JSON de esta configuración es el siguiente:
{
"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 " ]
},
}
}
}
}
}
Independientemente de qué sintaxis se use, la API dentro de la aplicación de llamadas es la misma. Puede funcionar directamente con los atributos y bloques de bajo nivel, para casos de uso más avanzados, o puede usar uno de los paquetes de decodificadores para extraer declarativamente en estructuras GO o de valor dinámico.
Los valores de los atributos pueden ser expresiones, así como solo valores literales:
# Arithmetic with literals and application-provided variables
sum = 1 + addend
# String interpolation and templates
message = " Hello, ${ name } ! "
# Application-provided functions
shouty_message = upper (message)
Aunque la sintaxis JSON no permite el uso directo de expresiones, la sintaxis de interpolación permite el uso de expresiones arbitrarias dentro de las cadenas JSON:
{
"sum" : " ${1 + addend} " ,
"message" : " Hello, ${name}! " ,
"shouty_message" : " ${upper(message)} "
}
Para obtener más información, consulte las especificaciones detalladas:
La versión 2.0 de HCL combina las características de HCL 1.0 con las del lenguaje de interpolación HIL para producir un solo lenguaje de configuración que admite expresiones arbitrarias.
Esta nueva versión tiene una API analizadora y GO completamente nueva, sin una ruta de migración directa. Aunque la sintaxis es similar, la implementación adopta algunos enfoques muy diferentes para mejorar algunos "bordes aproximados" que existían con la implementación original y para permitir un manejo de errores más sólido.
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"
)
HCL se inspiró fuertemente en Libucl, por Vsevolod Stakhov.
HCL y HIL se originan en Hashicorp Terraform, con los analizadores originales para cada uno escrito por Mitchell Hashimoto.
El analizador HCL original fue portado a Pure Go (de YACC) por Fatih Arslan. Las partes relacionadas con la estructura del nuevo analizador de sintaxis nativa se basan en ese trabajo.
El analizador original de Hil fue portado a Pure Go (de YACC) por Martin Atkins. Las partes relacionadas con la expresión del nuevo analizador de sintaxis nativa se basan en ese trabajo.
HCL 2, que fusionó los idiomas originales de HCL y HIL en este nuevo lenguaje único, se basa en el trabajo de diseño y creación de prototipos de Martin Atkins en ZCL.