puppet-check 1.5.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,8 +4,6 @@ require_relative '../puppet-check'
4
4
  class DataParser
5
5
  # checks yaml (.yaml/.yml)
6
6
  def self.yaml(files)
7
- return if files.empty?
8
-
9
7
  require 'yaml'
10
8
 
11
9
  files.each do |file|
@@ -18,7 +16,7 @@ class DataParser
18
16
  warnings = []
19
17
 
20
18
  # perform some rudimentary hiera checks if data exists and is hieradata
21
- warnings = hiera(parsed, file) unless (parsed.class.to_s == 'NilClass') || (File.basename(file) == 'hiera.yaml')
19
+ warnings = hiera(parsed, file) if parsed && (File.basename(file) != 'hiera.yaml')
22
20
 
23
21
  next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.join("\n")}") unless warnings.empty?
24
22
  PuppetCheck.settings[:clean_files].push(file.to_s)
@@ -28,15 +26,19 @@ class DataParser
28
26
 
29
27
  # checks eyaml (.eyaml/.eyml)
30
28
  def self.eyaml(files, public, private)
31
- return if files.empty?
32
-
33
29
  require 'openssl'
34
30
 
35
31
  # keys specified?
36
- return warn 'Public X509 and/or Private RSA PKCS7 certs were not specified. EYAML checks will not be executed.' if public.nil? || private.nil?
32
+ if public.nil? || private.nil?
33
+ PuppetCheck.settings[:ignored_files].concat(files)
34
+ return warn 'Public X509 and/or Private RSA PKCS7 certs were not specified. EYAML checks will not be executed.'
35
+ end
37
36
 
38
37
  # keys exist?
39
- return warn 'Specified Public X509 and/or Private RSA PKCS7 certs do not exist. EYAML checks will not be executed.' unless File.file?(public) && File.file?(private)
38
+ unless File.file?(public) && File.file?(private)
39
+ PuppetCheck.settings[:ignored_files].concat(files)
40
+ return warn 'Specified Public X509 and/or Private RSA PKCS7 certs do not exist. EYAML checks will not be executed.'
41
+ end
40
42
 
41
43
  # setup decryption
42
44
  rsa = OpenSSL::PKey::RSA.new(File.read(private))
@@ -52,14 +54,14 @@ class DataParser
52
54
 
53
55
  # check yaml syntax
54
56
  begin
55
- parsed = YAML.safe_load(decrypted)
57
+ parsed = YAML.load_file(decrypted)
56
58
  rescue StandardError => err
