hcl2: github.com/hashicorp/hcl2/hclpack Index | Examples | Files

package hclpack

import "github.com/hashicorp/hcl2/hclpack"

Package hclpack provides a straightforward representation of HCL block/body structure that can be easily serialized and deserialized for compact transmission (e.g. over a network) without transmitting the full source code.

Expressions are retained in native syntax source form so that their evaluation can be delayed until a package structure is decoded by some other system that has enough information to populate the evaluation context.

Packed structures retain source location information but do not retain actual source code. To make sense of source locations returned in diagnostics and via other APIs the caller must somehow gain access to the original source code that the packed representation was built from, which is a problem that must be solved somehow by the calling application.

Code:

src := `
	service "example" {
	  priority = 2
	  platform {
		os   = "linux"
		arch = "amd64"
	  }
	  process "web" {
	    exec = ["./webapp"]
	  }
	  process "worker" {
	    exec = ["./worker"]
	  }
	}
	`

body, diags := hclpack.PackNativeFile([]byte(src), "example.svc", hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() {
    fmt.Fprintf(os.Stderr, "Failed to parse: %s", diags.Error())
    return
}

jb, err := body.MarshalJSON()
if err != nil {
    fmt.Fprintf(os.Stderr, "Failed to marshal: %s", err)
    return
}

// Normally the compact form is best, but we'll indent just for the sake
// of this example so the result is readable.
var buf bytes.Buffer
json.Indent(&buf, jb, "", " ")
os.Stdout.Write(buf.Bytes())

Output:

{
 "r": {
  "b": [
   {
    "h": [
     "service",
     "example"
    ],
    "b": {
     "a": {
      "priority": {
       "s": "2",
       "r": "ChAKDA4QDhA"
      }
     },
     "b": [
      {
       "h": [
        "platform"
       ],
       "b": {
        "a": {
         "arch": {
          "s": "\"amd64\"",
          "r": "IiwiJCYsKCo"
         },
         "os": {
          "s": "\"linux\"",
          "r": "FiAWGBogHB4"
         }
        },
        "r": "Li4"
       },
       "r": "EhQSFA"
      },
      {
       "h": [
        "process",
        "web"
       ],
       "b": {
        "a": {
         "exec": {
          "s": "[\"./webapp\"]",
          "r": "OEA4OjxAPD4"
         }
        },
        "r": "QkI"
       },
       "r": "MDYwMjQ2"
      },
      {
       "h": [
        "process",
        "worker"
       ],
       "b": {
        "a": {
         "exec": {
          "s": "[\"./worker\"]",
          "r": "TFRMTlBUUFI"
         }
        },
        "r": "VlY"
       },
       "r": "REpERkhK"
      }
     ],
     "r": "WFg"
    },
    "r": "AggCBAYI"
   }
  ],
  "r": "Wlo"
 },
 "s": [
  "example.svc"
 ],
 "p": "BAQEAA4OAAICABISAggMABAQAAYGAAICAggIABAQAgYKAAQEAAoKAAICAAoKAAICAgYGAAgIAAYGAAICAAoKAAICAgoKAggIAA4OAAICAAoKAgwQAAgIAAYGAAICABYWAgoKAggIAA4OAAICABAQAgwQAAgIAAYGAAICABYWAgoKAgYGAgQE"
}

Index

Examples

Package Files

didyoumean.go doc.go expression.go exprsourcetype_string.go json_marshal.go pack_native.go positions_packed.go structure.go vlq.go

type Attribute Uses

type Attribute struct {
    Expr Expression

    Range, NameRange hcl.Range
}

Attribute represents an attribute definition within a body.

type Block Uses

type Block struct {
    Type   string
    Labels []string
    Body   Body

    DefRange, TypeRange hcl.Range
    LabelRanges         []hcl.Range
}

Block represents a nested block within a body.

type Body Uses

type Body struct {
    Attributes  map[string]Attribute
    ChildBlocks []Block

    MissingItemRange_ hcl.Range
}

Body is an implementation of hcl.Body.

func PackNativeFile Uses

func PackNativeFile(src []byte, filename string, start hcl.Pos) (*Body, hcl.Diagnostics)

PackNativeFile parses the given source code as HCL native syntax and packs it into a hclpack Body ready to be marshalled.

If the given source code contains syntax errors then error diagnostics will be returned. A non-nil body might still be returned in this case, which allows a cautious caller to still do certain analyses on the result.

func (*Body) Content Uses

func (b *Body) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics)

Content is an implementation of the method of the same name on hcl.Body.

When Content is called directly on a hclpack.Body, all child block bodies are guaranteed to be of type *hclpack.Body, so callers can type-assert to obtain a child Body in order to serialize it separately if needed.

