diff --git a/.travis.yml b/.travis.yml index f817fdcb0ee6b04cca367a4e0769f713dd433b00..aefe0aac694c28e49b6ea0bbe3908b50e0a480ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,26 +2,46 @@ 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.0.0" - - PUPPET_VERSION="~> 3.1.0" - - PUPPET_VERSION="~> 3.2.0" - - PUPPET_VERSION="~> 3.4.0" - - PUPPET_VERSION="~> 3.7.3" - - PUPPET_VERSION="~> 4.2.0" - - PUPPET_VERSION="~> 4.3.0" + - 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: - - rvm: 2.1.6 - env: PUPPET_VERSION="~> 3.2.0" - - rvm: 2.1.6 - env: PUPPET_VERSION="~> 3.1.0" - - rvm: 2.1.6 - env: PUPPET_VERSION="~> 3.0.0" + - 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 diff --git a/CHANGELOG b/CHANGELOG index e243e8480043d6e4bff082d1b91b63f4412134f4..cfca27cd5be9b76a7c55b5ce6c8a88e51ced17f4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,20 @@ +2017-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. diff --git a/Gemfile b/Gemfile index 4243d162b097b0dabc5d10901449d96582339c9e..1b39064ec00cfa19187ba4070f9c2b93025945fe 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,28 @@ source '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. -puppet_version = ENV['PUPPET_VERSION'] || '>2.7.0' -gem 'puppet', puppet_version +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' +end \ No newline at end of file diff --git a/README.md b/README.md index 2a66bfdb1163a59f2fe3961588a2a7d6e411a047..8a603be37b41c60e165f7a91a8a9187470500c4b 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,139 @@ -[](https://travis-ci.org/gds-operations/puppet-syntax) +[](https://travis-ci.org/voxpupuli/puppet-syntax) # Puppet::Syntax -Syntax checks for Puppet manifests, templates, and Hiera YAML. +Puppet::Syntax checks for correct syntax in Puppet manifests, templates, and Hiera YAML. ## Version support -This should work on any version of: +Puppet::Syntax is supported with: - Puppet >= 2.7 that provides the `validate` face. -- Ruby >= 1.8 with `erb` from stdlib. +- Ruby >= 1.8 with `erb` from Ruby stdlib. -You can see the matrix of specific versions that we currently test against -in the [TravisCI config](.travis.yml). +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 then you should upgrade to [puppetlabs_spec_helper][psh] -\>= 0.8.0 which no longer has a conflicting rake task and now depends on -this project. +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 -Include the following in your `Rakefile`: +* To enable Puppet::Syntax, include the following in your module's `Rakefile`: - require 'puppet-syntax/tasks/puppet-syntax' + require 'puppet-syntax/tasks/puppet-syntax' -Test all manifests and templates relative to your `Rakefile`: + For Continuous Integration, use Puppet::Syntax in conjunction with `puppet-lint` and spec tests. Add the following to your module's `Rakefile`: - ➜ puppet git:(master) bundle exec rake syntax - ---> syntax:manifests - ---> syntax:templates - ---> syntax:hiera:yaml + task :test => [ + :syntax, + :lint, + :spec, + ] -A non-zero exit code and error message will be returned for any failures: +* To test all manifests and templates, relative to the location of the `Rakefile`, run: - ➜ puppet git:(master) 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) + $ bundle exec rake syntax + ---> syntax:manifests + ---> syntax:templates + ---> syntax:hiera:yaml -Use in conjunction with lint and spec tests for Continuous Integration: +* To return a non-zero exit code and an error message on any failures, run: - task :test => [ - :syntax, - :lint, - :spec, - ] + $ 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) -## Configuration +## Checks -Paths can be excluded with: +Puppet::Syntax makes the following checks in the directories and subdirectories of the module, relative to the location of the `Rakefile`. - PuppetSyntax.exclude_paths = ["vendor/**/*"] +### Hiera -When you are using a Puppet version greater then 3.2, you can select the future parse by specifying +Checks `.yaml` files for syntax errors. - PuppetSyntax.future_parser = true +By default, this rake task looks for all `.yaml` files in a single module under: -If you are using some form of hiera data inside your module, you can configure where the `syntax:hiera:yaml` task looks for data with: +* `**/data/**/*.yaml` +* `hieradata/**/*.yaml` +* `hiera*.yaml` - PuppetSyntax.hieradata_paths = ["**/data/**/*.yaml", "hieradata/**/*.yaml", "hiera*.yaml"] +### manifests -## Installation +Checks all `.pp` files in the module for syntax errors. -Add this line to your application's Gemfile: +### templates - gem 'puppet-syntax' +#### erb -And then execute: +Checks `.erb` files in the module for syntax errors. - $ bundle +#### epp -Or install it yourself as: +Checks `.epp` files in the module for syntax errors. - $ gem install puppet-syntax +EPP checks are supported in Puppet 4 or greater, or in Puppet 3 with the future parser enabled. ## Contributing -1. Fork it -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 +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. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000000000000000000000000000000000000..eaf11f4fbaf07a700774520d8215db24a09b72e5 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,38 @@ +build: 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 diff --git a/lib/puppet-syntax.rb b/lib/puppet-syntax.rb index 65aa45663018ab7886ff102a016b3d5cd61058f8..98f83f930d9aa3117231a43065a6ebc48eb466ae 100644 --- a/lib/puppet-syntax.rb +++ b/lib/puppet-syntax.rb @@ -2,14 +2,32 @@ require "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"] + @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 + 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 diff --git a/lib/puppet-syntax/hiera.rb b/lib/puppet-syntax/hiera.rb index c6f200a0da59cc74e036fda0753ba376a9e03b45..c492ebb1b3e47464c3ba91f5baedf4657e648764 100644 --- a/lib/puppet-syntax/hiera.rb +++ b/lib/puppet-syntax/hiera.rb @@ -2,6 +2,24 @@ require '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) @@ -9,11 +27,20 @@ module PuppetSyntax filelist.each do |hiera_file| begin - YAML.load_file(hiera_file) + 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 + end errors.map! { |e| e.to_s } diff --git a/lib/puppet-syntax/manifests.rb b/lib/puppet-syntax/manifests.rb index 821fc054933078b1e6463fba902483cbf787b193..505ab33ea4cd703254ce191d336e580d184bafa1 100644 --- a/lib/puppet-syntax/manifests.rb +++ b/lib/puppet-syntax/manifests.rb @@ -58,7 +58,8 @@ module PuppetSyntax private def validate_manifest(file) - Puppet[:parser] = 'future' if PuppetSyntax.future_parser and Puppet::PUPPETVERSION.to_i < 4 + 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 diff --git a/lib/puppet-syntax/tasks/puppet-syntax.rb b/lib/puppet-syntax/tasks/puppet-syntax.rb index 4af27a1b1887b788f1d64b299548aa4639fec451..c8a14303d2e9faa30fd3886a73b54b7c6d5f552a 100644 --- a/lib/puppet-syntax/tasks/puppet-syntax.rb +++ b/lib/puppet-syntax/tasks/puppet-syntax.rb @@ -4,6 +4,24 @@ 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 => [ @@ -15,7 +33,7 @@ module PuppetSyntax namespace :syntax do task :check_puppetlabs_spec_helper do - psh_present = Rake::Task[:syntax].actions.any? { |a| + psh_present = task(:syntax).actions.any? { |a| a.inspect.match(/puppetlabs_spec_helper\/rake_tasks\.rb:\d+/) } @@ -30,33 +48,35 @@ to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax. desc 'Syntax check Puppet manifests' task :manifests do |t| - if Puppet::PUPPETVERSION.to_i >= 4 and PuppetSyntax.future_parser + 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}" - files = FileList["**/*.pp"] - files.reject! { |f| File.directory?(f) } - files = files.exclude(*PuppetSyntax.exclude_paths) c = PuppetSyntax::Manifests.new - output, has_errors = c.check(files) - print "#{output.join("\n")}\n" unless output.empty? - fail if has_errors || ( output.any? && PuppetSyntax.fail_on_deprecation_notices ) + 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}" - files = FileList["**/templates/**/*"] - files.reject! { |f| File.directory?(f) } - files = files.exclude(*PuppetSyntax.exclude_paths) c = PuppetSyntax::Templates.new - errors = c.check(files) - fail errors.join("\n") unless errors.empty? + 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' @@ -67,13 +87,10 @@ to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax. namespace :hiera do task :yaml do |t| $stderr.puts "---> #{t.name}" - files = FileList.new(PuppetSyntax.hieradata_paths) - files.reject! { |f| File.directory?(f) } - files = files.exclude(*PuppetSyntax.exclude_paths) - c = PuppetSyntax::Hiera.new - errors = c.check(files) - fail errors.join("\n") unless errors.empty? + errors = c.check(filelist_hiera_yaml) + $stdout.puts "#{errors.join("\n")}\n" unless errors.empty? + exit 1 unless errors.empty? end end end diff --git a/lib/puppet-syntax/templates.rb b/lib/puppet-syntax/templates.rb index 25257b4b3b9da96754d89a339c8c9e2569bb93bc..c62a70649b659546e7628c4e4e3b2ec1af6f26dd 100644 --- a/lib/puppet-syntax/templates.rb +++ b/lib/puppet-syntax/templates.rb @@ -14,7 +14,7 @@ module PuppetSyntax filelist.each do |file| if File.extname(file) == '.epp' or PuppetSyntax.epp_only errors.concat validate_epp(file) - else + elsif File.extname(file) == '.erb' errors.concat validate_erb(file) end end @@ -27,7 +27,7 @@ module PuppetSyntax end def validate_epp(filename) - if Puppet::PUPPETVERSION.to_f < 3.7 + if Puppet.version.to_f < 3.7 raise "Cannot validate EPP without Puppet 4 or future parser (3.7+)" end diff --git a/lib/puppet-syntax/version.rb b/lib/puppet-syntax/version.rb index d3de70c13969250d2bde73d013816479fffd2a7d..d339b66b17b765213a8bd2fa6f8b347058a77dfc 100644 --- a/lib/puppet-syntax/version.rb +++ b/lib/puppet-syntax/version.rb @@ -1,3 +1,3 @@ module PuppetSyntax - VERSION = "2.2.0" + VERSION = "2.4.1" end diff --git a/puppet-syntax.gemspec b/puppet-syntax.gemspec index f84147c58b5b7abbc14aa0f547b136f5bcf885e2..7731acf46cefc0402c7ba64f5562375064a1f393 100644 --- a/puppet-syntax.gemspec +++ b/puppet-syntax.gemspec @@ -6,11 +6,11 @@ require 'puppet-syntax/version' Gem::Specification.new do |spec| spec.name = "puppet-syntax" spec.version = PuppetSyntax::VERSION - spec.authors = ["Dan Carley"] - spec.email = ["dan.carley@gmail.com"] + 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/gds-operations/puppet-syntax" + spec.homepage = "https://github.com/voxpupuli/puppet-syntax" spec.license = "MIT" spec.files = `git ls-files`.split($/) @@ -20,6 +20,7 @@ Gem::Specification.new do |spec| spec.add_dependency "rake" - spec.add_development_dependency "rspec" + spec.add_development_dependency "pry" + spec.add_development_dependency "rb-readline" spec.add_development_dependency "gem_publisher", "~> 1.3" end diff --git a/spec/fixtures/hiera/data/hiera_1.yaml b/spec/fixtures/hiera/data/hiera_1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/spec/fixtures/hiera/data/hiera_2.eyaml b/spec/fixtures/hiera/data/hiera_2.eyaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/spec/fixtures/hiera/data/test/hiera_3.yaml b/spec/fixtures/hiera/data/test/hiera_3.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/spec/fixtures/hiera/data/test/hiera_4.eyaml b/spec/fixtures/hiera/data/test/hiera_4.eyaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/spec/fixtures/hiera/hiera_badkey.yaml b/spec/fixtures/hiera/hiera_badkey.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1f45f48b9fd9f3117a34f1c7898c931050777b7 --- /dev/null +++ b/spec/fixtures/hiera/hiera_badkey.yaml @@ -0,0 +1,11 @@ +--- +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 diff --git a/spec/fixtures/hiera/hiera_key_empty.yaml b/spec/fixtures/hiera/hiera_key_empty.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/spec/fixtures/test_module/manifests/test_app.pp b/spec/fixtures/test_module/manifests/test_app.pp new file mode 100644 index 0000000000000000000000000000000000000000..e15d502130321b946fa9d3e493f9664da7c98afa --- /dev/null +++ b/spec/fixtures/test_module/manifests/test_app.pp @@ -0,0 +1,3 @@ +application test_app { + +} diff --git a/spec/fixtures/test_module/templates/ignore.tpl b/spec/fixtures/test_module/templates/ignore.tpl new file mode 100644 index 0000000000000000000000000000000000000000..31ea616157f87f6b37d064802320f91cea38394d --- /dev/null +++ b/spec/fixtures/test_module/templates/ignore.tpl @@ -0,0 +1,3 @@ +This is plain text +<% This is not valid Ruby %> +This is also plain text diff --git a/spec/puppet-syntax/hiera_spec.rb b/spec/puppet-syntax/hiera_spec.rb index 8e750522ac48131a52cf6c83099fdc368a42f3ed..5662698c34cd1ef5b0369d2fdb649d59b88c5646 100644 --- a/spec/puppet-syntax/hiera_spec.rb +++ b/spec/puppet-syntax/hiera_spec.rb @@ -21,4 +21,34 @@ describe PuppetSyntax::Hiera do 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 diff --git a/spec/puppet-syntax/manifests_spec.rb b/spec/puppet-syntax/manifests_spec.rb index 738b99bdc5425c651caad577bfaeeefef847ec56..69d8d51e20f560630b0a64128360ff7948ed9dcb 100644 --- a/spec/puppet-syntax/manifests_spec.rb +++ b/spec/puppet-syntax/manifests_spec.rb @@ -28,9 +28,9 @@ describe PuppetSyntax::Manifests do files = fixture_manifests('fail_error.pp') output, has_errors = subject.check(files) - if Puppet::PUPPETVERSION.to_i >= 4 + if Puppet.version.to_i >= 4 expect(output.size).to eq(3) - expect(output[2]).to match(/Found 2 errors. Giving up/) + expect(output[2]).to match(/2 errors. Giving up/) expect(has_errors).to eq(true) else expect(output.size).to eq(1) @@ -72,11 +72,11 @@ describe PuppetSyntax::Manifests do output, has_errors = subject.check(files) expect(has_errors).to eq(true) - if Puppet::PUPPETVERSION.to_i >= 4 + 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('Found 2 errors. Giving up') + 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 @@ -136,6 +136,50 @@ describe PuppetSyntax::Manifests do 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 @@ -167,7 +211,7 @@ describe PuppetSyntax::Manifests do PuppetSyntax.future_parser = true } - if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0 and Puppet::PUPPETVERSION.to_i < 4 + 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']) diff --git a/spec/puppet-syntax/tasks/puppet-syntax_spec.rb b/spec/puppet-syntax/tasks/puppet-syntax_spec.rb index e3be1670a40734188ddf15d01d4b2cb064ccb888..f1117c9a408f9cb7f046735bd525a0ab22b0bc5d 100644 --- a/spec/puppet-syntax/tasks/puppet-syntax_spec.rb +++ b/spec/puppet-syntax/tasks/puppet-syntax_spec.rb @@ -1,8 +1,42 @@ require '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 @@ -10,11 +44,12 @@ describe 'PuppetSyntax rake tasks' do end end - it 'should generate FileList of templates relative to Rakefile' do + it 'should check templates relative to Rakefile' do if RSpec::Version::STRING < '3' pending else skip('needs to be done') end end + end diff --git a/spec/puppet-syntax/templates_spec.rb b/spec/puppet-syntax/templates_spec.rb index ade5d6068eb17764295de25f61345c95c661e828..cb97a1663d9effcb8c12a4f23fa5a2294939b0b8 100644 --- a/spec/puppet-syntax/templates_spec.rb +++ b/spec/puppet-syntax/templates_spec.rb @@ -60,7 +60,14 @@ describe PuppetSyntax::Templates do expect(res).to match([]) end - if Puppet::PUPPETVERSION.to_f < 3.7 + 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') @@ -80,7 +87,7 @@ describe PuppetSyntax::Templates do end end - if Puppet::PUPPETVERSION.to_f >= 3.7 + 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') diff --git a/spec/puppet-syntax_spec.rb b/spec/puppet-syntax_spec.rb index 7ab5d2289e151a20e744c062facd70f19c9f5096..fe85b5475ded6ed74092d147937c95142edd7abb 100644 --- a/spec/puppet-syntax_spec.rb +++ b/spec/puppet-syntax_spec.rb @@ -3,6 +3,7 @@ require '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 @@ -24,6 +25,15 @@ describe PuppetSyntax do 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)