puppet-check 1.6.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4351237d9dbb4f8790fb4b3aa77dce9a3274b9146b566261ca089c4759c634ee
4
- data.tar.gz: 4a6c8d9e48b456bea5a130e3984613f7cb923891c9fe6779ac481ffdc043a3c1
3
+ metadata.gz: 7f43468b01f25dba9ea6e997c982c632fb884d6cb8ec8faa31a670ac523a8ee8
4
+ data.tar.gz: 5baeb571e293b32c6120448d45c036523b96ffc0a325ba02c6f47e70323c1f3f
5
5
  SHA512:
6
- metadata.gz: dcf4c5c9ec7906f130f8ae74f61b1efaab297d33276f1587c88ac68bea8f25a09aa1deeac0ede9cee835e0b2bed95b404e1a208649df29e76693d56a37ab867c
7
- data.tar.gz: 1b4a1c372216d42d5e0e547e98a606866d0576da2e494d56340eb7a025e0f3763a9139ca18c24165a473c03429c1cf271ca0606017889e29dfbead14a0e5e7da
6
+ metadata.gz: f0ff327a57b78229800e56dae894b863ff0217d9ae8f368d7ff9db048160b29c0b1365144fb4db596c3951fafa4b5569d0c5ad741e7d0b3fa1a3491ed64fed50
7
+ data.tar.gz: 7b15f95dc0876eb1d8a6b9fa5295c45858fc7eef02ba6a2924c68ad29dadf6fa179c62ed32eae167923f39172eb9b1464910f48e7072dfaf8e9d98328dd6739e
data/CHANGELOG.md CHANGED
@@ -1,4 +1,24 @@
1
- ### 1.6.1 (Next)
1
+ ### 2.1.0 (Roadmap)
2
+ - Minimum supported version of Puppet bumped to 5.0.
3
+ - Minimum Ruby version bumped to 2.4.
4
+ - Official support for Puppet 7, Rubocop 1, and Reek 6.
5
+ - Fix Puppet message string transform conditionals.
6
+
7
+ ### 2.0.1
8
+ - Check for existence of executables for dependency module retrieval.
9
+ - Beta support for Puppet 7, Rubocop 1, and Reek 6.
10
+
11
+ ### 2.0.0
12
+ - Bump minimum version of Puppet to 4.0.0 and remove < 4 support code.
13
+ - Official support for Puppet 6.
14
+ - Minimum Ruby version bumped to 2.2.0.
15
+ - Bumped Rubocop and Reek minimum versions and fully migrated SPDX to Rubygems.
16
+ - Add rubocop-performance extension to Rubocop.
17
+ - Update manifest validation for breaking change in 6.5 API.
18
+ - Fix check on specified dependencies in metadata.
19
+ - Enable parallel module dependency retrieval.
20
+
21
+ ### 1.6.1
2
22
  - Removed check for hieradata nil/undef value for Hiera >= 5.
3
23
  - Add rudimentary checks for task metadata.
