HCL ist ein Toolkit zum Erstellen strukturierter Konfigurationssprachen, die sowohl menschlich als auch maschinenfreundlich sind, für die Verwendung mit Befehlszeilen-Tools. Obwohl es im Allgemeinen nützlich ist, richtet es sich hauptsächlich um DevOps -Tools, Server usw. usw.
Hinweis: Dies ist die Hauptversion 2 von HCL, deren Go -API mit der Hauptversion 1 unvereinbar ist. Beide Versionen können in Go -Modulprojekten ausgewählt werden. HCL 2 kann nicht aus GO -Projekten importiert werden, die keine Go -Module verwenden. Weitere Informationen finden Sie in unserem Versionsauswahlhandbuch.
HCL verfügt sowohl über eine native Syntax , die für den Menschen angenehm zu lesen und zu schreiben ist, als auch eine JSON-basierte Variante, die für Maschinen leichter zu erzeugen und analysieren kann.
Die hcl native Syntax ist von Libucl, Nginx -Konfiguration und anderen inspiriert.
Es enthält eine Expressionssyntax, die eine grundlegende Inline -Berechnung und mit Unterstützung der aufrufenden Anwendung, Verwendung von Variablen und Funktionen für dynamischere Konfigurationssprachen ermöglicht.
HCL bietet eine Reihe von Konstrukten, die von einer aufrufenden Anwendung verwendet werden können, um eine Konfigurationssprache zu erstellen. Die Anwendung definiert, welche Attributnamen und verschachtelten Blocktypen erwartet werden, und HCl analysiert die Konfigurationsdatei, verifiziert, dass sie der erwarteten Struktur entspricht, und gibt hochrangige Objekte zurück, die die Anwendung für die weitere Verarbeitung verwenden kann.
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 )
}
Eine API auf niedrigerer Ebene ist für Anwendungen verfügbar, die mehr Kontrolle über die Parsen, Dekodierung und Bewertung der Konfiguration benötigen. Weitere Informationen finden Sie in der Paketdokumentation.
Neuankömmlinge von HCL fragen oft: Warum nicht JSON, YAML usw.?
Während JSON und YAML Formate für Serialisierungsdatenstrukturen sind, ist HCL eine Syntax und API, die speziell für das Erstellen strukturierter Konfigurationsformate entwickelt wurde.
HCL versucht, einen Kompromiss zwischen generischen Serialisierungsformaten wie JSON- und Konfigurationsformaten zu treffen, die sich um vollständige Programmiersprachen wie Ruby bauen. Die HCL -Syntax ist so konzipiert, dass sie leicht von Menschen gelesen und geschrieben werden kann und ermöglicht eine deklarative Logik, ihre Verwendung in komplexeren Anwendungen zu ermöglichen.
HCL ist als Basissyntax für Konfigurationsformate gedacht, die um Schlüsselwertpaare und hierarchische Blöcke basieren, deren Struktur durch die aufrufende Anwendung gut definiert ist, und diese Definition der Konfigurationsstruktur ermöglicht bessere Fehlermeldungen und bequemere Definition innerhalb der Anrufanwendung .
Es kann nicht geleugnet werden, dass JSON als Verkehrssprache für die Interoperabilität zwischen verschiedenen Softwareteilen sehr bequem ist. Aus diesem Grund definiert HCL ein gemeinsames Konfigurationsmodell, das entweder aus seiner nativen Syntax oder aus einer gut definierten äquivalenten JSON-Struktur analysiert werden kann. Auf diese Weise kann die Konfiguration als Mischung aus menschlichautorierten Konfigurationsdateien in der nativen Syntax- und maschinengenerierten Dateien in JSON bereitgestellt werden.
HCL basiert auf zwei Hauptkonzepten: Attribute und Blöcke . In der nativen Syntax könnte eine Konfigurationsdatei für eine hypothetische Anwendung so aussehen:
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 " ]
}
}
Das JSON -Äquivalent dieser Konfiguration ist Folgendes:
{
"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 " ]
},
}
}
}
}
}
Unabhängig davon, welche Syntax verwendet wird, ist die API innerhalb der aufrufenden Anwendung gleich. Es kann entweder direkt mit den Attributen und Blöcken auf niedriger Ebene für erweiterte Anwendungsfälle funktionieren oder eines der Decoderpakete verwenden, um entweder in GO-Strukturen oder in dynamische Wertstrukturen zu extrahieren.
Attributwerte können Ausdrücke sowie wörtliche Werte sein:
# Arithmetic with literals and application-provided variables
sum = 1 + addend
# String interpolation and templates
message = " Hello, ${ name } ! "
# Application-provided functions
shouty_message = upper (message)
Obwohl die JSON -Syntax nicht die direkte Verwendung von Ausdrücken zulässt, ermöglicht die Interpolationssyntax willkürliche Ausdrücke in JSON -Zeichenfolgen:
{
"sum" : " ${1 + addend} " ,
"message" : " Hello, ${name}! " ,
"shouty_message" : " ${upper(message)} "
}
Weitere Informationen finden Sie in den detaillierten Spezifikationen:
Version 2.0 von HCL kombiniert die Funktionen von HCL 1.0 mit denen der Interpolationssprache HIL, um eine einzige Konfigurationssprache zu erstellen, die willkürliche Ausdrücke unterstützt.
Diese neue Version hat einen völlig neuen Parser- und Go -API ohne direkte Migrationspfad. Obwohl die Syntax ähnlich ist, verfolgt die Implementierung einige sehr unterschiedliche Ansätze, um einige "grobe Kanten" zu verbessern, die mit der ursprünglichen Implementierung vorhanden waren, und um eine robustere Fehlerbehandlung zu ermöglichen.
Es ist möglich, sowohl HCL 1 als auch HCL 2 mit dem semantischen Importversioning -Mechanismus von GO in das gleiche Programm zu importieren:
import (
hcl1 "github.com/hashicorp/hcl"
hcl2 "github.com/hashicorp/hcl/v2"
)
HCL wurde stark von Libucl von Vsevolod Stakhov inspiriert.
HCL und HIL stammen aus Hashicorp -Terraform, wobei die ursprünglichen Parser für jedes von Mitchell Hashimoto geschrieben wurden.
Der ursprüngliche HCL -Parser wurde von Fatih Arslan auf Pure Go (von YACC) portiert. Die strukturbezogenen Teile des neuen nativen Syntax-Parsers bauen auf dieser Arbeit auf.
Der ursprüngliche Hil -Parser wurde von Martin Atkins auf Pure Go (von YACC) portiert. Die expressionsbezogenen Teile des neuen nativen Syntax-Parsers bauen auf dieser Arbeit auf.
HCL 2, das die ursprünglichen HCL- und HIL -Sprachen in diese einzelne neue Sprache verschmolzen, baut auf Design- und Prototyping -Arbeiten von Martin Atkins in ZCL auf.