57
59
  PuppetCheck.settings[:error_files].push("#{file}:\n#{err.to_s.gsub("(#{file}): ", '')}")
58
60
  else
59
61
  warnings = []
60
62
 
61
63
  # perform some rudimentary hiera checks if data exists and is hieradata
62
- warnings = hiera(parsed, file) unless (parsed.class.to_s == 'NilClass') || (File.basename(file) == 'hiera.yaml')
64
+ warnings = hiera(parsed, file) if parsed
63
65
 
64
66
  next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.join("\n")}") unless warnings.empty?
65
67
  PuppetCheck.settings[:clean_files].push(file.to_s)
@@ -69,8 +71,6 @@ class DataParser
69
71
 
70
72
  # checks json (.json)
71
73
  def self.json(files)
72
- return if files.empty?
73
-
74
74
  require 'json'
75
75
 
76
76
  files.each do |file|
@@ -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,9 +97,8 @@ 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
101
- next unless parsed.key?(key)
102
- next if parsed[key].empty?
100
+ # skip if key is missing or value is an empty string, array, or hash
101
+ next if !parsed.key?(key) || parsed[key].empty?
103
102
 
104
103
  # check that dependencies and requirements are an array of hashes
105
104
  next errors.push("Field '#{key}' is not an array of hashes.") unless (parsed[key].is_a? Array) && (parsed[key][0].is_a? Hash)
@@ -113,14 +112,14 @@ class DataParser
113
112
  names << name
114
113
 
115
114
  # warn and skip if key is missing
116
- next warnings.push("'#{req_dep['name']}' is missing a 'version_requirement' key.") if req_dep['version_requirement'].class.to_s == 'NilClass'
115
+ next warnings.push("'#{req_dep['name']}' is missing a 'version_requirement' key.") if req_dep['version_requirement'].nil?
117
116
 
118
117
  # warn and skip if no upper bound
119
118
  next warnings.push("'#{req_dep['name']}' is missing an upper bound.") unless req_dep['version_requirement'].include?('<')
120
119
 
121
120
  # check for semantic versioning
122
- if key == 'dependencies'
123
- 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.")
124
123
  end
125
124
  end
126
125
  end
@@ -161,14 +160,38 @@ class DataParser
161
160
  warnings.push('Recommended field \'operatingsystem_support\' not found.')
162
161
  end
163
162
 
164
- # check for spdx license (rubygems/util/licenses for rubygems >= 2.5 in the far future)
165
- if parsed.key?('license') && !SpdxLicenses.exist?(parsed['license']) && parsed['license'] !~ /[pP]roprietary/
163
+ # check for spdx license
164
+ if parsed.key?('license') && !Gem::Licenses.match?(parsed['license']) && parsed['license'] !~ /[pP]roprietary/
166
165
  warnings.push("License identifier '#{parsed['license']}' is not in the SPDX list: http://spdx.org/licenses/")
167
166
  end
168
- # assume this is hieradata
169
- else
167
+ # assume this is task metadata if it has this key
168
+ elsif parsed.key?('description')
169
+ # check that description is a string
170
+ warnings.push('description value is not a String') unless parsed['description'].is_a?(String)
171
+ # check that input_method is one of three possible values
172
+ if parsed.key?('input_method')
173
+ if parsed['input_method'].is_a?(String)
174
+ warnings.push('input_method value is not one of environment, stdin, or powershell') unless %w[environment stdin powershell].include?(parsed['input_method'])
175
+ else
176
+ warnings.push('input_method value is not a String')
177
+ end
178
+ end
179
+ # check that parameters is a hash
180
+ if parsed.key?('parameters') && !parsed['parameters'].is_a?(Hash)
181
+ warnings.push('parameters value is not a Hash')
182
+ end
183
+ # check that puppet_task_version is an 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')
186
+ end
187
+ # check that supports_noop is a boolean
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')
190
+ end
191
+ # assume this is hieradata and ensure it is non-empty
192
+ elsif parsed
170
193
  # perform some rudimentary hiera checks if data exists
171
- warnings = hiera(parsed, file) unless parsed.class.to_s == 'NilClass'
194
+ warnings = hiera(parsed, file)
172
195
  end
173
196
  next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.join("\n")}") unless warnings.empty?
174
197
  PuppetCheck.settings[:clean_files].push(file.to_s)
@@ -181,15 +204,19 @@ class DataParser
181
204
  private_class_method :method
182
205
  warnings = []
183
206
 
184
- data.each do |key, value|
185
- # check for nil values in the data (nil keys are fine)
186
- if (value.is_a?(Hash) && value.values.any?(&:nil?)) || (value.class.to_s == 'NilClass')
187
- warnings.push("Value(s) missing in key '#{key}'.")
207
+ # disregard nil/undef value data check if default values (common)
208
+ unless file =~ /^common/
209
+ # unless /^common/.match?(file) TODO: use when ruby >= 2.4
210
+ data.each do |key, value|
211
+ # check for nil values in the data (nil keys are fine)
212
+ if (value.is_a?(Hash) && value.values.any?(&:nil?)) || value.nil?
213
+ warnings.push("Value(s) missing in key '#{key}'.")
214
+ end
188
215
  end
189
216
  end
190
217
 
191
218
  # check that '---' does not show up more than once in the hieradata
192
- warnings.push('The string --- appears more than once in this data and Hiera will fail to parse it correctly.') if File.read(file).scan(/---/).count >= 2
219
+ warnings.push('The string --- appears more than once in this data and Hiera may fail to parse it correctly.') if File.read(file).scan(/---/).count >= 2
193
220
 
194
221
  warnings
195
222
  end
@@ -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(settings)
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 settings[:output_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 '#{settings[:output_format]}' was specified."
42
43
  end
43
44
  end
44
45
  end
@@ -4,33 +4,53 @@ require_relative '../puppet-check'
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)
8
- return if files.empty?
9
-
7
+ def self.manifest(files, style, pl_args)
10
8
  require 'puppet/face'
