Computers are great at automatically checking things, and git has a mechanism for running hooks before events happen. Bosh these two things together and you can have git trigger anything you like before you're allowed to commit, which in turn means you can sanity check exactly what you're committing to make sure it meets whatever criteria you have.
To make it easy to manage my git hooks in a consistent fashion, I use a tool called overcommit. This comes with a config file to tell it what you want triggered when, and a bunch of standard plugins to choose from.
In a puppet repo for instance, I have it check
- bundler is happy everything's installed
- puppet-lint is happy with any changed puppet files
- Any JSON or YAML files involved in the commit have valid syntax
- Any shell scripts are valid (according to shellcheck)
- There is no trailing whitespace left in files
This usually means something like the following in
.overcommit.yml in the git repo
PreCommit: BundleCheck: enabled: true JsonSyntax: enabled: true PuppetLint: enabled: true ShellCheck: enabled: true YamlSyntax: enabled: true on_warn: fail
For the most part this works absolutely great. I have on occasion noticed that puppet-lint will let invalid puppet syntax slip through though which is irritating to find after you've pushed the changes up to the puppetmaster. The puppet command line tool has a validate subcommand however, so we can hook that into overcommit as a custom hook in the repo.
To do this we need to add our custom hook into the right directory, and we're adding a hook to run before commits, so it goes into
.git-hooks/pre_commit. Lets name it for what it does, validating puppet syntax. So into
puppet_validate.rb we put the following:
# .git-hooks/pre_commit/puppet_validate.rb module Overcommit::Hook::PreCommit class PuppetValidate < Base def run errors =  result = execute(%w(puppet parser validate), :args => applicable_files) return :pass if result.success? [:fail, result.stderr] end end end
Then we need to tell overcommit that it needs to run this custom hook as a check whenever we commit, that goes into
.overcommit.yml under the
PreCommit: PuppetValidate: enabled: true description: 'Validates puppet syntax' include: '**/*.pp'
Hey voila, along with all our other safety checks we're now checking that any puppet files added or changed in the repo have valid syntax.