func (*Body) JustAttributes Uses

func (b *Body) JustAttributes() (hcl.Attributes, hcl.Diagnostics)

JustAttributes is an implementation of the method of the same name on hcl.Body.

func (*Body) MarshalJSON Uses

func (b *Body) MarshalJSON() ([]byte, error)

MarshalJSON is an implementation of Marshaler from encoding/json, allowing bodies to be included in other types that are JSON-marshalable.

The result of MarshalJSON is optimized for compactness rather than easy human consumption/editing. Use UnmarshalJSON to decode it.

func (*Body) MissingItemRange Uses

func (b *Body) MissingItemRange() hcl.Range

MissingItemRange is an implementation of the method of the same name on hcl.Body.

func (*Body) PartialContent Uses

func (b *Body) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics)

PartialContent is an implementation of the method of the same name on hcl.Body.

The returned "remain" body may share some backing objects with the receiver, so neither the receiver nor the returned remain body, or any descendent objects within them, may be mutated after this method is used.

When Content is called directly on a hclpack.Body, all child block bodies and the returned "remain" body are guaranteed to be of type *hclpack.Body, so callers can type-assert to obtain a child Body in order to serialize it separately if needed.

func (*Body) UnmarshalJSON Uses

func (b *Body) UnmarshalJSON(data []byte) error

UnmarshalJSON is an implementation of Unmarshaler from encoding/json, allowing bodies to be included in other types that are JSON-unmarshalable.

type ExprSourceType Uses

type ExprSourceType rune

ExprSourceType defines the syntax type used for an expression's source code, which is then used to select a suitable parser for it when evaluating.

const (
    // ExprNative indicates that an expression must be parsed as native
    // expression syntax, with hclsyntax.ParseExpression.
    ExprNative ExprSourceType = 'N'

    // ExprTemplate indicates that an expression must be parsed as native
    // template syntax, with hclsyntax.ParseTemplate.
    ExprTemplate ExprSourceType = 'T'

    // ExprLiteralJSON indicates that an expression must be parsed as JSON and
    // treated literally, using cty/json. This can be used when populating
    // literal attribute values from a non-HCL source.
    ExprLiteralJSON ExprSourceType = 'L'
)

func (ExprSourceType) String Uses

func (i ExprSourceType) String() string

type Expression Uses

type Expression struct {
    // Source is the raw source code of the expression, which should be parsed
    // as the syntax specified by SourceType.
    Source     []byte
    SourceType ExprSourceType

    // Range_ and StartRange_ describe the physical extents of the expression
    // in the original source code. SourceRange_ is its entire range while
    // StartRange is just the tokens that introduce the expression type. For
    // simple expression types, SourceRange and StartRange are identical.
    Range_, StartRange_ hcl.Range
}

Expression is an implementation of hcl.Expression in terms of some raw expression source code. The methods of this type will first parse the source code and then pass the call through to the real expression that is produced.

func (*Expression) Parse Uses

func (e *Expression) Parse() (hcl.Expression, hcl.Diagnostics)

Parse attempts to parse the source code of the receiving expression using its indicated source type, returning the expression if possible and any diagnostics produced during parsing.

func (*Expression) Range Uses

func (e *Expression) Range() hcl.Range

func (*Expression) StartRange Uses

func (e *Expression) StartRange() hcl.Range

func (*Expression) UnwrapExpression Uses

func (e *Expression) UnwrapExpression() hcl.Expression

UnwrapExpression parses and returns the underlying expression, if possible.

This is essentially the same as Parse but without the ability to return an error; it is here only to support the static analysis facilities in the main HCL package (ExprList, ExprMap, etc). If any error is encountered during parsing, the result is a static expression that always returns cty.DynamicVal.

This function does not impose any further conversions on the underlying expression, so the result may still not be suitable for the static analysis functions, depending on the source type of the expression and thus what type of physical expression it becomes after decoding.

func (*Expression) Value Uses

func (e *Expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics)

Value implements the Value method of hcl.Expression but with the additional step of first parsing the expression source code. This implementation is unusual in that it can potentially return syntax errors, whereas other Value implementations usually work with already-parsed expressions.

func (*Expression) Variables Uses

func (e *Expression) Variables() []hcl.Traversal

Variables implements the Variables method of hcl.Expression but with the additional step of first parsing the expression source code.

Since this method cannot return errors, it will return a nil slice if parsing fails, indicating that no variables are present. This is okay in practice because a subsequent call to Value would fail with syntax errors regardless of what variables are in the context.

Package hclpack imports 12 packages (graph) and is imported by 5 packages. Updated 2019-04-29. Refresh now. Tools for package owners.