11
9
 
12
10
  # prepare the Puppet settings for the error checking
13
11
  Puppet.initialize_settings unless Puppet.settings.app_defaults_initialized?
14
- Puppet[:parser] = 'future' if future && (Puppet::PUPPETVERSION.to_i < 4)
15
12
 
16
13
  files.each do |file|
17
- # setup error logging and collection
14
+ # setup error logging and collection; warnings logged for all versions, but errors for only puppet < 6.5
18
15
  errors = []
19
16
  Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(errors))
20
17
 
21
18
  # check puppet syntax
22
19
  begin
23
- 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
24
28
  # this is the actual error that we need to rescue Puppet::Face from
25
29
  rescue SystemExit
26
- # puppet 5 can only do one error per line and outputs fake dir env info
27
- next PuppetCheck.settings[:error_files].push("#{file}:\n#{errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '').gsub(/Could not parse.*: /, '')}") if Puppet::PUPPETVERSION.to_i == 5
28
- # puppet < 5 parser output style
29
- 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
+ if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('5.4') && Gem::Version.new(Puppet::PUPPETVERSION) < Gem::Version.new('6.5')
32
+ message = 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
+ message = errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '').gsub(/Could not parse.*: /, '')
36
+ end
37
+ # puppet < 5 and 5.3 parser output style
38
+ message = errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '')
30
39
  end
40
+ # output message
41
+ next PuppetCheck.settings[:error_files].push("#{file}:\n#{message}") unless message.empty?
31
42
 
32
43
  # initialize warnings with output from the parser if it exists, since the output is warnings if Puppet::Face did not trigger a SystemExit
33
- warnings = errors.empty? ? "#{file}:" : "#{file}:\n#{errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '')}"
44
+ warnings = "#{file}:"
45
+ unless errors.empty?
46
+ # puppet 5.4-5.x has a new validator output format
47
+ warnings << if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('5.4')
48
+ "\n#{errors.map(&:to_s).join("\n").gsub("file: #{File.absolute_path(file)}, ", '')}"
49
+ # puppet <= 5.3 validator output format
50
+ else
51
+ "\n#{errors.map(&:to_s).join("\n").gsub("#{File.absolute_path(file)}:", '')}"
52
+ end
53
+ end
34
54
  Puppet::Util::Log.close_all
35
55
 
36
56
  # check puppet style
@@ -62,14 +82,9 @@ class PuppetParser
62
82
 
63
83
  # checks puppet template (.epp)
64
84
  def self.template(files)
65
- return if files.empty?
66
-
67
85
  require 'puppet/pops'
68
86
 
69
87
  files.each do |file|
70
- # puppet before version 4 cannot check template syntax
71
- next PuppetCheck.settings[:ignored_files].push("#{file}: ignored due to Puppet < 4") if Puppet::PUPPETVERSION.to_i < 4
72
-
73
88
  # check puppet template syntax
74
89
  begin
75
90
  # credits to gds-operations/puppet-syntax for the parser function call
@@ -3,22 +3,22 @@ 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
10
10
  def self.run
11
11
  # ensure this method does not do anything inside module dependencies
12
12
  specdirs = Dir.glob('**/spec').reject { |dir| dir =~ /fixtures/ }
13
- return if specdirs.class.to_s == 'NilClass'
13
+ return if specdirs.empty?
14
14
 
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))
@@ -40,11 +40,21 @@ class RSpecPuppetSupport
40
40
  File.write('spec/fixtures/manifests/site.pp', '') unless File.file?('spec/fixtures/manifests/site.pp')
41
41
 
42
42
  # symlink the module into spec/fixtures/modules
