/puppetcpp

A prototype Puppet compiler written in C++

Primary LanguageC++Apache License 2.0Apache-2.0

Puppet Compiler in C++

Build Status Code Coverage

Build History

This is a (very early) attempt to write a Puppet 4.x compiler in C++14.

Parser status:

  • Puppet 4.x compliant lexer
  • Puppet 4.x compliant parser
  • AST construction

Expression evaluator status:

  • literal expressions
  • variable assignment
  • + operator
  • - operator (binary)
  • - operator (unary)
  • * operator (binary)
  • * operator (unary)
  • / operator
  • % operator
  • << operator
  • >> operator
  • logical and
  • logical or
  • logical not
  • == operator
  • != operator
  • =~ operator
  • !~ operator
  • < operator
  • <= operator
  • > operator
  • >= operator
  • -> operator
  • ~> operator
  • <- operator
  • <~ operator
  • in operator
  • if expressions
  • unless expressions
  • selector expressions
  • case expressions
  • method call expressions
  • function call expressions
  • lambdas
  • resource expressions
  • resource metaparameters
  • virtual resource expressions
  • exported resource expressions
  • resource defaults expressions (see note below)
  • resource override expressions
  • class definition statements
  • defined type statements
  • node definition statements
  • resource collection statements
  • exported resource collection expressions (NYI: importing resources)
  • break statements
  • return statements
  • next statements
  • loading classes from modules
  • loading defined types from modules
  • access expressions
  • global scope
  • local scope
  • node scope
  • string interpolation
  • Puppet type aliases
  • custom functions written in Puppet
  • custom functions written in Ruby
  • custom types written in Puppet
  • custom types written in Ruby
  • external data binding (i.e. hiera)
  • module data functions in Ruby
  • module data functions in Puppet
  • EPP support
  • application orchestration (NYI: evaluation)

Note: resource default expressions use "static scoping" instead of "dynamic scoping"

Type system implemented:

  • Any
  • Array
  • Boolean
  • Callable
  • CatalogEntry
  • Collection
  • Data
  • Default
  • Enum
  • Float
  • Hash
  • Integer
  • Iterable
  • Iterator
  • Class
  • NotUndef
  • Numeric
  • Optional
  • Pattern
  • Regexp
  • Resource
  • Runtime
  • Scalar
  • String
  • Struct
  • Tuple
  • Type
  • Undef
  • Variant

Puppet functions implemented:

  • alert
  • assert_type
  • contain
  • create_resources
  • crit
  • debug
  • defined
  • digest
  • each
  • emerg
  • epp
  • err
  • fail
  • file
  • filter
  • fqdn_rand
  • generate
  • hiera
  • hiera_array
  • hiera_hash
  • hiera_include
  • include
  • info
  • inline_epp
  • inline_template
  • lookup
  • map
  • match
  • md5
  • new
  • notice
  • realize
  • reduce
  • regsubst
  • require
  • reverse_each
  • scanf
  • sha1
  • shellquote
  • slice
  • split
  • sprintf
  • step
  • tag
  • tagged
  • template
  • type
  • versioncmp
  • warning
  • with

Catalog compiling status:

  • Facts from files and Facter
  • JSON catalog generation

Running With Docker

The peterhuene/puppetcpp image on Docker Hub contains a pre-built version of the prototype compiler.

Use the following docker command to run the compiler:

$ docker run -it peterhuene/puppetcpp

This image is not yet automatically updated when commits are merged into master; it will be periodically updated when new features are merged.

Build Requirements

Pre-Build

All of the following examples start by assuming the current directory is the root of the repo.

Before building, use cmake to generate build files:

$ mkdir release
$ cd release
$ cmake ..

To generate a fully debug build use -DCMAKE_BUILD_TYPE=Debug when invoking cmake.

To speed up builds, it is recommended to use ccache as the "compiler":

$ cd release
$ CCACHE_SLOPPINESS=pch_defines,time_macros cmake .. -DCMAKE_C_COMPILER=$(which ccache) -DCMAKE_C_COMPILER_ARG1=cc -DCMAKE_CXX_COMPILER=$(which ccache) -DCMAKE_CXX_COMPILER_ARG1=c++

Note: the environment variable CCACHE_SLOPPINESS must be set to pch_defines,time_macros for precompiled headers to work with ccache.

Also consider using Ninja as a replacement for GNU Make:

$ cd release
$ cmake .. -GNinja -DDISABLE_PCH=1 -DCMAKE_C_COMPILER=$(which ccache) -DCMAKE_C_COMPILER_ARG1=cc -DCMAKE_CXX_COMPILER=$(which ccache) -DCMAKE_CXX_COMPILER_ARG1=c++

Then use ninja instead of make in the examples below.

Note: tracking precompiled header changes with ninja is currently unsupported in CMake so it is recommended to add -DDISABLE_PCH=1 when running cmake.

Build

Currently Boost 1.61 and later has a breaking change that prevents building this project; see the PR to revert the change.

Boost can be patched by simply updating include/boost/spirit/home/x3/operator/detail/sequence.hpp to the previous version. The previous version is available here.

To build puppetcpp, use 'make':

$ cd release
$ make

To build puppetcpp with debug information:

$ cd debug
$ make

Run

You can run puppetcpp from its output directory:

$ release/bin/puppetcpp help

For a debug build:

$ debug/bin/puppetcpp help

Test

You can run puppetcpp tests using the test target:

$ cd release
$ make test

For a debug build:

$ cd debug
$ make test

For verbose test output, run ctest instead of using the test target:

$ cd release
$ ctest -V

Install

You can install puppetcpp into your system:

$ cd release
$ make && sudo make install

By default, puppetcpp will install files into /usr/local/bin, /usr/local/lib, and /usr/local/include.

To install to a different location, set the install prefix:

$ cd release
$ cmake -DCMAKE_INSTALL_PREFIX=~/puppetcpp ..
$ make clean install

This would install puppetcpp into ~/puppetcpp/bin, ~/puppetcpp/lib, and ~/puppetcpp/include.

Uninstall

Run the following command to remove files that were previously installed:

$ sudo xargs rm < release/install_manifest.txt

Documentation

To generate API documentation, install doxygen 1.8.7 or later.

$ doxygen

To view the documentation, open html/index.html in a web browser.