4
24
  - Preliminary support for Puppet 6.
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Puppet Check
2
- [![Build Status](https://travis-ci.org/mschuchard/puppet-check.svg?branch=master)](https://travis-ci.org/mschuchard/puppet-check)
2
+ [![Build Status](https://travis-ci.com/mschuchard/puppet-check.svg?branch=master)](https://travis-ci.com/mschuchard/puppet-check)
3
+ [![CircleCI](https://circleci.com/gh/mschuchard/puppet-check.svg?style=svg)](https://circleci.com/gh/mschuchard/puppet-check)
3
4
 
4
5
  - [Description](#description)
5
6
  - [Usage](#usage)
@@ -124,14 +125,16 @@ The following files have unrecognized formats and therefore were not processed:
124
125
  ### What About Puppet Development Kit?
125
126
  The fairly recent release of the Puppet Development Kit (PDK) will hopefully eventually bring about the capability to test and validate your Puppet code and data in a streamlined, efficient, comprehensive, and accurate fashion comparable to Puppet Check. Unfortunately, the PDK has not yet achieved feature or efficiency parity with Puppet Check. The goal is for the PDK to one day replace Puppet Check and for Puppet Check to enter maintenance mode, but for now Puppet Check is still needed to lead Puppet testing.
126
127
 
128
+ ### What About PDK now?
129
+ As of version 2.4.0 of the PDK, the PDK has essentially more or less achieved feature parity with Puppet Check. Although the PDK is not as efficient (including especially that Puppet Check executes significantly faster), it is still supported by Puppetlabs. Therefore, if you need an efficient and comprehensive Puppet validation solution, then you can still utilize Puppet Check, but the PDK is a recommended alternative for the future.
130
+
127
131
  ## Usage
128
- Please see the [Gemspec](puppet-check.gemspec) for dependency information. All other dependencies should be fine with various versions. Puppet Check can be used with a CLI, Rake tasks, or API, from your system, rbenv, rvm, Docker, or Vagrant. Please note all interfaces (API by default, but can be modified) will ignore any directories named `fixtures` or specified paths with that directory during file checks and spec tests.
132
+ Please see the [Gemspec](puppet-check.gemspec) for dependency information. All other dependencies should be fine with various versions. Puppet Check can be used with a CLI, Rake tasks, or API, from your system, rbenv, rvm, Docker, or Vagrant. Please note all interfaces (API by default, but can be modified) will ignore any directories named `fixtures`, or specified paths with that directory during file checks and spec tests.
129
133
 
130
134
  ### CLI
131
135
  ```
132
136
  usage: puppet-check [options] paths
133
137
  --version Display the current version.
134
- -f, --future Enable future parser
135
138
  --fail-on-warnings Fail on warnings
136
139
  -s, --style Enable style checks
137
140
  --smoke Enable smoke testing
@@ -148,7 +151,7 @@ usage: puppet-check [options] paths
148
151
  --rubocop arg_one,arg_two Arguments for Rubocop disabled cops
149
152
  ```
150
153
 
151
- The command line interface enables the ability to select the Puppet future parser, additional style checks besides the syntax checks, and to specify PuppetLint and Rubocop checks to ignore. If you require a more robust interface to PuppetLint, Rubocop, and Reek, then please use `.puppet-lint.rc`, `.rubocop.yml` and `*.reek` config files. The `.puppet-lint.rc` can be specified with the `-c` argument. If it is not specified, then PuppetLint will automatically load one from `.puppet-lint.rc`, `~/.puppet-lint.rc`, or `/etc/puppet-lint.rc`, in that order of preference. The nearest `.rubocop.yml` and `*.reek` will be automatically respected.
154
+ The command line interface enables the ability to select additional style checks besides the syntax checks, and to specify PuppetLint and Rubocop checks to ignore. If you require a more robust interface to PuppetLint, Rubocop, and Reek, then please use `.puppet-lint.rc`, `.rubocop.yml` and `*.reek` config files. The `.puppet-lint.rc` can be specified with the `-c` argument. If it is not specified, then PuppetLint will automatically load one from `.puppet-lint.rc`, `~/.puppet-lint.rc`, or `/etc/puppet-lint.rc`, in that order of preference. The nearest `.rubocop.yml` and `*.reek` will be automatically respected.
152
155
 
153
156
  Example:
154
157
  ```
@@ -167,15 +170,14 @@ rake puppetcheck:kitchen:* # Execute Test Kitchen acceptance tests
167
170
  ```
168
171
 
169
172
  #### puppetcheck:file
170
- You can add style, smoke, and regression checks to and select the future parser for the `rake puppetcheck:file`, or change the output format, by adding the following after the require:
173
+ You can add style, smoke, and regression checks to the `rake puppetcheck:file`, or change the output format, by adding the following after the require:
171
174
 
172
175
  ```ruby
173
176
  # example of modifying Puppet Check behavior
174
- PuppetCheck.settings[:style_check] = true
177
+ PuppetCheck.settings[:style] = true
175
178
  PuppetCheck.settings[:fail_on_warnings] = true
176
- PuppetCheck.settings[:future_parser] = true
177
- PuppetCheck.settings[:smoke_check] = true
178
- PuppetCheck.settings[:regression_check] = true # in progress, do not use
179
+ PuppetCheck.settings[:smoke] = true
180
+ PuppetCheck.settings[:regression] = true # in progress, do not use
179
181
  PuppetCheck.settings[:public] = 'public.pem'
180
182
  PuppetCheck.settings[:private] = 'private.pem'
181
183
  PuppetCheck.settings[:output_format] = 'yaml'
@@ -256,11 +258,10 @@ If you are performing your Puppet testing from within a Ruby script or your own
256
258
  require 'puppet-check'
257
259
 
258
260
  settings = {}
259
- settings[:future_parser] = true # default false
260
261
  settings[:fail_on_warnings] = true # default false
261
- settings[:style_check] = true # default false
262
- settings[:smoke_check] = true # default false
263
- settings[:regression_check] = true # in progress, do not use; default false
262
+ settings[:style] = true # default false
263
+ settings[:smoke] = true # default false
264
+ settings[:regression] = true # in progress, do not use; default false
264
265
  settings[:public] = 'public.pem' # default nil
265
266
  settings[:private] = 'private.pem' # default nil
266
267
  settings[:output_format] = 'yaml' # also 'json'; default 'text'
@@ -280,15 +281,15 @@ task.pattern = Dir.glob('**/{classes,defines,facter,functions,hosts,puppet,unit,
280
281
 
281
282
  ### Docker
282
283
 
283
- You can also use Puppet Check inside of Docker for quick, portable, and disposable testing. Below is an example Dockerfile for this purpose:
284
+ You can also use Puppet Check inside of Docker for quick, portable, and disposable testing. Below is an example `Dockerfile` for this purpose:
284
285
 
285
286
  ```dockerfile
286
- # a reliable and small container at the moment
287
- FROM ubuntu:18.04
287
+ # a reliable and small container; today should maybe use ruby:slim instead
288
+ FROM ubuntu:20.04
288
289
  # you need ruby and any other extra dependencies that come from packages; in this example we install git to use it for downloading external module dependencies
289
290
  RUN apt-get update && apt-get install ruby git -y
290
- # you need puppet-check and any other extra dependencies that come from gems; in this example we install reek because the ruby ABI is 2.3 and then rspec-puppet and rake for extra testing
291
- RUN gem install --no-document puppet-check reek rspec-puppet rake
291
+ # you need puppet-check and any other extra dependencies that come from gems; in this example we install rspec-puppet and rake for extra testing
292
+ RUN gem install --no-document puppet-check rspec-puppet rake
292
293
  # this is needed for the ruby json parser to not flip out on fresh os installs for some reason (change encoding value as necessary)
293
294
  ENV LANG en_US.UTF-8
294
295
  # create the directory for your module, directory environment, etc. and change directory into it
@@ -299,24 +300,26 @@ COPY / .
299
300
  ENTRYPOINT ["rake", "puppetcheck"]
300
301
  ```
301
302
 
302
- You can also build your own general container for testing various Puppet situations by removing the last three lines. You can then test each module, directory environment, etc. on top of that container by merely adding and modifying the final three lines to a Dockerfile that uses the container you built from the first four lines. This is recommended usage due to being very efficient and stable.
303
+ You can also build your own general container image for testing various Puppet situations by removing the last three lines. You can then test each module, directory environment, etc. on top of that container by merely adding and modifying the final three lines to a `Dockerfile` that uses the container you built from the first four lines. This is recommended usage due to being very efficient and stable.
304
+
305
+ As an alternative to copying Puppet code and data into the image for testing, it is also recommended to bind volume mount the container to the directory with your Puppet code and data.
303
306
 
304
307
  ### Vagrant
305
308
 
306
- As an alternative to Docker, you can also use Vagrant for quick and disposable testing, but it is not as portable as Docker for these testing purposes. Below is an example Vagrantfile for this purpose.
309
+ As an alternative to Docker, you can also use Vagrant for quick and disposable testing, but it is not as portable as Docker for these testing purposes. Below is an example `Vagrantfile` for this purpose.
307
310
 
308
311
  ```ruby
309
312
  Vagrant.configure(2) do |config|
310
313
  # a reliable and small box at the moment
311
- config.vm.box = 'fedora/26-cloud-base'
314
+ config.vm.box = 'fedora/35-cloud-base'
312
315
 
313
316
  config.vm.provision 'shell', inline: <<-SHELL
314
317
  # cd to '/vagrant'
315
318
  cd /vagrant
316
319
  # you need ruby and any other extra dependencies that come from packages; in this example we install git to use it for downloading external module dependencies
317
320
  sudo dnf install ruby rubygems git -y
318
- # you need puppet-check and any other extra dependencies that come from gems; in this example we install reek because the ruby ABI is 2.2 and then rspec-puppet and rake for extra testing
319
- sudo gem install --no-document puppet-check reek rspec-puppet rake
321
+ # you need puppet-check and any other extra dependencies that come from gems; in this example we install rspec-puppet and rake for extra testing
322
+ sudo gem install --no-document puppet-check rspec-puppet rake
320
323
  # this is needed for the ruby json parser to not flip out on fresh os installs for some reason (change encoding value as necessary)
321
324
  export LANG='en_US.UTF-8'
322
325
  # execute your tests; in this example we are executing the full suite of tests
@@ -330,7 +333,7 @@ To overcome the lack of convenient portability, you could try spinning up the Va
330
333
  ### Exit Codes
331
334
  - 0: PuppetCheck exited with no internal exceptions or errors in your code and data.
332
335
  - 1: PuppetCheck exited with an internal exception (takes preference over other non-zero exit codes) or failed spec test(s).
333
- - 2: PuppetCheck exited with one or more errors in your code and data. Alternatively, PuppetCheck exited with one or more warnings in your code and data and you specified to fail on warnings.
336
+ - 2: PuppetCheck exited with one or more errors in your code and data. Alternatively, PuppetCheck exited with one or more warnings in your code and data, and you specified to fail on warnings.
334
337
 
335
338
  ### Optional Dependencies
336
339
  - **rake** (gem): install this if you want to use Puppet Check with `rake` tasks in addition to the CLI.
@@ -1,5 +1,5 @@
1
1
  require 'optparse'
2
- require_relative '../puppet-check'
2
+ require_relative '../puppet_check'
3
3
 
4
4
  # the command line interface for PuppetCheck
5
5
  class PuppetCheck::CLI
@@ -27,16 +27,15 @@ class PuppetCheck::CLI
27
27
 
28
28
  # base options
29
29
  opts.on('--version', 'Display the current version.') do
30
- puts 'puppet-check 1.6.1'
30
+ puts 'puppet-check 2.1.0'
31
31
  exit 0
32
32
  end
33
33
 
34
34
  # bool options
35
- opts.on('-f', '--future', 'Enable future parser') { settings[:future_parser] = true }
36
35
  opts.on('--fail-on-warnings', 'Fail on warnings') { settings[:fail_on_warnings] = true }
37
- opts.on('-s', '--style', 'Enable style checks') { settings[:style_check] = true }
38
- opts.on('--smoke', 'Enable smoke testing') { settings[:smoke_check] = true }
39
- opts.on('-r', '--regression', 'Enable regression testing (in progress, do not use)') { settings[:regression_check] = true }
36
+ opts.on('-s', '--style', 'Enable style checks') { settings[:style] = true }
37
+ opts.on('--smoke', 'Enable smoke testing') { settings[:smoke] = true }
38
+ opts.on('-r', '--regression', 'Enable regression testing (in progress, do not use)') { settings[:regression] = true }
40
39
 
41
40
  # ssl key options for eyaml checks
42
41
  opts.on('--public cert.pem', String, 'Public key for EYAML checks') { |arg| settings[:public] = arg }
@@ -1,4 +1,4 @@
1
- require_relative '../puppet-check'
1
+ require_relative '../puppet_check'
2
2
 
3
3
  # executes diagnostics on data files
4
4
  class DataParser
@@ -85,7 +85,7 @@ class DataParser
85
85
  # check metadata.json
86
86
  if File.basename(file) == 'metadata.json'
87
87
  # metadata-json-lint has issues and is essentially no longer maintained, so here is an improved and leaner version of it
88
- require 'spdx-licenses'
88
+ require 'rubygems/util/licenses'
89
89
 
90
90
  # check for errors
91
91
  errors = []
@@ -97,7 +97,7 @@ class DataParser
97
97
 
98
98
  # check requirements and dependencies keys
99
99
  %w[requirements dependencies].each do |key|
100
- # skip if key is missing or or value is an empty string, array, or hash
100
+ # skip if key is missing or value is an empty string, array, or hash
101
101
  next if !parsed.key?(key) || parsed[key].empty?
102
102
 
103
103
  # check that dependencies and requirements are an array of hashes
@@ -118,8 +118,8 @@ class DataParser
118
118
  next warnings.push("'#{req_dep['name']}' is missing an upper bound.") unless req_dep['version_requirement'].include?('<')
119
119
 
120
120
  # check for semantic versioning
121
- if key == 'dependencies'
122
- warnings.push("'#{req_dep['name']}' has non-semantic versioning in its 'version_requirement' key.") unless req_dep['version_requirement'] =~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/
121
+ if key == 'dependencies' && req_dep['version_requirement'] !~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/
122
+ warnings.push("'#{req_dep['name']}' has non-semantic versioning in its 'version_requirement' key.")
123
123
  end
124
124
  end
125
125
  end
@@ -161,16 +161,8 @@ class DataParser
161
161
  end
162
162
 
163
163
  # check for spdx license
164
- begin
165
- require 'rubygems/util/licenses'
166
-
167
- if parsed.key?('license') && !Gem::Licenses.match?(parsed['license']) && parsed['license'] !~ /[pP]roprietary/
168
- warnings.push("License identifier '#{parsed['license']}' is not in the SPDX list: http://spdx.org/licenses/")
169
- end
170
- rescue LoadError
171
- if parsed.key?('license') && !SpdxLicenses.exist?(parsed['license']) && parsed['license'] !~ /[pP]roprietary/
172
- warnings.push("License identifier '#{parsed['license']}' is not in the SPDX list: http://spdx.org/licenses/")
173
- end
164
+ if parsed.key?('license') && !Gem::Licenses.match?(parsed['license']) && parsed['license'] !~ /[pP]roprietary/
165
+ warnings.push("License identifier '#{parsed['license']}' is not in the SPDX list: http://spdx.org/licenses/")
174
166
  end
175
167
  # assume this is task metadata if it has this key
176
168
  elsif parsed.key?('description')
@@ -185,16 +177,16 @@ class DataParser
185
177
  end
186
178
  end
187
179
  # check that parameters is a hash
188
- if parsed.key?('parameters')
189
- warnings.push('parameters value is not a Hash') unless parsed['parameters'].is_a?(Hash)
180
+ if parsed.key?('parameters') && !parsed['parameters'].is_a?(Hash)
181
+ warnings.push('parameters value is not a Hash')
190
182
  end
191
183
  # check that puppet_task_version is an integer
192
- if parsed.key?('puppet_task_version')
193
- warnings.push('puppet_task_version value is not an Integer') unless parsed['puppet_task_version'].is_a?(Integer)
184
+ if parsed.key?('puppet_task_version') && !parsed['puppet_task_version'].is_a?(Integer)
185
+ warnings.push('puppet_task_version value is not an Integer')
194
186
  end
195
187
  # check that supports_noop is a boolean
196
- if parsed.key?('supports_noop')
197
- warnings.push('supports_noop value is not a Boolean') unless parsed['supports_noop'].is_a?(TrueClass) || parsed['supports_noop'].is_a?(FalseClass)
188
+ if parsed.key?('supports_noop') && !(parsed['supports_noop'].is_a?(TrueClass) || parsed['supports_noop'].is_a?(FalseClass))
189
+ warnings.push('supports_noop value is not a Boolean')
198
190
  end
199
191
  # assume this is hieradata and ensure it is non-empty
200
192
  elsif parsed
@@ -213,7 +205,7 @@ class DataParser
213
205
  warnings = []
214
206
 
215
207
  # disregard nil/undef value data check if default values (common)
216
- unless file =~ /^common/
208
+ unless /^common/.match?(file)
217
209
  data.each do |key, value|
218
210
  # check for nil values in the data (nil keys are fine)
219
211
  if (value.is_a?(Hash) && value.values.any?(&:nil?)) || value.nil?
@@ -1,4 +1,4 @@
1
- require_relative '../puppet-check'
1
+ require_relative '../puppet_check'
2
2
 
3
3
  # class to handle outputting diagnostic results in desired format
4
4
  class OutputResults
@@ -22,7 +22,7 @@ class OutputResults
22
22
  end
23
23
 
24
24
  # output the results as yaml or json
25
- def self.markup
25
+ def self.markup(format)
26
26
  # generate output hash
27
27
  hash = {}
28
28
  hash['errors'] = PuppetCheck.settings[:error_files] unless PuppetCheck.settings[:error_files].empty?
@@ -31,14 +31,15 @@ class OutputResults
31
31
  hash['ignored'] = PuppetCheck.settings[:ignored_files] unless PuppetCheck.settings[:ignored_files].empty?
32
32
 
33
33
  # convert hash to markup language
34
- if PuppetCheck.settings[:output_format] == 'yaml'
34
+ case format
35
+ when 'yaml'
35
36
  require 'yaml'
36
37
  puts Psych.dump(hash, indentation: 2)
37
- elsif PuppetCheck.settings[:output_format] == 'json'
38
+ when 'json'
38
39
  require 'json'
39
40
  puts JSON.pretty_generate(hash)
40
41
  else
41
- raise "puppet-check: Unsupported output format '#{PuppetCheck.settings[:output_format]}' was specified."
42
+ raise "puppet-check: Unsupported output format '#{format}' was specified."
42
43
  end
43
44
  end
44
45
  end
@@ -1,42 +1,51 @@
1
1
  require 'puppet'
2
- require_relative '../puppet-check'
2
+ require_relative '../puppet_check'
3
3
 
4
4
  # executes diagnostics on puppet files
5
5
  class PuppetParser
6
6
  # checks puppet (.pp)
7
- def self.manifest(files, future, style, pl_args)
7
+ def self.manifest(files, style, pl_args)
8
8
  require 'puppet/face'
9
9
 
10
10
  # prepare the Puppet settings for the error checking
11
11
  Puppet.initialize_settings unless Puppet.settings.app_defaults_initialized?
12
- Puppet[:parser] = 'future' if future && (Puppet::PUPPETVERSION.to_i < 4)
13
12
 
14
13
  files.each do |file|
15
- # setup error logging and collection
14
+ # setup error logging and collection; warnings logged for all versions, but errors for only puppet < 6.5
16
15
  errors = []
17
16
  Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(errors))
18
17
 
19
18
  # check puppet syntax
20
19
  begin
21
- Puppet::Face[:parser, :current].validate(file)
20
+ # initialize message
21
+ message = ''
22
+ # in puppet >= 6.5 the return of this method is a hash with the error
23
+ new_error = Puppet::Face[:parser, :current].validate(file)
24
+ # puppet 6.5 output format is now a hash from the face api
25
+ if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('6.5.0') && new_error != {}
26
+ message = new_error.values.map(&:to_s).join("\n").gsub(/ \(file: #{File.absolute_path(file)}(, |\))/, '').gsub(/Could not parse.*: /, '')
27
+ end
22
28
  # this is the actual error that we need to rescue Puppet::Face from
23
29
  rescue SystemExit
24
- # puppet 5.4-5.x has a new validator output format and eof errors have fake dir env info
25
- if Puppet::PUPPETVERSION.to_f >= 5.4
26
- next PuppetCheck.settings[:error_files].push("#{file}:\n#{errors.map(&:to_s).join("\n").gsub(/file: #{File.absolute_path(file)}(, |\))/, '').gsub(/Could not parse.*: /, '')}")
27
- # puppet 5.0-5.2 can only do one error per line and outputs fake dir env info
28
- elsif Puppet::PUPPETVERSION.to_f >= 5.0 && Puppet::PUPPETVERSION.to_f < 5.3
29
- next PuppetCheck.settings[:error_files].push("#{file}:\n#{errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '').gsub(/Could not parse.*: /, '')}")
30
- end
31
- # puppet < 5 and 5.3 parser output style
32
- next PuppetCheck.settings[:error_files].push("#{file}:\n#{errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '')}")
30
+ # puppet 5.4-6.4 has a new validator output format and eof errors have fake dir env info
31
+ message = if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('5.4') && Gem::Version.new(Puppet::PUPPETVERSION) < Gem::Version.new('6.5')
32
+ errors.map(&:to_s).join("\n").gsub(/file: #{File.absolute_path(file)}(, |\))/, '').gsub(/Could not parse.*: /, '')
33
+ # puppet 5.0-5.2 can only do one error per line and outputs fake dir env info
34
+ elsif Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('5.0') && Gem::Version.new(Puppet::PUPPETVERSION) < Gem::Version.new('5.3')
35
+ errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '').gsub(/Could not parse.*: /, '')
36
+ # puppet < 5 and 5.3 parser output style
37
+ else
38
+ errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '')
39
+ end
33
40
  end
41
+ # output message
42
+ next PuppetCheck.settings[:error_files].push("#{file}:\n#{message}") unless message.empty?
34
43
 
35
44
  # initialize warnings with output from the parser if it exists, since the output is warnings if Puppet::Face did not trigger a SystemExit
36
45
  warnings = "#{file}:"
37
46
  unless errors.empty?
38
47
  # puppet 5.4-5.x has a new validator output format
39
- warnings << if Puppet::PUPPETVERSION.to_f >= 5.4
48
+ warnings << if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('5.4')
40
49
  "\n#{errors.map(&:to_s).join("\n").gsub("file: #{File.absolute_path(file)}, ", '')}"
41
50
  # puppet <= 5.3 validator output format
42
51
  else
@@ -77,9 +86,6 @@ class PuppetParser
77
86
  require 'puppet/pops'
78
87
 
79
88
  files.each do |file|
80
- # puppet before version 4 cannot check template syntax
81
- next PuppetCheck.settings[:ignored_files].push("#{file}: ignored due to Puppet < 4") if Puppet::PUPPETVERSION.to_i < 4
82
-
83
89
  # check puppet template syntax
84
90
  begin
85
91
  # credits to gds-operations/puppet-syntax for the parser function call
@@ -3,7 +3,7 @@ class RSpecPuppetSupport
3
3
  # code diagram:
4
4
  # 'puppetcheck:spec' task invokes 'run'
5
5
  # 'run' invokes 'file_setup' always and 'dependency_setup' if metadata.json exists
6
- # 'dependency_setup' invokes 'git/forge/hg' if dependencies exist and git/forge/hg is download option
6
+ # 'dependency_setup' invokes 'git/forge/svn/hg' if dependencies exist and git/forge/svn/hg is download option
7
7
  # 'git/forge/svn/hg' downloads module fixture appropriately
8
8
 
9
9
  # prepare the spec fixtures directory for rspec-puppet testing
@@ -15,10 +15,10 @@ class RSpecPuppetSupport
15
15
  # setup fixtures for rspec-puppet testing
16
16
  specdirs.each do |specdir|
17
17
  # skip to next specdir if it does not seem like a puppet module
18
- next unless File.directory?(specdir + '/../manifests')
18
+ next unless File.directory?("#{specdir}/../manifests")
19
19
 
20
20
  # change to module directory
21
- Dir.chdir(specdir + '/..')
21
+ Dir.chdir("#{specdir}/..")
22
22
 
23
23
  # grab the module name from the directory name of the module to pass to file_setup
24
24
  file_setup(File.basename(Dir.pwd))
@@ -66,7 +66,7 @@ class RSpecPuppetSupport
66
66
  parsed = JSON.parse(File.read('metadata.json'))
67
67
 
68
68
  # grab dependencies if they exist
69
- return if parsed['dependencies'].empty?
69
+ return unless parsed.key?('dependencies')
70
70
  parsed['dependencies'].each do |dependency_hash|
71
71
  # determine how the user wants to download the module dependency
72
72
  if dependency_hash.key?('git')
@@ -81,6 +81,7 @@ class RSpecPuppetSupport
81
81
  warn "#{dependency_hash['name']} has an unspecified, or specified but unsupported, download method."
82
82
  end
83
83
  end
84
+ Process.waitall
84
85
  end
85
86
 
86
87
  # download external module dependency with git
@@ -89,7 +90,11 @@ class RSpecPuppetSupport
89
90
  # establish path to clone module to
90
91
  path = "spec/fixtures/modules/#{File.basename(git_url, '.git')}"
91
92
  # is the module present and already cloned with git? do a pull; otherwise, do a clone
92
- File.directory?("#{path}/.git") ? system("git -C #{path} pull") : system("git clone #{args} #{git_url} #{path}")
93
+ begin
94
+ File.directory?("#{path}/.git") ? spawn("git -C #{path} pull") : spawn("git clone #{args} #{git_url} #{path}")
95
+ rescue Errno::ENOENT
96
+ warn 'git is not installed and cannot be used to retrieve dependency modules'
97
+ end
93
98
  end
94
99
 
95
100
  # download external module dependency with forge
@@ -97,7 +102,7 @@ class RSpecPuppetSupport
97
102
  private_class_method :method
98
103
  # is the module present? do an upgrade; otherwise, do an install
99
104
  subcommand = File.directory?("spec/fixtures/modules/#{forge_name}") ? 'upgrade' : 'install'
100
- system("puppet module #{subcommand} --modulepath spec/fixtures/modules/ #{args} #{forge_name}")
105
+ spawn("puppet module #{subcommand} --modulepath spec/fixtures/modules/ #{args} #{forge_name}")
101
106
  end
102
107
 
103
108
  # download external module dependency with svn
@@ -106,7 +111,11 @@ class RSpecPuppetSupport
106
111
  # establish path to checkout module to
107
112
  path = "spec/fixtures/modules/#{File.basename(svn_url)}"
108
113
  # is the module present and already checked out with svn? do an update; otherwise, do a checkout
109
- File.directory?("#{path}/.svn") ? system("svn update #{path}") : system("svn co #{args} #{svn_url} #{path}")
114
+ begin
115
+ File.directory?("#{path}/.svn") ? spawn("svn update #{path}") : spawn("svn co #{args} #{svn_url} #{path}")
116
+ rescue Errno::ENOENT
117
+ warn 'subversion is not installed and cannot be used to retrieve dependency modules'
118
+ end
110
119
  end
111
120
 
112
121
  # download external module dependency with hg
@@ -115,6 +124,10 @@ class RSpecPuppetSupport
115
124
  # establish path to clone module to
116
125
  path = "spec/fixtures/modules/#{File.basename(hg_url)}"
117
126
  # is the module present and already cloned with hg? do a pull and update; otherwise do a clone
118
- File.directory?("#{path}/.hg") ? system("hg --cwd #{path} pull; hg --cwd #{path} update") : system("hg clone #{args} #{hg_url} #{path}")
127
+ begin
128
+ File.directory?("#{path}/.hg") ? spawn("hg --cwd #{path} pull; hg --cwd #{path} update") : spawn("hg clone #{args} #{hg_url} #{path}")
129
+ rescue Errno::ENOENT
130
+ warn 'mercurial is not installed and cannot be used to retrieve dependency modules'
131
+ end
119
132
  end
120
133
  end
@@ -1,4 +1,4 @@
1
- require_relative '../puppet-check'
1
+ require_relative '../puppet_check'
2
2
  require_relative 'utils'
3
3
 
4
4
  # executes diagnostics on ruby files
@@ -18,7 +18,7 @@ class RubyParser
18
18
  require 'rubocop'
19
19
 
20
20
  # check RuboCop and collect warnings
21
- rubocop_warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--format', 'emacs', file]) }
21
+ rubocop_warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--require', 'rubocop-performance', '--format', 'emacs', file]) }
22
22
  warnings = rubocop_warnings == '' ? '' : rubocop_warnings.split("#{File.absolute_path(file)}:").join('')
23
23
 
24
24
  # check Reek and collect warnings
@@ -43,8 +43,14 @@ class RubyParser
43
43
  # check ruby template syntax
44
44
  begin
45
45
  # need to eventually have this associated with a different binding during each iteration
46
- warnings = Utils.capture_stderr { ERB.new(File.read(file), nil, '-').result }
47
- # ERB.new(File.read(file), nil, '-').result(RubyParser.new.bind)
46
+ # older usage throws extra warning and mixes with valid warnings confusingly
47
+ warnings = if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
48
+ Utils.capture_stderr { ERB.new(File.read(file), trim_mode: '-').result }
49
+ # ERB.new(File.read(file), trim_mode: '-').result(RubyParser.new.bind)
50
+ # and for extra fun it is incompatible with non-new ruby
51
+ else
52
+ Utils.capture_stderr { ERB.new(File.read(file), nil, '-').result }
53
+ end
48
54
  rescue NameError, TypeError
49
55
  # empty out warnings since it would contain an error if this pass triggers
50
56
  warnings = ''
@@ -62,10 +68,9 @@ class RubyParser
62
68
  # efficient var assignment prior to iterator
63
69
  if style
64
70
  require 'rubocop'
65
- # cop named differently depending upon version
66
- filename_cop = RuboCop::Version::STRING.to_f >= 0.5 ? 'Naming/FileName' : 'Style/FileName'
71
+
67
72
  # RuboCop is grumpy about non-snake_case filenames so disable the FileName check
68
- rc_args.include?('--except') ? rc_args[rc_args.index('--except') + 1] = "#{rc_args[rc_args.index('--except') + 1]},#{filename_cop}" : rc_args.concat(['--except', filename_cop])
73
+ rc_args.include?('--except') ? rc_args[rc_args.index('--except') + 1] = "#{rc_args[rc_args.index('--except') + 1]},Naming/FileName" : rc_args.concat(['--except', 'Naming/FileName'])
69
74
  end
70
75
 
71
76
  files.each do |file|
@@ -79,7 +84,7 @@ class RubyParser
79
84
  else
80
85
  if style
81
86
  # check Rubocop
82
- warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--format', 'emacs', file]) }
87
+ warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--require', 'rubocop-performance', '--format', 'emacs', file]) }
83
88
 
84
89
  # collect style warnings
85
90
  next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.split("#{File.absolute_path(file)}:").join('')}") unless warnings.empty?
@@ -3,7 +3,7 @@ begin
3
3
  rescue LoadError
4
4
  raise 'Rake is not installed and you are attempting to execute Rake tasks with Puppet Check. Please install Rake before continuing.'
5
5
  end
6
- require_relative '../puppet-check'
6
+ require_relative '../puppet_check'
7
7
 
8
8
  # the rake interface for PuppetCheck
9
9
  class PuppetCheck::Tasks < ::Rake::TaskLib