43
- File.symlink("../../../#{module_name}", "spec/fixtures/modules/#{module_name}") unless File.exist?("spec/fixtures/modules/#{module_name}")
43
+ if File.exist?("spec/fixtures/modules/#{module_name}")
44
+ # check if target is a symlink
45
+ if File.symlink?("spec/fixtures/modules/#{module_name}")
46
+ # check if target is correct
47
+ warn "spec/fixtures/modules/#{module_name} is not a symlink to the correct source! Your tests may fail because of this!" unless File.readlink("spec/fixtures/modules/#{module_name}") == File.expand_path("../../../../#{module_name}")
48
+ else
49
+ warn "spec/fixtures/modules/#{module_name} is not a symlink! Your tests may fail because of this!"
50
+ end
51
+ else
52
+ File.symlink("../../../../#{module_name}", "spec/fixtures/modules/#{module_name}")
53
+ end
44
54
 
45
55
  # create spec_helper if missing
46
56
  return if File.file?('spec/spec_helper.rb')
47
- File.open('spec/spec_helper.rb', 'w') { |file| file.puts "require 'rspec-puppet'\n\nfixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))\n\nRSpec.configure do |c|\n c.module_path = File.join(fixture_path, 'modules')\n c.manifest_dir = File.join(fixture_path, 'manifests')\n c.manifest = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'manifests', 'site.pp')\n c.environmentpath = File.join(Dir.pwd, 'spec')\nend" }
57
+ File.open('spec/spec_helper.rb', 'w') { |file| file.puts "require 'rspec-puppet/spec_helper'\n" }
48
58
  end
49
59
 
50
60
  # setup the module dependencies for rspec-puppet testing
@@ -56,7 +66,7 @@ class RSpecPuppetSupport
56
66
  parsed = JSON.parse(File.read('metadata.json'))
57
67
 
58
68
  # grab dependencies if they exist
59
- return if parsed['dependencies'].empty?
69
+ return unless parsed.key?('dependencies')
60
70
  parsed['dependencies'].each do |dependency_hash|
61
71
  # determine how the user wants to download the module dependency
62
72
  if dependency_hash.key?('git')
@@ -71,6 +81,7 @@ class RSpecPuppetSupport
71
81
  warn "#{dependency_hash['name']} has an unspecified, or specified but unsupported, download method."
72
82
  end
73
83
  end
84
+ Process.waitall
74
85
  end
75
86
 
76
87
  # download external module dependency with git
@@ -79,7 +90,11 @@ class RSpecPuppetSupport
79
90
  # establish path to clone module to
80
91
  path = "spec/fixtures/modules/#{File.basename(git_url, '.git')}"
81
92
  # is the module present and already cloned with git? do a pull; otherwise, do a clone
82
- 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
83
98
  end
84
99
 
85
100
  # download external module dependency with forge
@@ -87,7 +102,7 @@ class RSpecPuppetSupport
87
102
  private_class_method :method
88
103
  # is the module present? do an upgrade; otherwise, do an install
89
104
  subcommand = File.directory?("spec/fixtures/modules/#{forge_name}") ? 'upgrade' : 'install'
90
- system("puppet module #{subcommand} --modulepath spec/fixtures/modules/ #{args} #{forge_name}")
105
+ spawn("puppet module #{subcommand} --modulepath spec/fixtures/modules/ #{args} #{forge_name}")
91
106
  end
92
107
 
93
108
  # download external module dependency with svn
@@ -96,7 +111,11 @@ class RSpecPuppetSupport
96
111
  # establish path to checkout module to
97
112
  path = "spec/fixtures/modules/#{File.basename(svn_url)}"
98
113
  # is the module present and already checked out with svn? do an update; otherwise, do a checkout
99
- 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
100
119
  end
101
120
 
102
121
  # download external module dependency with hg
@@ -105,6 +124,10 @@ class RSpecPuppetSupport
105
124
  # establish path to clone module to
106
125
  path = "spec/fixtures/modules/#{File.basename(hg_url)}"
107
126
  # is the module present and already cloned with hg? do a pull and update; otherwise do a clone
108
- 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
109
132
  end
110
133
  end
@@ -9,7 +9,7 @@ class RubyParser
9
9
  # check ruby syntax
10
10
  begin
11
11
  # prevents ruby code from actually executing
12
- catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}") }
12
+ catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}", file) }
13
13
  rescue ScriptError, StandardError => err
14
14
  PuppetCheck.settings[:error_files].push("#{file}:\n#{err}")
15
15
  else
