├── .gitignore ├── hooks.yaml ├── ruby-stubs ├── ruby-validate ├── epp-validate ├── erb-validate ├── bolt-validate ├── r10k-validate ├── g10k-validate └── puppet-validate ├── pre_commit_fake_gem.gemspec ├── .pre-commit-hooks.yaml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hooks.yaml: -------------------------------------------------------------------------------- 1 | .pre-commit-hooks.yaml -------------------------------------------------------------------------------- /ruby-stubs/ruby-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `ruby -wc "#{file}" 2>&1` 6 | next if $CHILD_STATUS.exitstatus == 0 7 | puts "#{file}: failed ruby syntax check" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/epp-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `puppet epp validate "#{file}" 2>&1` 6 | next if $CHILD_STATUS.exitstatus == 0 7 | puts "#{file}: failed epp validation" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/erb-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `erb -x -P -T - -- "#{file}" | ruby -c 2>&1` 6 | next if $CHILD_STATUS.exitstatus == 0 7 | puts "#{file}: failed erb validation" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/bolt-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `puppet parser validate --tasks "#{file}" 2>&1` 6 | next if $CHILD_STATUS.exitstatus == 0 7 | puts "#{file}: failed plan validation" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/r10k-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `r10k puppetfile check --puppetfile="#{file}" 2>&1` 6 | next if $CHILD_STATUS.exitstatus == 0 7 | puts "#{file}: failed r10k validation" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/g10k-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | ARGV.each do |file| 5 | output = `g10k -dryrun -puppetfile -puppetfilelocation "#{file}" check 2>&1` 6 | next unless output =~ /^Error:/ 7 | puts "#{file}: failed g10k validation" 8 | puts output 9 | status = 1 10 | end 11 | 12 | exit status 13 | 14 | # vim: ft=ruby 15 | -------------------------------------------------------------------------------- /ruby-stubs/puppet-validate: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | status = 0 4 | options = [] 5 | ARGV.each do |arg| 6 | if arg =~ /^--.+=.+$/ 7 | options.append arg 8 | next 9 | end 10 | output = `puppet parser validate #{options.join(' ')} -- "#{arg}" 2>&1` 11 | next if $CHILD_STATUS.exitstatus == 0 12 | puts "#{arg}: failed Puppet validation" 13 | puts output 14 | status = 1 15 | end 16 | 17 | exit status 18 | 19 | # vim: ft=ruby 20 | -------------------------------------------------------------------------------- /pre_commit_fake_gem.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = 'pre_commit_fake_gem' 3 | s.version = '0' 4 | s.authors = 'Chris Kuehl' 5 | s.summary = 'pre-commit hooks for Puppet projects' 6 | s.description = 'pre-commit hooks for Puppet projects' 7 | 8 | s.bindir = 'ruby-stubs' 9 | s.executables = ['bolt-validate', 'erb-validate', 'epp-validate', 'g10k-validate', 'puppet-validate', 'r10k-validate', 'ruby-validate'] 10 | end 11 | -------------------------------------------------------------------------------- /.pre-commit-hooks.yaml: -------------------------------------------------------------------------------- 1 | - id: bolt-validate 2 | additional_dependencies: ['puppet'] 3 | description: Validate syntax of Bolt plans 4 | entry: bolt-validate 5 | files: plans/\w+\.pp$ 6 | language: ruby 7 | name: Validate Bolt plans 8 | 9 | - id: epp-validate 10 | additional_dependencies: ['puppet'] 11 | description: Validate syntax of Puppet EPP templates 12 | entry: epp-validate 13 | files: \.epp$ 14 | language: ruby 15 | name: Validate EPP templates 16 | 17 | - id: erb-validate 18 | description: Validate syntax of Ruby ERB templates 19 | entry: erb-validate 20 | files: \.erb$ 21 | language: ruby 22 | name: Validate ERB templates 23 | 24 | - id: g10k-validate 25 | description: Validate syntax of Puppetfile using g10k 26 | entry: g10k-validate 27 | files: Puppetfile$ 28 | language: ruby 29 | name: Validate g10k Puppetfile 30 | 31 | - id: puppet-lint 32 | additional_dependencies: ['puppet-lint'] 33 | description: Check Puppet manifests for stylistic problems 34 | entry: puppet-lint 35 | files: \.pp$ 36 | language: ruby 37 | name: puppet-lint 38 | 39 | - id: puppet-validate 40 | additional_dependencies: ['puppet'] 41 | description: Validate syntax of Puppet manifests 42 | entry: puppet-validate 43 | files: \.pp$ 44 | exclude: plans/ 45 | language: ruby 46 | name: Validate Puppet manifests 47 | 48 | - id: r10k-validate 49 | additional_dependencies: ['r10k'] 50 | description: Validate syntax of Puppetfile using r10k 51 | entry: r10k-validate 52 | files: Puppetfile$ 53 | language: ruby 54 | name: Validate r10k Puppetfile 55 | 56 | - id: ruby-validate 57 | additional_dependencies: ['ruby'] 58 | description: Validate syntax of ruby code 59 | entry: ruby-validate 60 | files: \.rb$ 61 | language: ruby 62 | name: Validate ruby syntax 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Puppet pre-commit hooks 2 | ========= 3 | 4 | [pre-commit hooks](http://pre-commit.com/) for use on Puppet projects. 5 | 6 | Provides the following hooks: 7 | 8 | * **bolt-validate:** uses [`puppet parser validate --tasks`][puppet-parser] to check the syntax of 9 | Puppet bolt plans. 10 | 11 | * **epp-validate:** validates and syntax-checks [Puppet's epp templates][epp]. 12 | 13 | * **erb-validate:** compiles and syntax-checks [Ruby erb templates][erb]. 14 | 15 | * **g10k-validate:** uses [g10k][g10k] to validate [Puppetfile][puppetfile] syntax. 16 | 17 | * **puppet-lint:** uses [`puppet-lint`](http://puppet-lint.com/) to check for 18 | stylistic issues with Puppet manifests. 19 | 20 | * **puppet-validate:** uses [`puppet parser validate`][puppet-parser] to check the syntax of 21 | Puppet manifests. 22 | 23 | * **r10k-validate:** uses [r10k][r10k] to validate [Puppetfile][puppetfile] syntax. 24 | 25 | * **ruby-validate:** uses [`ruby -c`][ruby-c] to validate the syntax of ruby code. 26 | 27 | 28 | [epp]: https://docs.puppet.com/puppet/latest/lang_template_epp.html 29 | [erb]: https://puppet.com/docs/puppet/latest/lang_template_erb.html 30 | [g10k]: https://github.com/xorpaul/g10k 31 | [puppetfile]: https://puppet.com/docs/pe/latest/puppetfile.html 32 | [puppet-parser]: https://puppet.com/docs/puppet/latest/man/parser.html#EXAMPLES 33 | [r10k]: https://github.com/puppetlabs/r10k 34 | [rubocop]: https://github.com/rubocop-hq/rubocop 35 | [ruby-c]: https://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/options.html 36 | [yamllint]: https://github.com/adrienverge/yamllint 37 | 38 | ## Usage 39 | 40 | 1. Install [pre-commit](http://pre-commit.com/), if you haven't already. 41 | 42 | 2. Add the following lines to a file named `.pre-commit-config.yaml` in the 43 | root of your git repository: 44 | 45 | ```yaml 46 | - repo: https://github.com/chriskuehl/puppet-pre-commit-hooks.git 47 | rev: v2.1.0 48 | hooks: 49 | - id: bolt-validate 50 | - id: epp-validate 51 | - id: erb-validate 52 | - id: puppet-lint 53 | args: 54 | - --fail-on-warnings 55 | - id: puppet-validate 56 | - id: r10k-validate 57 | - id: ruby-validate 58 | ``` 59 | 60 | You'll almost certainly want to adjust the puppet-lint args for your 61 | project. I find the following most helpful: 62 | 63 | ```yaml 64 | - --no-80chars-check 65 | - --no-documentation-check 66 | - --no-puppet_url_without_modules-check 67 | ``` 68 | 69 | To check ruby *style* as well as *syntax*, you may find it useful 70 | to add a hook for [`rubocop`][rubocop]: 71 | 72 | ```yaml 73 | - repo: https://github.com/jumanjihouse/pre-commit-hooks 74 | rev: 1.11.0 75 | hooks: 76 | - id: reek 77 | - id: rubocop 78 | ``` 79 | 80 | To check yaml syntax, you may want to add a hook for [`yamllint`][yamllint]: 81 | 82 | ```yaml 83 | - repo: 'https://github.com/adrienverge/yamllint' 84 | rev: v1.15.0 85 | hooks: 86 | - id: 'yamllint' 87 | ``` 88 | 89 | 3. Run `pre-commit install` to add pre-commit git hooks. 90 | 91 | 4. Test the hooks work properly with `pre-commit run --all-files`. 92 | 93 | Any other arguments to `puppet-validate` will be fed directly to 94 | `puppet parser validate`, as long as they are in the format `--arg=value`. 95 | 96 | By default, the latest versions of `puppet` and `puppet-lint` are used. If 97 | you'd like to use a different version, you can pass `additional_dependencies` 98 | when definining the hooks. 99 | 100 | For example, if you're still using Puppet 3, you can use: 101 | 102 | ```yaml 103 | hooks: 104 | - id: puppet-validate 105 | additional_dependencies: ['puppet:<4'] 106 | ``` 107 | 108 | To see what dependencies you might want to change, take a look at 109 | `hooks.yaml` in this repo. 110 | --------------------------------------------------------------------------------