Browse files

adds syntax checking before an rsync

  • Loading branch information...
1 parent eefe3f2 commit cc6073db68e92248ab18d085a8074bc10aa1526c @pitluga committed Feb 24, 2012
View
8 README.md
@@ -31,6 +31,11 @@ This will show you a list of the pending changes to be applied server-by-server.
Applies the pending changes to all the servers.
+ cap puppet:syntax_check
+
+Locally syntax checks all the puppet files and erb templates. Requires you to have puppet installed locally.
+
+
You can specify that one of your servers should not be puppeted by setting the :nopuppet flag to true, like so. It will then be skipped by all the above commands.
role :weird_thing, '33.33.33.33', :nopuppet => true
@@ -67,6 +72,9 @@ these are patterns that are passed as rsync --exclude flags when pushing your pu
determines whether the rsync commands for multiple servers are run in parallel threads or serially
+ set :puppet_syntax_check, true
+
+when true, will syntax check your puppet files and erb templates before rsyncing them to your servers.
### Handling Legacy Puppet
View
1 examples/vagrant/Capfile
@@ -14,6 +14,7 @@ require 'supply_drop'
set :puppet_destination, "~/supply_drop"
set :puppet_command, "puppet"
set :puppet_stream_output, true
+set :puppet_syntax_check, false
server '33.33.33.10', :web, :app
role :db, '33.33.33.11', :nopuppet => true
View
24 lib/supply_drop.rb
@@ -1,5 +1,6 @@
require 'supply_drop/rsync'
require 'supply_drop/async_enumerable'
+require 'supply_drop/syntax_checker'
require 'supply_drop/util'
Capistrano::Configuration.instance.load do
@@ -13,6 +14,7 @@
set :puppet_excludes, %w(.git .svn)
set :puppet_stream_output, false
set :puppet_parallel_rsync, true
+ set :puppet_syntax_check, true
namespace :bootstrap do
desc "installs puppet via rubygems on an osx host"
@@ -38,6 +40,24 @@
end
end
+ desc "checks the syntax of all *.pp and *.erb files"
+ task :syntax_check do
+ checker = SupplyDrop::SyntaxChecker.new(puppet_source)
+ logger.info "Sytax Checking..."
+ errors = false
+ checker.validate_puppet_files.each do |file, error|
+ logger.important "Puppet error: #{file}"
+ logger.important error
+ errors = true
+ end
+ checker.validate_templates.each do |file, error|
+ logger.important "Template error: #{file}"
+ logger.important error
+ errors = true
+ end
+ raise "syntax errors" if errors
+ end
+
desc "pushes the current puppet configuration to the server"
task :update_code, :except => { :nopuppet => true } do
servers = SupplyDrop::Util.optionally_async(find_servers_for_task(current_task), puppet_parallel_rsync)
@@ -56,6 +76,10 @@
raise "rsync failed on #{failed_servers.join(',')}" if failed_servers.any?
end
+ before :'puppet:update_code' do
+ syntax_check if puppet_syntax_check
+ end
+
desc "runs puppet with --noop flag to show changes"
task :noop, :except => { :nopuppet => true } do
update_code
View
21 lib/supply_drop/syntax_checker.rb
@@ -0,0 +1,21 @@
+module SupplyDrop
+ class SyntaxChecker
+ def initialize(path)
+ @path = path
+ end
+
+ def validate_puppet_files
+ Dir.glob("#{@path}/**/*.pp").map do |puppet_file|
+ output = `puppet parser validate #{puppet_file}`
+ $?.to_i == 0 ? nil : [puppet_file, output]
+ end.compact
+ end
+
+ def validate_templates
+ Dir.glob("#{@path}/**/*.erb").map do |template_file|
+ output = `erb -x -T '-' #{template_file} | ruby -c 2>&1`
+ $?.to_i == 0 ? nil : [template_file, output]
+ end.compact
+ end
+ end
+end
View
1 test/files/manifests/invalid.pp
@@ -0,0 +1 @@
+class example {
View
9 test/files/manifests/valid.pp
@@ -0,0 +1,9 @@
+class valid {
+ file { "/etc/hosts":
+ ensure => present,
+ content => "127.0.0.1 localhost",
+ owner => root,
+ group => root,
+ mode => "0644"
+ }
+}
View
1 test/files/templates/invalid.erb
@@ -0,0 +1 @@
+this is a <%= if true %> template
View
1 test/files/templates/valid.erb
@@ -0,0 +1 @@
+this is a <%= "good" %> template
View
23 test/syntax_checker_test.rb
@@ -0,0 +1,23 @@
+require 'test/unit'
+require File.expand_path('../../lib/supply_drop/syntax_checker', __FILE__)
+
+class SyntaxCheckerTest < Test::Unit::TestCase
+
+ def test_syntax_checks_puppet_files
+ checker = SupplyDrop::SyntaxChecker.new(File.expand_path('../files', __FILE__))
+ errors = checker.validate_puppet_files
+ assert_equal 1, errors.count
+ file, error = errors.first
+ assert_match %r[manifests/invalid.pp$], file
+ assert_match %r[expected '\}'], error
+ end
+
+ def test_synatx_checks_erb_files
+ checker = SupplyDrop::SyntaxChecker.new(File.expand_path('../files', __FILE__))
+ errors = checker.validate_templates
+ assert_equal 1, errors.count
+ file, error = errors.first
+ assert_match %r[templates/invalid.erb$], file
+ assert_match %r[syntax error], error
+ end
+end

0 comments on commit cc6073d

Please sign in to comment.