Merge pull request #538 from tonistiigi/vars-multi-file
						commit
						7d2e30096b
					
				@ -1,108 +0,0 @@
 | 
			
		||||
// Package hclsimple is a higher-level entry point for loading HCL
 | 
			
		||||
// configuration files directly into Go struct values in a single step.
 | 
			
		||||
//
 | 
			
		||||
// This package is more opinionated than the rest of the HCL API. See the
 | 
			
		||||
// documentation for function Decode for more information.
 | 
			
		||||
package hclsimple
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/hashicorp/hcl/v2"
 | 
			
		||||
	"github.com/hashicorp/hcl/v2/gohcl"
 | 
			
		||||
	"github.com/hashicorp/hcl/v2/hclsyntax"
 | 
			
		||||
	"github.com/hashicorp/hcl/v2/json"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Decode parses, decodes, and evaluates expressions in the given HCL source
 | 
			
		||||
// code, in a single step.
 | 
			
		||||
//
 | 
			
		||||
// The main HCL API is built to allow applications that need to decompose
 | 
			
		||||
// the processing steps into a pipeline, with different tasks done by
 | 
			
		||||
// different parts of the program: parsing the source code into an abstract
 | 
			
		||||
// representation, analysing the block structure, evaluating expressions,
 | 
			
		||||
// and then extracting the results into a form consumable by the rest of
 | 
			
		||||
// the program.
 | 
			
		||||
//
 | 
			
		||||
// This function does all of those steps in one call, going directly from
 | 
			
		||||
// source code to a populated Go struct value.
 | 
			
		||||
//
 | 
			
		||||
// The "filename" and "src" arguments describe the input configuration. The
 | 
			
		||||
// filename is used to add source location context to any returned error
 | 
			
		||||
// messages and its suffix will choose one of the two supported syntaxes:
 | 
			
		||||
// ".hcl" for native syntax, and ".json" for HCL JSON. The src must therefore
 | 
			
		||||
// contain a sequence of bytes that is valid for the selected syntax.
 | 
			
		||||
//
 | 
			
		||||
// The "ctx" argument provides variables and functions for use during
 | 
			
		||||
// expression evaluation. Applications that need no variables nor functions
 | 
			
		||||
// can just pass nil.
 | 
			
		||||
//
 | 
			
		||||
// The "target" argument must be a pointer to a value of a struct type,
 | 
			
		||||
// with struct tags as defined by the sibling package "gohcl".
 | 
			
		||||
//
 | 
			
		||||
// The return type is error but any non-nil error is guaranteed to be
 | 
			
		||||
// type-assertable to hcl.Diagnostics for applications that wish to access
 | 
			
		||||
// the full error details.
 | 
			
		||||
//
 | 
			
		||||
// This is a very opinionated function that is intended to serve the needs of
 | 
			
		||||
// applications that are just using HCL for simple configuration and don't
 | 
			
		||||
// need detailed control over the decoding process. Because this function is
 | 
			
		||||
// just wrapping functionality elsewhere, if it doesn't meet your needs then
 | 
			
		||||
// please consider copying it into your program and adapting it as needed.
 | 
			
		||||
func Decode(filename string, src []byte, ctx *hcl.EvalContext, target interface{}) error {
 | 
			
		||||
	var file *hcl.File
 | 
			
		||||
	var diags hcl.Diagnostics
 | 
			
		||||
 | 
			
		||||
	switch suffix := strings.ToLower(filepath.Ext(filename)); suffix {
 | 
			
		||||
	case ".hcl":
 | 
			
		||||
		file, diags = hclsyntax.ParseConfig(src, filename, hcl.Pos{Line: 1, Column: 1})
 | 
			
		||||
	case ".json":
 | 
			
		||||
		file, diags = json.Parse(src, filename)
 | 
			
		||||
	default:
 | 
			
		||||
		diags = diags.Append(&hcl.Diagnostic{
 | 
			
		||||
			Severity: hcl.DiagError,
 | 
			
		||||
			Summary:  "Unsupported file format",
 | 
			
		||||
			Detail:   fmt.Sprintf("Cannot read from %s: unrecognized file format suffix %q.", filename, suffix),
 | 
			
		||||
		})
 | 
			
		||||
		return diags
 | 
			
		||||
	}
 | 
			
		||||
	if diags.HasErrors() {
 | 
			
		||||
		return diags
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	diags = gohcl.DecodeBody(file.Body, ctx, target)
 | 
			
		||||
	if diags.HasErrors() {
 | 
			
		||||
		return diags
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DecodeFile is a wrapper around Decode that first reads the given filename
 | 
			
		||||
// from disk. See the Decode documentation for more information.
 | 
			
		||||
func DecodeFile(filename string, ctx *hcl.EvalContext, target interface{}) error {
 | 
			
		||||
	src, err := ioutil.ReadFile(filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			return hcl.Diagnostics{
 | 
			
		||||
				{
 | 
			
		||||
					Severity: hcl.DiagError,
 | 
			
		||||
					Summary:  "Configuration file not found",
 | 
			
		||||
					Detail:   fmt.Sprintf("The configuration file %s does not exist.", filename),
 | 
			
		||||
				},
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return hcl.Diagnostics{
 | 
			
		||||
			{
 | 
			
		||||
				Severity: hcl.DiagError,
 | 
			
		||||
				Summary:  "Failed to read configuration",
 | 
			
		||||
				Detail:   fmt.Sprintf("Can't read %s: %s.", filename, err),
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Decode(filename, src, ctx, target)
 | 
			
		||||
}
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue