puppet-syntax-2.4.1/0000755000004100000410000000000013130700324014400 5ustar www-datawww-datapuppet-syntax-2.4.1/Rakefile0000644000004100000410000000037413130700324016051 0ustar www-datawww-datarequire 'rspec/core/rake_task' RSpec::Core::RakeTask.new('spec') task :publish_gem do require 'gem_publisher' gem = GemPublisher.publish_if_updated('puppet-syntax.gemspec', :rubygems) puts "Published #{gem}" if gem end task :default => [:spec] puppet-syntax-2.4.1/CHANGELOG0000644000004100000410000000642713130700324015623 0ustar www-datawww-data2017-06-29 Release 2.4.1 - Fix to ensure namespace scope is inherited. - Cleanly exits when syntax warnings/errors are found instead of failing. 2017-03-14 Release 2.4.0 - Add check_hiera_keys flag for deep checking of Hiera key name correctness. Thanks @petems. - Fix Puppet version comparisons for compatibility with Puppet 4.10. - Fix app_management setting compatibility with Puppet 5. - Refactor PUPPETVERSION usage to Puppet.version public API. 2017-01-30 Release 2.3.0 - Add app_management flag for Puppet application orchestration support. Thanks @ipcrm. - Check all *yaml file extensions, including eyaml. thanks @kjetilho, @rjw1. - Only test ERB syntax in files with an *.erb extension. Thanks @alexiri. - Extend README to list specific files and checks implemented. Thanks @petems. - Refactor Rake filelist generation, add tests. Thanks @kjetilho, @rjw1. 2016-12-02 Release 2.2.0 - Replace Puppet.initialize_settings with Puppet::Test::TestHelper. Thanks @domcleal #60 This clears out caches on every test so increases runtime. 2016-10-21 Release 2.1.1 - Use `$stderr.puts` rather than `warn` and `info` (thanks @mmckinst) - Allow latest 3.x to validate EPP files (thanks @DavidS) 2016-01-18 Release 2.1.0 - Support Puppet 4. Many thanks to @DavidS - Support validation of EPP templates. Thanks to @trlinkin - Test improvements and refactoring, including Travis CI tests against Puppet 4. Thanks to @trlinkin - Don't error when a tag metaparameter is present. Thank you @dhardy92 - Report the filename of invalid hiera data files. Thanks @danzilio 2015-02-25 Release 2.0.0 - Removed support for Puppet version 2.7.x - New option, fail_on_deprecation_notices, which defaults to true (compatible with previous behaviour); thanks @pcfens - PuppetSyntax::Manifests#check now has two return arguments 2015-01-08 Release 1.4.1 - Support appending to config arrays, thanks @domcleal 2014-12-04 Release 1.4.0 - Rspec 3 is now supported, thanks @tuxmea - Build error fixed where gem_publisher was used prematurely - Lazy load Puppet only when it's required, thanks @logicminds 2014-08-07 Release 1.3.0 - Add the ability to pass hieradata_paths array of globs to check - Check hieradata in modules ('**/data/**/*.yaml') by default 2014-08-05 Release 1.2.3 - Fix puppetlabs_spec_helper warning on Ruby 1.8 2014-07-31 Release 1.2.2 - Check and document conflicts with puppetlabs_spec_helper <= 0.7.0 2014-07-23 Release 1.2.1 - Remove dependency on Puppet from Gemspec (for Puppet Entreprise users). 2014-03-28 Release 1.2.0 - Optional support for Puppet's future parser. 2014-03-17 Release 1.1.1 - Ignore exit(1) from Puppet 3.4 - Don't use hardcoded version of parser face. 2013-09-06 Release 1.1.0 - Syntax checks for Hiera YAML files. - Improved documentation. 2013-07-04 Release 1.0.0 - Refactor code to make it easier to test. - Implement spec tests for syntax checks. - Pending spec tests for FileList matching. - Matrix tests for other Ruby/Puppet versions. - Improve usage example in README. 2013-06-14 Release 0.0.4 - Fix `$confdir` error for Puppet 3.x 2013-06-11 Release 0.0.3 - List rake as a dependency. - Output names of tasks to STDERR. - Match template paths correctly. - Add pending spec tests, not yet working. 2013-06-10 Release 0.0.2 - Fix namespacing of rake tasks. 2013-06-10 Release 0.0.1 - Initial release puppet-syntax-2.4.1/Gemfile0000644000004100000410000000200713130700324015672 0ustar www-datawww-datasource 'https://rubygems.org' # Find a location or specific version for a gem. place_or_version can be a # version, which is most often used. It can also be git, which is specified as # `git://somewhere.git#branch`. You can also use a file source location, which # is specified as `file://some/location/on/disk`. def location_for(place_or_version, fake_version = nil) if place_or_version =~ /^(git[:@][^#]*)#(.*)/ [fake_version, { :git => $1, :branch => $2, :require => false }].compact elsif place_or_version =~ /^file:\/\/(.*)/ ['>= 0', { :path => File.expand_path($1), :require => false }] else [place_or_version, { :require => false }] end end # Specify your gem's dependencies in puppet-syntax.gemspec gemspec # Override gemspec for CI matrix builds. gem 'puppet', *location_for(ENV['PUPPET_VERSION'] || '>2.7.0') # older version required for ruby 1.9 compat, as it is pulled in as dependency of puppet, this has to be carried by the module gem 'json_pure', '<= 2.0.1' group :test do gem 'rspec' endpuppet-syntax-2.4.1/appveyor.yml0000644000004100000410000000144513130700324016774 0ustar www-datawww-databuild: off branches: only: - master # ruby versions under test environment: matrix: - RUBY_VERSION: 21 PUPPET_VERSION: "~> 3.8.7" - RUBY_VERSION: 21 PUPPET_VERSION: "~> 4.8.0" - RUBY_VERSION: 23-x64 PUPPET_VERSION: "~> 4.9.0" - RUBY_VERSION: 23-x64 PUPPET_VERSION: "> 0" - RUBY_VERSION: 23-x64 PUPPET_VERSION: "git://github.com/puppetlabs/puppet.git#master" matrix: allow_failures: - RUBY_VERSION: 23-x64 PUPPET_VERSION: "git://github.com/puppetlabs/puppet.git#master" install: - SET PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% - SET LOG_SPEC_ORDER=true - bundle install --jobs 4 --retry 2 --without development before_test: - type Gemfile.lock - ruby -v - gem -v - bundle -v test_script: - bundle exec rake spec puppet-syntax-2.4.1/LICENSE.txt0000644000004100000410000000205313130700324016223 0ustar www-datawww-dataCopyright (c) 2013 Dan Carley MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. puppet-syntax-2.4.1/spec/0000755000004100000410000000000013130700324015332 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/puppet-syntax/0000755000004100000410000000000013130700324020173 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/puppet-syntax/manifests_spec.rb0000644000004100000410000002130013130700324023517 0ustar www-datawww-datarequire 'spec_helper' require 'puppet' describe PuppetSyntax::Manifests do let(:subject) { PuppetSyntax::Manifests.new } it 'should expect an array of files' do expect { subject.check(nil) }.to raise_error(/Expected an array of files/) end it 'should return nothing from a valid file' do files = fixture_manifests('pass.pp') output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end it 'should return nothing from a valid file with a class using tag parameter' do files = fixture_manifests('tag_notice.pp') output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end it 'should return an error from an invalid file' do files = fixture_manifests('fail_error.pp') output, has_errors = subject.check(files) if Puppet.version.to_i >= 4 expect(output.size).to eq(3) expect(output[2]).to match(/2 errors. Giving up/) expect(has_errors).to eq(true) else expect(output.size).to eq(1) expect(output[0]).to match(/Syntax error at .*:3$/) expect(has_errors).to eq(true) end end it 'should return a warning from an invalid file' do files = fixture_manifests('fail_warning.pp') output, has_errors = subject.check(files) expect(output.size).to eq(2) expect(has_errors).to eq(true) expect(output[0]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/) expect(output[1]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/) end it 'should ignore warnings about storeconfigs' do files = fixture_manifests('pass_storeconfigs.pp') output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end it 'should read more than one valid file' do files = fixture_manifests(['pass.pp', 'pass_storeconfigs.pp']) output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end it 'should continue after finding an error in the first file' do files = fixture_manifests(['fail_error.pp', 'fail_warning.pp']) output, has_errors = subject.check(files) expect(has_errors).to eq(true) if Puppet.version.to_i >= 4 expect(output.size).to eq(5) expect(output[0]).to match(/This Name has no effect. A Host Class Definition can not end with a value-producing expression without other effect at \S*\/fail_error.pp:2:32$/) expect(output[1]).to match(/This Name has no effect. A value(-producing expression without other effect may only be placed last in a block\/sequence| was produced and then forgotten.*) at \S*\/fail_error.pp:2:3$/) expect(output[2]).to match('2 errors. Giving up') expect(output[3]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/) expect(output[4]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/) else expect(output.size).to eq(3) expect(output[0]).to match(/Syntax error at '\}' .*:3$/) expect(output[1]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/) expect(output[2]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/) end end describe 'deprecation notices' do case Puppet.version.to_f when 4.0..4.99 context 'on puppet 4.0.0 and above' do it 'should instead be failures' do files = fixture_manifests('deprecation_notice.pp') output, has_errors = subject.check(files) expect(has_errors).to eq(true) expect(output.size).to eq(1) expect(output[0]).to match (/Node inheritance is not supported in Puppet >= 4.0.0/) end end when 3.7, 3.8 context 'on puppet 3.7 and 3.8' do it 'should return deprecation notices as warnings' do files = fixture_manifests('deprecation_notice.pp') output, has_errors = subject.check(files) expect(has_errors).to eq(false) expect(output.size).to eq(2) expect(output[0]).to match(/The use of 'import' is deprecated/) expect(output[1]).to match(/Deprecation notice:/) end end when 3.5, 3.6 context 'on puppet 3.5 and 3.6' do it 'should return deprecation notices as warnings' do files = fixture_manifests('deprecation_notice.pp') output, has_errors = subject.check(files) expect(has_errors).to eq(false) expect(output.size).to eq(1) expect(output[0]).to match(/The use of 'import' is deprecated/) end end when 3.0..3.4 context 'on puppet 3.0 to 3.4' do it 'should not print deprecation notices' do files = fixture_manifests('deprecation_notice.pp') output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end end end end describe 'app_management' do after do PuppetSyntax.app_management = false if Puppet.version.to_i < 5 end context 'app_management = false (default)', :if => (Puppet.version.to_i < 5) do it 'should fail to parse an application manifest' do files = fixture_manifests(['test_app.pp']) output,has_errors = subject.check(files) expect(has_errors).to eq(true) expect(output).to include(/error/) end end context 'app_management = true' do before(:each) { PuppetSyntax.app_management = true } if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0 it 'should successfully parse an application manifest on Puppet >= 4.3.0' do expect(PuppetSyntax.app_management).to eq(true) files = fixture_manifests(['test_app.pp']) output,has_errors = subject.check(files) expect(output.size).to eq(0) expect(has_errors).to eq(false) end else it 'should fail to parse an application manifest on Puppet < 4.3.0' do expect(PuppetSyntax.app_management).to eq(true) files = fixture_manifests(['test_app.pp']) output,has_errors = subject.check(files) expect(output).to include(/error/) expect(has_errors).to eq(true) end end end end describe 'future_parser' do context 'future_parser = false (default)' do if Puppet::Util::Package.versioncmp(Puppet.version, '4.0') < 0 it 'should fail without setting future option to true on future manifest on Puppet < 4.0.0' do expect(PuppetSyntax.future_parser).to eq(false) files = fixture_manifests(['future_syntax.pp']) output, has_errors = subject.check(files) expect(output.size).to eq(1) expect(output[0]).to match(/Syntax error at '='; expected '\}' .*:2$/) expect(has_errors).to eq(true) end else it 'should succeed on Puppet >= 4.0.0' do expect(PuppetSyntax.future_parser).to eq(false) files = fixture_manifests(['future_syntax.pp']) output, has_errors = subject.check(files) expect(output.size).to eq(0) expect(has_errors).to eq(false) end end end context 'future_parser = true' do before(:each) { PuppetSyntax.future_parser = true } if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0 and Puppet.version.to_i < 4 context 'Puppet >= 3.2 < 4' do it 'should pass with future option set to true on future manifest' do files = fixture_manifests(['future_syntax.pp']) output, has_errors = subject.check(files) expect(output).to eq([]) expect(has_errors).to eq(false) end end context 'Puppet >= 3.7 < 4' do # Certain elements of the future parser weren't added until 3.7 if Puppet::Util::Package.versioncmp(Puppet.version, '3.7') >= 0 it 'should fail on what were deprecation notices in the non-future parser' do files = fixture_manifests('deprecation_notice.pp') output, has_errors = subject.check(files) expect(output.size).to eq(1) expect(output[0]).to match(/Node inheritance is not supported/) expect(has_errors).to eq(true) end end end elsif Puppet::Util::Package.versioncmp(Puppet.version, '3.2') < 0 context 'Puppet < 3.2' do it 'should return an error that the parser option is not supported' do files = fixture_manifests(['future_syntax.pp']) output, has_errors = subject.check(files) expect(output.size).to eq(1) expect(output[0]).to match("Attempt to assign a value to unknown configuration parameter :parser") expect(has_errors).to eq(true) end end end end end end puppet-syntax-2.4.1/spec/puppet-syntax/tasks/0000755000004100000410000000000013130700324021320 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/puppet-syntax/tasks/puppet-syntax_spec.rb0000644000004100000410000000326613130700324025527 0ustar www-datawww-datarequire 'spec_helper' require 'puppet-syntax/tasks/puppet-syntax' known_pp = 'spec/fixtures/test_module/manifests/pass.pp' known_erb = 'spec/fixtures/test_module/templates/pass.erb' known_yaml = 'spec/fixtures/hiera/data/hiera_1.yaml' known_eyaml = 'spec/fixtures/hiera/data/hiera_2.eyaml' known_yaml_subdir = 'spec/fixtures/hiera/data/test/hiera_3.yaml' known_eyaml_subdir = 'spec/fixtures/hiera/data/test/hiera_4.eyaml' describe 'PuppetSyntax rake tasks' do it 'should filter directories' do list = PuppetSyntax::RakeTask.new.filelist(['**/lib', known_pp]) expect(list.count).to eq 1 expect(list).to include(known_pp) end it 'should generate FileList of manifests relative to Rakefile' do list = PuppetSyntax::RakeTask.new.filelist_manifests expect(list).to include(known_pp) expect(list.count).to eq 8 end it 'should generate FileList of templates relative to Rakefile' do list = PuppetSyntax::RakeTask.new.filelist_templates expect(list).to include(known_erb) expect(list.count).to eq 9 end it 'should generate FileList of Hiera yaml files relative to Rakefile' do list = PuppetSyntax::RakeTask.new.filelist_hiera_yaml expect(list).to include(known_yaml) expect(list).to include(known_eyaml) expect(list).to include(known_yaml_subdir) expect(list).to include(known_eyaml_subdir) expect(list.count).to eq 4 end it 'should check manifests relative to Rakefile' do if RSpec::Version::STRING < '3' pending else skip('needs to be done') end end it 'should check templates relative to Rakefile' do if RSpec::Version::STRING < '3' pending else skip('needs to be done') end end end puppet-syntax-2.4.1/spec/puppet-syntax/hiera_spec.rb0000644000004100000410000000354313130700324022627 0ustar www-datawww-datarequire 'spec_helper' describe PuppetSyntax::Hiera do let(:subject) { PuppetSyntax::Hiera.new } it 'should expect an array of files' do expect { subject.check(nil) }.to raise_error(/Expected an array of files/) end it "should return nothing from valid YAML" do files = fixture_hiera('hiera_good.yaml') res = subject.check(files) expect(res).to be == [] end it "should return an error from invalid YAML" do hiera_yaml = RUBY_VERSION =~ /1.8/ ? 'hiera_bad_18.yaml' : 'hiera_bad.yaml' files = fixture_hiera(hiera_yaml) expected = /ERROR: Failed to parse #{files[0]}:/ res = subject.check(files) expect(res.size).to be == 1 expect(res.first).to match(expected) end context 'check_hiera_keys = true' do before(:each) { PuppetSyntax.check_hiera_keys = true } it "should return warnings for invalid keys" do hiera_yaml = 'hiera_badkey.yaml' examples = 5 files = fixture_hiera(hiera_yaml) res = subject.check(files) (1..examples).each do |n| expect(res).to include(/::warning#{n}/) end expect(res.size).to be == examples expect(res[0]).to match('Key :typical:typo::warning1: Looks like a missing colon') expect(res[1]).to match('Key ::notsotypical::warning2: Puppet automatic lookup will not use leading \'::\'') expect(res[2]).to match('Key :noCamelCase::warning3: Not a valid Puppet variable name for automatic lookup') expect(res[3]).to match('Key :no-hyphens::warning4: Not a valid Puppet variable name for automatic lookup') expect(res[4]).to match('Key :picky::warning5: Puppet automatic lookup will not look up symbols') end it "should handle empty files" do hiera_yaml = 'hiera_key_empty.yaml' files = fixture_hiera(hiera_yaml) res = subject.check(files) expect(res).to be_empty end end end puppet-syntax-2.4.1/spec/puppet-syntax/templates_spec.rb0000644000004100000410000000747213130700324023542 0ustar www-datawww-datarequire 'spec_helper' describe PuppetSyntax::Templates do let(:subject) { PuppetSyntax::Templates.new } it 'should expect an array of files' do expect { subject.check(nil) }.to raise_error(/Expected an array of files/) end it 'should return nothing from a valid file' do files = fixture_templates('pass.erb') res = subject.check(files) expect(res).to match([]) end it 'should ignore NameErrors from unbound variables' do files = fixture_templates('pass_unbound_var.erb') res = subject.check(files) expect(res).to match([]) end it 'should catch SyntaxError' do files = fixture_templates('fail_error.erb') res = subject.check(files) expect(res.size).to eq(1) expect(res[0]).to match(/2: syntax error, unexpected/) end it 'should catch Ruby warnings' do files = fixture_templates('fail_warning.erb') res = subject.check(files) expect(res.size).to eq(1) expect(res[0]).to match(/2: warning: found = in conditional/) end it 'should read more than one valid file' do files = fixture_templates(['pass.erb', 'pass_unbound_var.erb']) res = subject.check(files) expect(res).to match([]) end it 'should continue after finding an error in the first file' do files = fixture_templates(['fail_error.erb', 'fail_warning.erb']) res = subject.check(files) expect(res.size).to eq(2) expect(res[0]).to match(/2: syntax error, unexpected/) expect(res[1]).to match(/2: warning: found = in conditional/) end it 'should ignore a TypeError' do files = fixture_templates('typeerror_shouldwin.erb') res = subject.check(files) expect(res).to match([]) end it 'should ignore files without .erb extension' do files = fixture_templates('ignore.tpl') res = subject.check(files) expect(res).to match([]) end if Puppet.version.to_f < 3.7 context 'on Puppet < 3.7' do it 'should throw an exception when parsing EPP files' do file = fixture_templates('pass.epp') expect{ subject.check(file) }.to raise_error(/Cannot validate EPP without Puppet 4/) end context "when the 'epp_only' options is set" do before(:each) { PuppetSyntax.epp_only = true } it 'should throw an exception for any file' do file = fixture_templates('pass.erb') expect{ subject.check(file) }.to raise_error(/Cannot validate EPP without Puppet 4/) end end end end if Puppet.version.to_f >= 3.7 context 'on Puppet >= 3.7' do it 'should return nothing from a valid file' do files = fixture_templates('pass.epp') res = subject.check(files) expect(res).to match([]) end it 'should catch SyntaxError' do files = fixture_templates('fail_error.epp') res = subject.check(files) expect(res.size).to eq(1) expect(res[0]).to match(/This Type-Name has no effect/) end it 'should read more than one valid file' do files = fixture_templates(['pass.epp', 'pass_also.epp']) res = subject.check(files) expect(res).to match([]) end it 'should continue after finding an error in the first file' do files = fixture_templates(['fail_error.epp', 'fail_error_also.epp']) res = subject.check(files) expect(res.size).to eq(2) expect(res[0]).to match(/This Type-Name has no effect/) expect(res[1]).to match(/Syntax error at '}' at \S*\/fail_error_also.epp:2:4/) end context "when the 'epp_only' options is set" do before(:each) { PuppetSyntax.epp_only = true } it 'should process an ERB as EPP and find an error' do files = fixture_templates('pass.erb') res = subject.check(files) expect(res.size).to eq(1) end end end end end puppet-syntax-2.4.1/spec/spec_helper.rb0000644000004100000410000000075113130700324020153 0ustar www-datawww-datarequire 'rspec' require 'puppet-syntax' def fixture_hiera(list) fixture_files(list, 'hiera') end def fixture_templates(list) fixture_files(list, 'test_module/templates') end def fixture_manifests(list) fixture_files(list, 'test_module/manifests') end def fixture_files(list, path) list = [list].flatten list.map { |f| File.expand_path("../fixtures/#{path}/#{f}", __FILE__) } end RSpec.configure do |config| config.color = true config.formatter = 'documentation' end puppet-syntax-2.4.1/spec/fixtures/0000755000004100000410000000000013130700324017203 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/0000755000004100000410000000000013130700324020273 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/0000755000004100000410000000000013130700324021204 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/hiera_1.yaml0000644000004100000410000000000013130700324023366 0ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/test/0000755000004100000410000000000013130700324022163 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/test/hiera_3.yaml0000644000004100000410000000000013130700324024347 0ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/test/hiera_4.eyaml0000644000004100000410000000000013130700324024515 0ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/data/hiera_2.eyaml0000644000004100000410000000000013130700324023534 0ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/hiera_badkey.yaml0000644000004100000410000000034213130700324023565 0ustar www-datawww-data--- this_is_ok: 0 this_is_ok::too: 0 th1s_is_ok::two3: 0 :eventhis: 0 typical:typo::warning1: true ::notsotypical::warning2: true noCamelCase::warning3: true no-hyphens::warning4: true :picky::warning5: true puppet-syntax-2.4.1/spec/fixtures/hiera/hiera_bad_18.yaml0000644000004100000410000000001713130700324023363 0ustar www-datawww-data--- !!!str foo puppet-syntax-2.4.1/spec/fixtures/hiera/hiera_good.yaml0000644000004100000410000000012513130700324023255 0ustar www-datawww-data--- :backends: - yaml :yaml: :datadir: './hieradata/good' :hierarchy: - common puppet-syntax-2.4.1/spec/fixtures/hiera/hiera_key_empty.yaml0000644000004100000410000000000013130700324024323 0ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/hiera/hiera_bad.yaml0000644000004100000410000000001113130700324023045 0ustar www-datawww-data%YAMLBAD puppet-syntax-2.4.1/spec/fixtures/test_module/0000755000004100000410000000000013130700324021527 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/test_module/templates/0000755000004100000410000000000013130700324023525 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/test_module/templates/fail_error_also.epp0000644000004100000410000000006313130700324027374 0ustar www-datawww-dataThis is plain text <% } %> This is also plain text puppet-syntax-2.4.1/spec/fixtures/test_module/templates/pass_also.epp0000644000004100000410000000011713130700324026216 0ustar www-datawww-data<%# VALID COMMENT %> <% $valid = 'valid' -%> This is a <%= $valid %> template. puppet-syntax-2.4.1/spec/fixtures/test_module/templates/pass.epp0000644000004100000410000000011713130700324025200 0ustar www-datawww-data<%# VALID COMMENT %> <% $valid = 'valid' -%> This is a <%= $valid %> template. puppet-syntax-2.4.1/spec/fixtures/test_module/templates/ignore.tpl0000644000004100000410000000011013130700324025521 0ustar www-datawww-dataThis is plain text <% This is not valid Ruby %> This is also plain text puppet-syntax-2.4.1/spec/fixtures/test_module/templates/typeerror_shouldwin.erb0000644000004100000410000000012613130700324030345 0ustar www-datawww-data#this is valid syntax <%= File.dirname(@the_path_of_the_file_you_first_thought_of) %> puppet-syntax-2.4.1/spec/fixtures/test_module/templates/fail_warning.erb0000644000004100000410000000010313130700324026651 0ustar www-datawww-dataAssignment in condition should warn. <%= "oh yes" if foo = true %> puppet-syntax-2.4.1/spec/fixtures/test_module/templates/fail_error.epp0000644000004100000410000000010713130700324026355 0ustar www-datawww-dataThis is plain text <% This is not valid EPP %> This is also plain text puppet-syntax-2.4.1/spec/fixtures/test_module/templates/pass.erb0000644000004100000410000000007113130700324025163 0ustar www-datawww-data<% valid = 'valid' -%> This is a <%= valid -%> template. puppet-syntax-2.4.1/spec/fixtures/test_module/templates/pass_unbound_var.erb0000644000004100000410000000005013130700324027562 0ustar www-datawww-data<%= this_variable_has_not_been_bound %> puppet-syntax-2.4.1/spec/fixtures/test_module/templates/fail_error.erb0000644000004100000410000000011013130700324026333 0ustar www-datawww-dataThis is plain text <% This is not valid Ruby %> This is also plain text puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/0000755000004100000410000000000013130700324023520 5ustar www-datawww-datapuppet-syntax-2.4.1/spec/fixtures/test_module/manifests/pass.pp0000644000004100000410000000015213130700324025025 0ustar www-datawww-dataclass normal_puppet_module { notify { 'should should pass': message => 'with flying colours', } } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/future_syntax.pp0000644000004100000410000000006213130700324026777 0ustar www-datawww-dataclass module_with_future_syntax { $a = $b = 10 } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/deprecation_notice.pp0000644000004100000410000000024513130700324027720 0ustar www-datawww-datanode test inherits default { import 'pass.pp' notify { 'this should give a deprecation notice': message => 'inheritance is gone in the future parser', } } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/test_app.pp0000644000004100000410000000003213130700324025673 0ustar www-datawww-dataapplication test_app { } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/pass_storeconfigs.pp0000644000004100000410000000006713130700324027617 0ustar www-datawww-dataclass uses_storeconfigs { @@notify { 'exported': } } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/fail_warning.pp0000644000004100000410000000020213130700324026513 0ustar www-datawww-dataclass warning_puppet_module { notify { 'this should raise a warning': message => "because of \[\] escape characters", } } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/tag_notice.pp0000644000004100000410000000016113130700324026173 0ustar www-datawww-dataclass tag_parameter_test ($tag=undef){ notify { 'tag_should pass': message => 'with flying colours', } } puppet-syntax-2.4.1/spec/fixtures/test_module/manifests/fail_error.pp0000644000004100000410000000010413130700324026200 0ustar www-datawww-dataclass failing_puppet_module { this is not a valid resource name } puppet-syntax-2.4.1/spec/puppet-syntax_spec.rb0000644000004100000410000000267113130700324021540 0ustar www-datawww-datarequire 'spec_helper' describe PuppetSyntax do after do PuppetSyntax.exclude_paths = [] PuppetSyntax.app_management = false if Puppet.version.to_i < 5 end it 'should default exclude_paths to empty array' do expect(PuppetSyntax.exclude_paths).to be_empty end it 'should support setting exclude_paths' do PuppetSyntax.exclude_paths = ["foo", "bar/baz"] expect(PuppetSyntax.exclude_paths).to eq(["foo", "bar/baz"]) end it 'should support appending exclude_paths' do PuppetSyntax.exclude_paths << "foo" expect(PuppetSyntax.exclude_paths).to eq(["foo"]) end it 'should support future parser setting' do PuppetSyntax.future_parser = true expect(PuppetSyntax.future_parser).to eq(true) end it 'should support app_management setting setting' do PuppetSyntax.app_management = true expect(PuppetSyntax.app_management).to eq(true) end it 'should raise error when app_management is disabled on 5.x', :if => (Puppet.version.to_i >= 5) do expect { PuppetSyntax.app_management = false }.to raise_error(/app_management cannot be disabled on Puppet 5 or higher/) end it 'should support a fail_on_deprecation_notices setting' do PuppetSyntax.fail_on_deprecation_notices = false expect(PuppetSyntax.fail_on_deprecation_notices).to eq(false) end it 'should support forcing EPP only templates' do PuppetSyntax.epp_only = true expect(PuppetSyntax.epp_only).to eq(true) end end puppet-syntax-2.4.1/.travis.yml0000644000004100000410000000256013130700324016514 0ustar www-datawww-data--- language: ruby # Workaround https://github.com/bundler/bundler/issues/3558 before_install: gem install bundler install: bundle install --jobs 4 --retry 2 --without development script: bundle exec rake rvm: - 1.9.3 - 2.1.6 - 2.2.6 - 2.3.3 - 2.4.0 env: - PUPPET_VERSION="~> 3.8.7" - PUPPET_VERSION="~> 4.8.0" - PUPPET_VERSION="~> 4.9.0" - PUPPET_VERSION=">= 0" - PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master" matrix: exclude: - env: PUPPET_VERSION="~> 3.8.7" rvm: 2.2.6 - env: PUPPET_VERSION="~> 3.8.7" rvm: 2.3.3 - env: PUPPET_VERSION="~> 3.8.7" rvm: 2.4.0 # 4.9 with Ruby 1.9.3 issues deprecation warnings - env: PUPPET_VERSION="~> 4.9.0" rvm: 1.9.3 - env: PUPPET_VERSION=">= 0" rvm: 1.9.3 - env: PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master" rvm: 1.9.3 allow_failures: - env: PUPPET_VERSION=">= 0" - env: PUPPET_VERSION="git://github.com/puppetlabs/puppet.git#master" deploy: provider: rubygems api_key: secure: "kwxryZZ/t9EkWuYxhz3G1v+U3ZK4WdsiN0UFHDjijnAGPxqe/n+oBcNA8hOiNhjZeTFo8bADEZkL7JtdKQo9RvgStipyaS5gDHB/C1c4LOBWv4Tga21NNCAuBcE2CDtAH3+TzrZV5vv2+SpOrhKZpzZoAoR6PR1MWVWMUie/rE0=" gem: puppet-syntax on: rvm: 2.4.0 condition: '"$PUPPET_VERSION" = "~> 4.8.0"' tags: true all_branches: true repo: voxpupuli/puppet-syntax puppet-syntax-2.4.1/lib/0000755000004100000410000000000013130700324015146 5ustar www-datawww-datapuppet-syntax-2.4.1/lib/puppet-syntax/0000755000004100000410000000000013130700324020007 5ustar www-datawww-datapuppet-syntax-2.4.1/lib/puppet-syntax/manifests.rb0000644000004100000410000000415213130700324022327 0ustar www-datawww-datamodule PuppetSyntax class Manifests def check(filelist) raise "Expected an array of files" unless filelist.is_a?(Array) require 'puppet' require 'puppet/face' require 'puppet/test/test_helper' output = [] if Puppet::Test::TestHelper.respond_to?(:initialize) # 3.1+ Puppet::Test::TestHelper.initialize end Puppet::Test::TestHelper.before_all_tests called_before_all_tests = true # Catch syntax warnings. Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(output)) Puppet::Util::Log.level = :warning filelist.each do |puppet_file| Puppet::Test::TestHelper.before_each_test begin validate_manifest(puppet_file) rescue SystemExit # Disregard exit(1) from face. rescue => error output << error ensure Puppet::Test::TestHelper.after_each_test end end Puppet::Util::Log.close_all output.map! { |e| e.to_s } # Exported resources will raise warnings when outside a puppetmaster. output.reject! { |e| e =~ /^You cannot collect( exported resources)? without storeconfigs being set/ } # tag parameter in class raise warnings notice in output that prevent from succeed output.reject! { |e| e =~ /^tag is a metaparam; this value will inherit to all contained resources in the / } deprecations = output.select { |e| e =~ /^Deprecation notice:|is deprecated/ } # Errors exist if there is any output that isn't a deprecation notice. has_errors = (output != deprecations) return output, has_errors ensure Puppet::Test::TestHelper.after_all_tests if called_before_all_tests end private def validate_manifest(file) Puppet[:parser] = 'future' if PuppetSyntax.future_parser and Puppet.version.to_i < 4 Puppet[:app_management] = true if PuppetSyntax.app_management && (Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0 && Puppet.version.to_i < 5) Puppet::Face[:parser, :current].validate(file) end end end puppet-syntax-2.4.1/lib/puppet-syntax/version.rb0000644000004100000410000000005413130700324022020 0ustar www-datawww-datamodule PuppetSyntax VERSION = "2.4.1" end puppet-syntax-2.4.1/lib/puppet-syntax/hiera.rb0000644000004100000410000000245613130700324021433 0ustar www-datawww-datarequire 'yaml' module PuppetSyntax class Hiera def check_hiera_key(key) if key.is_a? Symbol if key.to_s.start_with?(':') return "Puppet automatic lookup will not use leading '::'" elsif key !~ /^[a-z]+$/ # we allow Hiera's own configuration return "Puppet automatic lookup will not look up symbols" end elsif key !~ /^[a-z][a-z0-9_]+(::[a-z][a-z0-9_]+)*$/ if key =~ /[^:]:[^:]/ # be extra helpful return "Looks like a missing colon" else return "Not a valid Puppet variable name for automatic lookup" end end end def check(filelist) raise "Expected an array of files" unless filelist.is_a?(Array) errors = [] filelist.each do |hiera_file| begin yamldata = YAML.load_file(hiera_file) rescue Exception => error errors << "ERROR: Failed to parse #{hiera_file}: #{error}" next end if yamldata yamldata.each do |k,v| if PuppetSyntax.check_hiera_keys key_msg = check_hiera_key(k) errors << "WARNING: #{hiera_file}: Key :#{k}: #{key_msg}" if key_msg end end end end errors.map! { |e| e.to_s } errors end end end puppet-syntax-2.4.1/lib/puppet-syntax/tasks/0000755000004100000410000000000013130700324021134 5ustar www-datawww-datapuppet-syntax-2.4.1/lib/puppet-syntax/tasks/puppet-syntax.rb0000644000004100000410000000577213130700324024335 0ustar www-datawww-datarequire 'puppet-syntax' require 'rake' require 'rake/tasklib' module PuppetSyntax class RakeTask < ::Rake::TaskLib def filelist(paths) files = FileList[paths] files.reject! { |f| File.directory?(f) } files.exclude(*PuppetSyntax.exclude_paths) end def filelist_manifests filelist("**/*.pp") end def filelist_templates filelist(["**/templates/**/*.erb", "**/templates/**/*.epp"]) end def filelist_hiera_yaml filelist(PuppetSyntax.hieradata_paths) end def initialize(*args) desc 'Syntax check Puppet manifests and templates' task :syntax => [ 'syntax:check_puppetlabs_spec_helper', 'syntax:manifests', 'syntax:templates', 'syntax:hiera', ] namespace :syntax do task :check_puppetlabs_spec_helper do psh_present = task(:syntax).actions.any? { |a| a.inspect.match(/puppetlabs_spec_helper\/rake_tasks\.rb:\d+/) } if psh_present $stderr.puts <<-EOS [WARNING] A conflicting :syntax rake task has been defined by puppetlabs_spec_helper/rake_tasks. You should either disable this or upgrade to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax. EOS end end desc 'Syntax check Puppet manifests' task :manifests do |t| if Puppet.version.to_i >= 4 and PuppetSyntax.future_parser $stderr.puts <<-EOS [INFO] Puppet 4 has been detected and `future_parser` has been set to 'true'. The `future_parser setting will be ignored. EOS end if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') < 0 and PuppetSyntax.app_management $stderr.puts <<-EOS [WARNING] Puppet `app_management` has been detected but the Puppet version is less then 4.3. The `app_management` setting will be ignored. EOS end $stderr.puts "---> #{t.name}" c = PuppetSyntax::Manifests.new output, has_errors = c.check(filelist_manifests) $stdout.puts "#{output.join("\n")}\n" unless output.empty? exit 1 if has_errors || ( output.any? && PuppetSyntax.fail_on_deprecation_notices ) end desc 'Syntax check Puppet templates' task :templates do |t| $stderr.puts "---> #{t.name}" c = PuppetSyntax::Templates.new errors = c.check(filelist_templates) $stdout.puts "#{errors.join("\n")}\n" unless errors.empty? exit 1 unless errors.empty? end desc 'Syntax check Hiera config files' task :hiera => [ 'syntax:hiera:yaml', ] namespace :hiera do task :yaml do |t| $stderr.puts "---> #{t.name}" c = PuppetSyntax::Hiera.new errors = c.check(filelist_hiera_yaml) $stdout.puts "#{errors.join("\n")}\n" unless errors.empty? exit 1 unless errors.empty? end end end end end end PuppetSyntax::RakeTask.new puppet-syntax-2.4.1/lib/puppet-syntax/templates.rb0000644000004100000410000000324513130700324022336 0ustar www-datawww-datarequire 'erb' require 'puppet' require 'stringio' module PuppetSyntax class Templates def check(filelist) raise "Expected an array of files" unless filelist.is_a?(Array) # We now have to redirect STDERR in order to capture warnings. $stderr = warnings = StringIO.new() errors = [] filelist.each do |file| if File.extname(file) == '.epp' or PuppetSyntax.epp_only errors.concat validate_epp(file) elsif File.extname(file) == '.erb' errors.concat validate_erb(file) end end $stderr = STDERR errors << warnings.string unless warnings.string.empty? errors.map! { |e| e.to_s } errors end def validate_epp(filename) if Puppet.version.to_f < 3.7 raise "Cannot validate EPP without Puppet 4 or future parser (3.7+)" end require 'puppet/pops' errors = [] begin parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new() parser.parse_file(filename) rescue => detail errors << detail end errors end def validate_erb(filename) errors = [] begin erb = ERB.new(File.read(filename), nil, '-') erb.filename = filename erb.result rescue NameError => error # This is normal because we don't have the variables that would # ordinarily be bound by the parent Puppet manifest. rescue TypeError # This is normal because we don't have the variables that would # ordinarily be bound by the parent Puppet manifest. rescue SyntaxError => error errors << error end errors end end end puppet-syntax-2.4.1/lib/puppet-syntax.rb0000644000004100000410000000164213130700324020337 0ustar www-datawww-datarequire "puppet-syntax/version" require "puppet-syntax/manifests" require "puppet-syntax/templates" require "puppet-syntax/hiera" require "puppet/version" module PuppetSyntax @exclude_paths = [] @future_parser = false @hieradata_paths = [ "**/data/**/*.*yaml", "hieradata/**/*.*yaml", "hiera*.*yaml" ] @fail_on_deprecation_notices = true @app_management = Puppet.version.to_i >= 5 ? true : false @check_hiera_keys = false class << self attr_accessor :exclude_paths, :future_parser, :hieradata_paths, :fail_on_deprecation_notices, :epp_only, :check_hiera_keys attr_reader :app_management def app_management=(app_management) raise 'app_management cannot be disabled on Puppet 5 or higher' if Puppet.version.to_i >= 5 && !app_management @app_management = app_management end end end puppet-syntax-2.4.1/jenkins.sh0000755000004100000410000000036113130700324016400 0ustar www-datawww-data#!/usr/bin/env bash set -eu # Avoid Psych bug in Ruby 1.9.3p0 on Ubuntu 12.04 export RBENV_VERSION="1.9.3" rm -f Gemfile.lock bundle install --path "${HOME}/bundles/${JOB_NAME}" --shebang ruby bundle exec rake bundle exec rake publish_gem puppet-syntax-2.4.1/.gitignore0000644000004100000410000000024213130700324016366 0ustar www-datawww-data*.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp vendor/ puppet-syntax-2.4.1/puppet-syntax.gemspec0000644000004100000410000000177113130700324020614 0ustar www-datawww-data# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'puppet-syntax/version' Gem::Specification.new do |spec| spec.name = "puppet-syntax" spec.version = PuppetSyntax::VERSION spec.authors = ["Vox Pupuli"] spec.email = ["voxpupuli@groups.io"] spec.description = %q{Syntax checks for Puppet manifests and templates} spec.summary = %q{Syntax checks for Puppet manifests, templates, and Hiera YAML} spec.homepage = "https://github.com/voxpupuli/puppet-syntax" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] spec.add_dependency "rake" spec.add_development_dependency "pry" spec.add_development_dependency "rb-readline" spec.add_development_dependency "gem_publisher", "~> 1.3" end puppet-syntax-2.4.1/README.md0000644000004100000410000001074613130700324015667 0ustar www-datawww-data[![Build Status](https://travis-ci.org/voxpupuli/puppet-syntax.svg?branch=master)](https://travis-ci.org/voxpupuli/puppet-syntax) # Puppet::Syntax Puppet::Syntax checks for correct syntax in Puppet manifests, templates, and Hiera YAML. ## Version support Puppet::Syntax is supported with: - Puppet >= 2.7 that provides the `validate` face. - Ruby >= 1.8 with `erb` from Ruby stdlib. For the specific versions that we test against, see the [TravisCI config](.travis.yml). If you're using `puppetlabs_spec_helper/rake_tasks` and getting unexpected non-zero exit codes, upgrade to [puppetlabs_spec_helper][psh] version 0.8.0 or greater. Versions of `puppetlabs_spec_helper` prior to 0.8.0 conflicted with Puppet::Syntax. [psh]: https://github.com/puppetlabs/puppetlabs_spec_helper ## Installation To install Puppet::Syntax, either add it to your module's Gemfile or install the gem manually. * To install with the Gemfile, add: gem 'puppet-syntax' And then execute: $ bundle install * To install the gem yourself, run: $ gem install puppet-syntax ## Configuration To configure Puppet::Syntax, add any of the following settings to your `Rakefile`. * To exclude certain paths from the syntax checks, set: PuppetSyntax.exclude_paths = ["vendor/**/*"] * To use the Puppet 4 ("future") parser in Puppet 3.2 through 3.8, set: PuppetSyntax.future_parser = true * To configure specific paths for the Hiera syntax check, specify `hieradata_paths`. This is useful if you use Hiera data inside your module. PuppetSyntax.hieradata_paths = ["**/data/**/*.yaml", "hieradata/**/*.yaml", "hiera*.yaml"] * To validate the syntax of code written for application orchestration, enable `app_management`: PuppetSyntax.app_management = true The `app_management` setting is supported with Puppet 4.3 or greater and is off by default. In Puppet 5, app_management is always enabled. * To ignore deprecation warnings, disable `fail_on_deprecation_notices`. By default, `puppet-syntax` fails if it encounters Puppet deprecation notices. If you are working with a legacy code base and want to ignore such non-fatal warnings, you might want to override the default behavior. PuppetSyntax.fail_on_deprecation_notices = false * To enable a syntax check on Hiera keys, set: PuppetSyntax.check_hiera_keys = true This reports common mistakes in key names in Hiera files, such as: - Leading `::` in keys, such as: `::notsotypical::warning2: true`. - Single colon scope separators, such as: `:picky::warning5: true`. - Invalid camel casing, such as: `noCamelCase::warning3: true`. - Use of hyphens, such as: `no-hyphens::warning4: true`. ## Usage * To enable Puppet::Syntax, include the following in your module's `Rakefile`: require 'puppet-syntax/tasks/puppet-syntax' For Continuous Integration, use Puppet::Syntax in conjunction with `puppet-lint` and spec tests. Add the following to your module's `Rakefile`: task :test => [ :syntax, :lint, :spec, ] * To test all manifests and templates, relative to the location of the `Rakefile`, run: $ bundle exec rake syntax ---> syntax:manifests ---> syntax:templates ---> syntax:hiera:yaml * To return a non-zero exit code and an error message on any failures, run: $ bundle exec rake syntax ---> syntax:manifests rake aborted! Could not parse for environment production: Syntax error at end of file at demo.pp:2 Tasks: TOP => syntax => syntax:manifests (See full trace by running task with --trace) ## Checks Puppet::Syntax makes the following checks in the directories and subdirectories of the module, relative to the location of the `Rakefile`. ### Hiera Checks `.yaml` files for syntax errors. By default, this rake task looks for all `.yaml` files in a single module under: * `**/data/**/*.yaml` * `hieradata/**/*.yaml` * `hiera*.yaml` ### manifests Checks all `.pp` files in the module for syntax errors. ### templates #### erb Checks `.erb` files in the module for syntax errors. #### epp Checks `.epp` files in the module for syntax errors. EPP checks are supported in Puppet 4 or greater, or in Puppet 3 with the future parser enabled. ## Contributing 1. Fork the repo. 2. Create your feature branch (`git checkout -b my-new-feature`). 3. Commit your changes (`git commit -am 'Add some feature'`). 4. Push to the branch (`git push origin my-new-feature`). 5. Create new Pull Request.