go-puppet

The Puppet language in pure Go โ€” lexer, parser, Puppet::Pops AST, evaluator and catalog compiler, no cgo.

pure Go ยท zero cgo Puppet 8 grammar Puppet::Pops AST evaluator catalog compiler EPP/ERB + plans HCL2 front-end types via go-pcore lookup via go-hiera facts via go-facter 100% coverage 6 arches
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-puppet is a pure-Go (no cgo) implementation of the Puppet language. It parses Puppet 8 manifests into a faithful Puppet::Pops-style AST and compiles them to a catalog โ€” a resource graph with containment and relationship edges, serializable to Puppet catalog JSON. The type system is delegated to go-pcore, data binding to go-hiera, and facts to go-facter โ€” never reimplemented. A function/type registry seam lets go-ruby-puppet contribute Ruby-defined custom functions. 100% coverage, CI green across 6 arches.

Lexer & parser ready

A hand-written lexer and recursive-descent parser for the Puppet 8 grammar: literals and ${} interpolation, heredocs (@(TAG), :syntax, | margins, - chomp), data-type expressions, the full operator precedence ladder, selectors, if/unless/case, and the whitespace-sensitive [.

AST (Puppet::Pops) ready

A faithful Puppet::Pops-style node model โ€” resources, defaults, overrides, collectors, virtual/exported forms, class/define/node/function definitions, calls with lambdas, and relationship chaining โ€” with a compact Sexpr renderer for tests.

Evaluator ready

Scopes (top/node/local, $facts, $::top-scope), full expression semantics, data-type checks via go-pcore, class/defined-type instantiation (include/require/contain, inherits), iteration (each/map/filter/reduce/with/slice), and a built-in function set including lookup() via go-hiera.

Catalog compiler ready

Manifests compile to a catalog: a resource graph with containment, relationship (->/~>/<-/<~) and metaparameter (require/before/notify/subscribe) edges, serialized to the Puppet catalog JSON shape.

Registry seam ready

Evaluator.RegisterFunction(name, fn) adds or overrides functions at runtime โ€” the seam go-ruby-puppet plugs into to contribute Ruby-defined custom functions and types, without this library depending on the Ruby VM.

Templates, exported resources, plans & stdlib ready

EPP/ERB templates (epp/inline_epp/template/inline_template), resource defaults/overrides/collectors, exported resources, the Bolt-style plan/apply language and an extensive stdlib โ€” all implemented and evaluated (no fake stubs), through injectable template, exported-resource and plan-executor seams.

HCL2 front-end ready

hcl.Parse reads a Terraform-style HCL2 manifest and produces the very same ast.Program the native Puppet parser does, so an HCL2 manifest compiles to an identical catalog through the same evaluator. The v0.1 mapping covers resource/locals blocks, literals, templates, traversal, operators and relationships.

Type constructors & HCL2 v0.2 active

Still in progress, returning a clear error rather than a fake stub: Pcore type constructors beyond the scalar core (Timestamp(), SemVer(), โ€ฆ), and the HCL2 front-end’s v0.2 expression set (function calls, a ? b : c, for comprehensions, %{โ€ฆ} directives, additional block types).

A faithful implementation of the Puppet language in pure Go, cgo disabled, so it cross-compiles and embeds anywhere. Node kinds, grammar, precedence and evaluator semantics track the Puppet specification; every parse- and eval-error branch is covered by tests. It is a standalone, reusable module in the Puppet family alongside go-pcore, go-hiera and go-facter.