@@ -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
@@ -37,8 +37,6 @@ class RubyParser
37
37
 
38
38
  # checks ruby template (.erb)
39
39
  def self.template(files)
40
- return if files.empty?
41
-
42
40
  require 'erb'
43
41
 
44
42
  files.each do |file|
@@ -66,22 +64,22 @@ class RubyParser
66
64
  require 'rubocop'
67
65
  # cop named differently depending upon version
68
66
  filename_cop = RuboCop::Version::STRING.to_f >= 0.5 ? 'Naming/FileName' : 'Style/FileName'
67
+ # 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])
69
69
  end
70
70
 
71
71
  files.each do |file|
72
72
  # check librarian puppet syntax
73
73
  begin
74
74
  # prevents ruby code from actually executing
75
- catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}") }
75
+ catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}", file) }
76
76
  rescue SyntaxError, LoadError, ArgumentError => err
77
77
  PuppetCheck.settings[:error_files].push("#{file}:\n#{err}")
78
78
  # check librarian puppet style
79
79
  else
80
80
  if style
81
81
  # check Rubocop
82
- # RuboCop is grumpy about non-snake_case filenames so disable the FileName check
83
- 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])
84
- warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--format', 'emacs', file]) }
82
+ warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--require', 'rubocop-performance', '--format', 'emacs', file]) }
85
83
 
86
84
  # collect style warnings
87
85
  next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.split("#{File.absolute_path(file)}:").join('')}") unless warnings.empty?
@@ -14,10 +14,10 @@ class PuppetCheck::Tasks < ::Rake::TaskLib
14
14
  namespace :puppetcheck do
15
15
  desc 'Execute Puppet-Check file checks'
16
16
  task :file do
17
- PuppetCheck.new.run(Dir.glob('*'))
17
+ PuppetCheck.new.run(PuppetCheck.settings, Dir.glob('*'))
18
18
  end
19
19
 
20
- # rspec, rspec-puppet, and beaker tasks
20
+ # rspec and rspec-puppet tasks
21
21
  begin
22
22
  require 'rspec/core/rake_task'
23
23
  require_relative 'rspec_puppet_support'
@@ -30,22 +30,26 @@ class PuppetCheck::Tasks < ::Rake::TaskLib
30
30
  task.pattern = spec_dirs.empty? ? 'skip_rspec' : spec_dirs
31
31
  task.rspec_opts = '-f json' if PuppetCheck.settings[:output_format] == 'json'
32
32
  end
33
-
34
- desc 'Execute Beaker acceptance tests'
35
- RSpec::Core::RakeTask.new(:beaker) do |task|
36
- # generate tasks for all recognized directories and ensure acceptance tests inside module dependencies are ignored
37
- acceptance_dirs = Dir.glob('**/acceptance').reject { |dir| dir =~ /fixtures/ }
38
- task.pattern = acceptance_dirs.empty? ? 'skip_beaker' : acceptance_dirs
39
- task.rspec_opts = '-f json' if PuppetCheck.settings[:output_format] == 'json'
40
- end
41
33
  rescue LoadError
42
34
  desc 'RSpec is not installed.'
43
35
  task :spec do
44
- puts 'RSpec is not installed. The RSpec/RSpecPuppet tasks will not be available.'
36
+ puts 'RSpec is not installed. The RSpec/RSpec-Puppet tasks will not be available.'
45
37
  end
46
- desc 'RSpec is not installed.'
38
+ end
39
+
40
+ # beaker tasks
41
+ begin
42
+ require 'beaker/tasks/quick_start'
43
+
44
+ desc 'Execute Beaker acceptance tests'
45
+ task :beaker, %i[hypervisor] do |_, args|
46
+ args[:hypervisor] = 'vagrant' if args[:hypervisor].nil?
47
+ Rake::Task["beaker_quickstart:run_test[#{args[:hypervisor]}]"].invoke
48
+ end
49
+ rescue LoadError
50
+ desc 'Beaker is not installed.'
47
51
  task :beaker do
48
- puts 'RSpec is not installed. The Beaker tasks will not be available.'
52
+ puts 'Beaker is not installed. The Beaker tasks will not be available.'
49
53
  end
50
54
  end
51
55