puppet-lint 2.5.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +522 -0
- data/lib/puppet-lint/bin.rb +71 -6
- data/lib/puppet-lint/checkplugin.rb +43 -9
- data/lib/puppet-lint/checks.rb +16 -16
- data/lib/puppet-lint/configuration.rb +134 -134
- data/lib/puppet-lint/data.rb +28 -28
- data/lib/puppet-lint/lexer/string_slurper.rb +138 -140
- data/lib/puppet-lint/lexer/token.rb +188 -190
- data/lib/puppet-lint/lexer.rb +416 -417
- data/lib/puppet-lint/monkeypatches.rb +1 -1
- data/lib/puppet-lint/optparser.rb +5 -1
- data/lib/puppet-lint/plugins/check_classes/arrow_on_right_operand_line.rb +6 -4
- data/lib/puppet-lint/plugins/check_classes/autoloader_layout.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/class_inherits_from_params_class.rb +6 -4
- data/lib/puppet-lint/plugins/check_classes/code_on_top_scope.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/inherits_across_namespaces.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/names_containing_dash.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/names_containing_uppercase.rb +7 -5
- data/lib/puppet-lint/plugins/check_classes/nested_classes_or_defines.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +7 -4
- data/lib/puppet-lint/plugins/check_classes/right_to_left_relationship.rb +5 -3
- data/lib/puppet-lint/plugins/check_classes/variable_scope.rb +15 -13
- data/lib/puppet-lint/plugins/check_comments/slash_comments.rb +9 -7
- data/lib/puppet-lint/plugins/check_comments/star_comments.rb +10 -8
- data/lib/puppet-lint/plugins/check_conditionals/case_without_default.rb +6 -4
- data/lib/puppet-lint/plugins/check_conditionals/selector_inside_resource.rb +5 -3
- data/lib/puppet-lint/plugins/check_documentation/documentation.rb +7 -3
- data/lib/puppet-lint/plugins/check_nodes/unquoted_node_name.rb +15 -11
- data/lib/puppet-lint/plugins/check_resources/duplicate_params.rb +5 -3
- data/lib/puppet-lint/plugins/check_resources/ensure_first_param.rb +8 -5
- data/lib/puppet-lint/plugins/check_resources/ensure_not_symlink_target.rb +11 -8
- data/lib/puppet-lint/plugins/check_resources/file_mode.rb +14 -9
- data/lib/puppet-lint/plugins/check_resources/unquoted_file_mode.rb +11 -6
- data/lib/puppet-lint/plugins/check_resources/unquoted_resource_title.rb +6 -4
- data/lib/puppet-lint/plugins/check_strings/double_quoted_strings.rb +12 -7
- data/lib/puppet-lint/plugins/check_strings/only_variable_string.rb +8 -6
- data/lib/puppet-lint/plugins/check_strings/puppet_url_without_modules.rb +14 -8
- data/lib/puppet-lint/plugins/check_strings/quoted_booleans.rb +11 -7
- data/lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb +11 -6
- data/lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb +12 -8
- data/lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb +11 -7
- data/lib/puppet-lint/plugins/check_variables/variable_is_lowercase.rb +11 -7
- data/lib/puppet-lint/plugins/check_whitespace/140chars.rb +3 -8
- data/lib/puppet-lint/plugins/check_whitespace/2sp_soft_tabs.rb +10 -8
- data/lib/puppet-lint/plugins/check_whitespace/80chars.rb +3 -8
- data/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb +10 -8
- data/lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb +11 -7
- data/lib/puppet-lint/plugins/check_whitespace/line_length.rb +29 -0
- data/lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb +13 -7
- data/lib/puppet-lint/plugins.rb +63 -61
- data/lib/puppet-lint/report/github.rb +17 -0
- data/lib/puppet-lint/report/sarif_template.json +63 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +84 -83
- data/lib/puppet-lint/tasks/release_test.rb +4 -1
- data/lib/puppet-lint/version.rb +1 -1
- data/lib/puppet-lint.rb +27 -12
- data/spec/acceptance/puppet_lint_spec.rb +46 -0
- data/spec/spec_helper.rb +92 -91
- data/spec/spec_helper_acceptance.rb +6 -0
- data/spec/spec_helper_acceptance_local.rb +38 -0
- data/spec/{puppet-lint → unit/puppet-lint}/bin_spec.rb +79 -35
- data/spec/{puppet-lint → unit/puppet-lint}/checks_spec.rb +36 -36
- data/spec/unit/puppet-lint/configuration_spec.rb +88 -0
- data/spec/{puppet-lint → unit/puppet-lint}/data_spec.rb +6 -3
- data/spec/{puppet-lint → unit/puppet-lint}/ignore_overrides_spec.rb +17 -17
- data/spec/{puppet-lint → unit/puppet-lint}/lexer/string_slurper_spec.rb +128 -128
- data/spec/{puppet-lint → unit/puppet-lint}/lexer/token_spec.rb +1 -1
- data/spec/{puppet-lint → unit/puppet-lint}/lexer_spec.rb +653 -671
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/arrow_on_right_operand_line_spec.rb +16 -16
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/autoloader_layout_spec.rb +13 -13
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/class_inherits_from_params_class_spec.rb +3 -3
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/code_on_top_scope_spec.rb +4 -4
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/inherits_across_namespaces_spec.rb +4 -4
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/name_contains_uppercase_spec.rb +10 -10
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/names_containing_dash_spec.rb +7 -7
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/nested_classes_or_defines_spec.rb +7 -7
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/parameter_order_spec.rb +9 -9
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/right_to_left_relationship_spec.rb +3 -3
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_classes/variable_scope_spec.rb +25 -25
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_comments/slash_comments_spec.rb +7 -7
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_comments/star_comments_spec.rb +13 -13
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_conditionals/case_without_default_spec.rb +10 -10
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_conditionals/selector_inside_resource_spec.rb +3 -3
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_documentation/documentation_spec.rb +8 -8
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_nodes/unquoted_node_name_spec.rb +24 -24
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/duplicate_params_spec.rb +9 -9
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/ensure_first_param_spec.rb +19 -19
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/ensure_not_symlink_target_spec.rb +10 -10
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/file_mode_spec.rb +40 -40
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/unquoted_file_mode_spec.rb +20 -20
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_resources/unquoted_resource_title_spec.rb +24 -24
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/double_quoted_strings_spec.rb +28 -27
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/only_variable_string_spec.rb +18 -18
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/puppet_url_without_modules_spec.rb +9 -9
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/quoted_booleans_spec.rb +22 -22
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/single_quote_string_with_variables_spec.rb +2 -2
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_strings/variables_not_enclosed_spec.rb +21 -21
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_variables/variable_contains_dash_spec.rb +6 -6
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_variables/variable_is_lowercase_spec.rb +7 -7
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/140chars_spec.rb +5 -5
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/2sp_soft_tabs_spec.rb +2 -2
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/80chars_spec.rb +6 -6
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/arrow_alignment_spec.rb +127 -127
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/hard_tabs_spec.rb +7 -7
- data/spec/{puppet-lint → unit/puppet-lint}/plugins/check_whitespace/trailing_whitespace_spec.rb +15 -15
- data/spec/unit/puppet-lint/puppet-lint_spec.rb +18 -0
- metadata +69 -120
- data/CHANGELOG.md +0 -1130
- data/spec/puppet-lint/configuration_spec.rb +0 -66
- data/spec/puppet-lint_spec.rb +0 -16
@@ -1,110 +1,111 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
|
1
3
|
require 'puppet-lint'
|
2
4
|
require 'puppet-lint/optparser'
|
3
5
|
require 'rake'
|
4
6
|
require 'rake/tasklib'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
# Public: A Rake task that can be loaded and used with everything you need.
|
9
|
+
#
|
10
|
+
# Examples
|
11
|
+
#
|
12
|
+
# require 'puppet-lint'
|
13
|
+
# PuppetLint::RakeTask.new
|
14
|
+
class PuppetLint::RakeTask < ::Rake::TaskLib
|
15
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
16
|
+
|
17
|
+
DEFAULT_PATTERN = '**/*.pp'.freeze
|
18
|
+
|
19
|
+
attr_accessor :name
|
20
|
+
attr_accessor :pattern
|
21
|
+
attr_accessor :ignore_paths
|
22
|
+
attr_accessor :with_filename
|
23
|
+
attr_accessor :disable_checks
|
24
|
+
attr_accessor :only_checks
|
25
|
+
attr_accessor :fail_on_warnings
|
26
|
+
attr_accessor :error_level
|
27
|
+
attr_accessor :log_format
|
28
|
+
attr_accessor :with_context
|
29
|
+
attr_accessor :fix
|
30
|
+
attr_accessor :show_ignored
|
31
|
+
attr_accessor :relative
|
32
|
+
|
33
|
+
# Public: Initialise a new PuppetLint::RakeTask.
|
34
|
+
#
|
35
|
+
# args - Not used.
|
8
36
|
#
|
9
|
-
#
|
37
|
+
# Example
|
10
38
|
#
|
11
|
-
# require 'puppet-lint'
|
12
39
|
# PuppetLint::RakeTask.new
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
attr_accessor :fail_on_warnings
|
25
|
-
attr_accessor :error_level
|
26
|
-
attr_accessor :log_format
|
27
|
-
attr_accessor :with_context
|
28
|
-
attr_accessor :fix
|
29
|
-
attr_accessor :show_ignored
|
30
|
-
attr_accessor :relative
|
31
|
-
|
32
|
-
# Public: Initialise a new PuppetLint::RakeTask.
|
33
|
-
#
|
34
|
-
# args - Not used.
|
35
|
-
#
|
36
|
-
# Example
|
37
|
-
#
|
38
|
-
# PuppetLint::RakeTask.new
|
39
|
-
def initialize(*args, &task_block)
|
40
|
-
@name = args.shift || :lint
|
41
|
-
@pattern = DEFAULT_PATTERN
|
42
|
-
@with_filename = true
|
43
|
-
@disable_checks = []
|
44
|
-
@only_checks = []
|
45
|
-
@ignore_paths = []
|
46
|
-
|
47
|
-
define(args, &task_block)
|
48
|
-
end
|
40
|
+
# rubocop:disable Lint/MissingSuper
|
41
|
+
def initialize(*args, &task_block)
|
42
|
+
@name = args.shift || :lint
|
43
|
+
@pattern = DEFAULT_PATTERN
|
44
|
+
@with_filename = true
|
45
|
+
@disable_checks = []
|
46
|
+
@only_checks = []
|
47
|
+
@ignore_paths = []
|
48
|
+
|
49
|
+
define(args, &task_block)
|
50
|
+
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
+
def define(args, &task_block)
|
53
|
+
desc 'Run puppet-lint'
|
52
54
|
|
53
|
-
|
55
|
+
yield(*[self, args].slice(0, task_block.arity)) if task_block
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
# clear any (auto-)pre-existing task
|
58
|
+
Rake::Task[@name].clear if Rake::Task.task_defined?(@name)
|
59
|
+
task @name do
|
60
|
+
PuppetLint::OptParser.build
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
62
|
+
if Array(@only_checks).any?
|
63
|
+
enable_checks = Array(@only_checks).map(&:to_sym)
|
64
|
+
PuppetLint.configuration.checks.each do |check|
|
65
|
+
if enable_checks.include?(check)
|
66
|
+
PuppetLint.configuration.send("enable_#{check}")
|
67
|
+
else
|
68
|
+
PuppetLint.configuration.send("disable_#{check}")
|
68
69
|
end
|
69
70
|
end
|
71
|
+
end
|
70
72
|
|
71
|
-
|
72
|
-
|
73
|
-
|
73
|
+
Array(@disable_checks).each do |check|
|
74
|
+
PuppetLint.configuration.send("disable_#{check}")
|
75
|
+
end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
['with_filename', 'fail_on_warnings', 'error_level', 'log_format', 'with_context', 'fix', 'show_ignored', 'relative'].each do |config|
|
78
|
+
value = instance_variable_get("@#{config}")
|
79
|
+
PuppetLint.configuration.send("#{config}=".to_sym, value) unless value.nil?
|
80
|
+
end
|
79
81
|
|
80
|
-
|
81
|
-
|
82
|
-
|
82
|
+
if PuppetLint.configuration.ignore_paths && @ignore_paths.empty?
|
83
|
+
@ignore_paths = PuppetLint.configuration.ignore_paths
|
84
|
+
end
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
-
|
86
|
+
if PuppetLint.configuration.pattern
|
87
|
+
@pattern = PuppetLint.configuration.pattern
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
90
|
+
RakeFileUtils.send(:verbose, true) do
|
91
|
+
linter = PuppetLint.new
|
92
|
+
matched_files = FileList[@pattern]
|
91
93
|
|
92
|
-
|
94
|
+
matched_files = matched_files.exclude(*@ignore_paths)
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
matched_files.to_a.each do |puppet_file|
|
97
|
+
next unless File.file?(puppet_file)
|
98
|
+
linter.file = puppet_file
|
99
|
+
linter.run
|
100
|
+
linter.print_problems
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
end
|
102
|
+
if PuppetLint.configuration.fix && linter.problems.none? { |e| e[:check] == :syntax }
|
103
|
+
IO.write(puppet_file, linter.manifest)
|
103
104
|
end
|
104
|
-
abort if linter.errors? || (
|
105
|
-
linter.warnings? && PuppetLint.configuration.fail_on_warnings
|
106
|
-
)
|
107
105
|
end
|
106
|
+
abort if linter.errors? || (
|
107
|
+
linter.warnings? && PuppetLint.configuration.fail_on_warnings
|
108
|
+
)
|
108
109
|
end
|
109
110
|
end
|
110
111
|
end
|
@@ -86,9 +86,12 @@ task :release_test do
|
|
86
86
|
'puppetlabs/puppetlabs-chocolatey',
|
87
87
|
'voxpupuli/puppet-archive',
|
88
88
|
'voxpupuli/puppet-collectd',
|
89
|
+
'voxpupuli/puppet-prometheus',
|
90
|
+
'voxpupuli/puppet-borg',
|
91
|
+
'voxpupuli/puppet-nginx',
|
92
|
+
'voxpupuli/puppet-jenkins',
|
89
93
|
'garethr/garethr-docker',
|
90
94
|
'sensu/sensu-puppet',
|
91
|
-
'jenkinsci/puppet-jenkins',
|
92
95
|
]
|
93
96
|
|
94
97
|
FileUtils.mkdir_p('tmp')
|
data/lib/puppet-lint/version.rb
CHANGED
data/lib/puppet-lint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
|
1
3
|
# encoding: utf-8
|
2
4
|
|
3
5
|
require 'set'
|
@@ -7,10 +9,12 @@ require 'puppet-lint/lexer'
|
|
7
9
|
require 'puppet-lint/configuration'
|
8
10
|
require 'puppet-lint/data'
|
9
11
|
require 'puppet-lint/checks'
|
12
|
+
require 'puppet-lint/report/github'
|
10
13
|
require 'puppet-lint/bin'
|
11
14
|
require 'puppet-lint/monkeypatches'
|
12
15
|
|
13
16
|
class PuppetLint::NoCodeError < StandardError; end
|
17
|
+
|
14
18
|
class PuppetLint::NoFix < StandardError; end
|
15
19
|
|
16
20
|
# Parser Syntax Errors
|
@@ -19,6 +23,7 @@ class PuppetLint::SyntaxError < StandardError
|
|
19
23
|
|
20
24
|
def initialize(token)
|
21
25
|
@token = token
|
26
|
+
super
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
@@ -58,7 +63,7 @@ class PuppetLint
|
|
58
63
|
# Public: Initialise a new PuppetLint object.
|
59
64
|
def initialize
|
60
65
|
@code = nil
|
61
|
-
@statistics = { :
|
66
|
+
@statistics = { error: 0, warning: 0, fixed: 0, ignored: 0 }
|
62
67
|
@manifest = ''
|
63
68
|
end
|
64
69
|
|
@@ -121,6 +126,16 @@ class PuppetLint
|
|
121
126
|
puts " #{message[:reason]}" if message[:kind] == :ignored && !message[:reason].nil?
|
122
127
|
end
|
123
128
|
|
129
|
+
# Internal: Format a problem message and print it to STDOUT so GitHub Actions
|
130
|
+
# recognizes it as an annotation.
|
131
|
+
#
|
132
|
+
# message - A Hash containing all the information about a problem.
|
133
|
+
#
|
134
|
+
# Returns nothing.
|
135
|
+
def print_github_annotation(message)
|
136
|
+
puts PuppetLint::Report::GitHubActionsReporter.format_problem(path, message)
|
137
|
+
end
|
138
|
+
|
124
139
|
# Internal: Get the line of the manifest on which the problem was found
|
125
140
|
#
|
126
141
|
# message - A Hash containing all the information about a problem.
|
@@ -150,7 +165,7 @@ class PuppetLint
|
|
150
165
|
# problems - An Array of problem Hashes as returned by
|
151
166
|
# PuppetLint::Checks#run.
|
152
167
|
#
|
153
|
-
# Returns
|
168
|
+
# Returns array of problem.
|
154
169
|
def report(problems)
|
155
170
|
json = []
|
156
171
|
problems.each do |message|
|
@@ -158,19 +173,19 @@ class PuppetLint
|
|
158
173
|
|
159
174
|
message[:KIND] = message[:kind].to_s.upcase
|
160
175
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
176
|
+
next unless message[:kind] == :fixed || [message[:kind], :all].include?(configuration.error_level)
|
177
|
+
|
178
|
+
if configuration.json || configuration.sarif
|
179
|
+
message['context'] = get_context(message) if configuration.with_context
|
180
|
+
json << message
|
181
|
+
else
|
182
|
+
format_message(message)
|
183
|
+
print_context(message) if configuration.with_context
|
184
|
+
print_github_annotation(message) if configuration.github_actions
|
169
185
|
end
|
170
186
|
end
|
171
|
-
puts JSON.pretty_generate(json) if configuration.json
|
172
|
-
|
173
187
|
$stderr.puts 'Try running `puppet parser validate <file>`' if problems.any? { |p| p[:check] == :syntax }
|
188
|
+
json
|
174
189
|
end
|
175
190
|
|
176
191
|
# Public: Determine if PuppetLint found any errors in the manifest.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper_acceptance'
|
4
|
+
|
5
|
+
describe 'When executing puppet-lint' do
|
6
|
+
let(:manifest_root) { File.join(File.dirname(__FILE__), '..', 'fixtures', 'test', 'manifests') }
|
7
|
+
|
8
|
+
context 'with no manifest provided' do
|
9
|
+
it 'returns an exit code of 1 with no arguments' do
|
10
|
+
result = puppet_lint
|
11
|
+
expect(result[:exit_code]).to eq(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns an exit code of 0 when given a single flag' do
|
15
|
+
result = puppet_lint(['--help'])
|
16
|
+
expect(result[:exit_code]).to eq(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns the correct version number with the --version flag' do
|
20
|
+
result = puppet_lint(['--version'])
|
21
|
+
expect(result[:stdout]).to match(PuppetLint::VERSION)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with a manifest provided' do
|
26
|
+
it 'returns one error when there is one problem' do
|
27
|
+
result = puppet_lint([File.join(manifest_root, 'fail.pp')])
|
28
|
+
expect(result[:stdout]).to have_errors(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns zero errors when there is an ignore comment present' do
|
32
|
+
result = puppet_lint([File.join(manifest_root, 'ignore.pp')])
|
33
|
+
expect(result[:stdout]).to have_errors(0)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns one warning when there is one problem' do
|
37
|
+
result = puppet_lint([File.join(manifest_root, 'warning.pp')])
|
38
|
+
expect(result[:stdout]).to have_warnings(1)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'contains two warnings when there are two problems' do
|
42
|
+
result = puppet_lint([File.join(manifest_root, 'two_warnings.pp')])
|
43
|
+
expect(result[:stdout]).to have_warnings(2)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# Disable GitHub Actions reporting since it breaks the test suite
|
2
|
+
ENV.delete('GITHUB_ACTION')
|
3
|
+
|
4
|
+
if ENV['COVERAGE'] == 'yes' && RUBY_VERSION.start_with?('2.7.')
|
2
5
|
require 'simplecov'
|
3
6
|
SimpleCov.start do
|
4
7
|
add_filter('/spec/')
|
@@ -16,115 +19,113 @@ rescue LoadError, SyntaxError
|
|
16
19
|
puts 'rspec/json_expectations is not available'
|
17
20
|
end
|
18
21
|
|
19
|
-
module RSpec
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
22
|
+
module RSpec::LintExampleGroup
|
23
|
+
class HaveProblem
|
24
|
+
def initialize(method, message)
|
25
|
+
@expected_problem = {
|
26
|
+
kind: method.to_s.gsub(%r{\Acontain_}, '').to_sym,
|
27
|
+
message: message,
|
28
|
+
}
|
29
|
+
@description = ["contain a #{@expected_problem[:kind]}"]
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def on_line(line)
|
33
|
+
@expected_problem[:line] = line
|
34
|
+
@description << "on line #{line}"
|
35
|
+
self
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def in_column(column)
|
39
|
+
@expected_problem[:column] = column
|
40
|
+
@description << "starting in column #{column}"
|
41
|
+
self
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
def with_reason(reason)
|
45
|
+
@expected_problem[:reason] = reason
|
46
|
+
@description << "with reason '#{reason}'"
|
47
|
+
self
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
+
def matches?(problems)
|
51
|
+
@problems = problems
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
53
|
+
problems.any? do |problem|
|
54
|
+
@expected_problem.all? do |key, value|
|
55
|
+
problem.key?(key) && problem[key] == value
|
55
56
|
end
|
56
57
|
end
|
58
|
+
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def check_attr(attr, prefix)
|
63
|
-
return if @expected_problem[attr] == @problems.first[attr]
|
60
|
+
def description
|
61
|
+
@description.join(' ')
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
"#{prefix} #{expected}, but it was #{actual}"
|
68
|
-
end
|
64
|
+
def check_attr(attr, prefix)
|
65
|
+
return if @expected_problem[attr] == @problems.first[attr]
|
69
66
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
when 1
|
75
|
-
messages = ['expected that the problem']
|
76
|
-
|
77
|
-
messages << check_attr(:kind, 'would be of kind')
|
78
|
-
messages << check_attr(:message, 'would have the message')
|
79
|
-
messages << check_attr(:line, 'would be on line')
|
80
|
-
messages << check_attr(:column, 'would start on column')
|
81
|
-
messages << check_attr(:reason, 'would have the reason')
|
82
|
-
|
83
|
-
messages.compact.join("\n ")
|
84
|
-
else
|
85
|
-
[
|
86
|
-
'expected that the check would create',
|
87
|
-
PP.pp(@expected_problem, '').strip,
|
88
|
-
'but it instead created',
|
89
|
-
PP.pp(@problems, ''),
|
90
|
-
].join("\n")
|
91
|
-
end
|
92
|
-
end
|
67
|
+
expected = @expected_problem[attr].inspect
|
68
|
+
actual = @problems.first[attr].inspect
|
69
|
+
"#{prefix} #{expected}, but it was #{actual}"
|
70
|
+
end
|
93
71
|
|
94
|
-
|
95
|
-
|
72
|
+
def failure_message
|
73
|
+
case @problems.length
|
74
|
+
when 0
|
75
|
+
'expected that the check would create a problem but it did not'
|
76
|
+
when 1
|
77
|
+
messages = ['expected that the problem']
|
78
|
+
|
79
|
+
messages << check_attr(:kind, 'would be of kind')
|
80
|
+
messages << check_attr(:message, 'would have the message')
|
81
|
+
messages << check_attr(:line, 'would be on line')
|
82
|
+
messages << check_attr(:column, 'would start on column')
|
83
|
+
messages << check_attr(:reason, 'would have the reason')
|
84
|
+
|
85
|
+
messages.compact.join("\n ")
|
86
|
+
else
|
87
|
+
[
|
88
|
+
'expected that the check would create',
|
89
|
+
PP.pp(@expected_problem, '').strip,
|
90
|
+
'but it instead created',
|
91
|
+
PP.pp(@problems, ''),
|
92
|
+
].join("\n")
|
96
93
|
end
|
97
94
|
end
|
98
95
|
|
99
|
-
def
|
100
|
-
|
101
|
-
super
|
96
|
+
def failure_message_when_negated
|
97
|
+
'expected that the check would not create the problem, but it did'
|
102
98
|
end
|
99
|
+
end
|
103
100
|
|
104
|
-
|
105
|
-
|
106
|
-
|
101
|
+
def method_missing(method, *args, &block)
|
102
|
+
return HaveProblem.new(method, args.first) if method.to_s.start_with?('contain_')
|
103
|
+
super
|
104
|
+
end
|
107
105
|
|
108
|
-
|
109
|
-
|
110
|
-
|
106
|
+
def respond_to_missing?(method, *)
|
107
|
+
method.to_s.start_with?('contain_') || super
|
108
|
+
end
|
111
109
|
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
def problems
|
111
|
+
subject.problems
|
112
|
+
end
|
115
113
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
klass.load_data(filepath, code)
|
120
|
-
check_name = self.class.top_level_description.to_sym
|
121
|
-
check = PuppetLint.configuration.check_object[check_name].new
|
122
|
-
klass.problems = check.run
|
114
|
+
def manifest
|
115
|
+
subject.manifest
|
116
|
+
end
|
123
117
|
|
124
|
-
|
118
|
+
def subject
|
119
|
+
klass = PuppetLint::Checks.new
|
120
|
+
filepath = respond_to?(:path) ? path : ''
|
121
|
+
klass.load_data(filepath, code)
|
122
|
+
check_name = self.class.top_level_description.to_sym
|
123
|
+
check = PuppetLint.configuration.check_object[check_name].new
|
124
|
+
klass.problems = check.run
|
125
125
|
|
126
|
-
|
127
|
-
|
126
|
+
klass.problems = check.fix_problems if PuppetLint.configuration.fix
|
127
|
+
|
128
|
+
klass
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
@@ -132,8 +133,8 @@ RSpec.configure do |config|
|
|
132
133
|
config.mock_framework = :rspec
|
133
134
|
config.include(
|
134
135
|
RSpec::LintExampleGroup,
|
135
|
-
:
|
136
|
-
:
|
136
|
+
type: :lint,
|
137
|
+
file_path: Regexp.compile(['spec', 'unit', 'puppet-lint', 'plugins'].join('[\\\/]')),
|
137
138
|
)
|
138
139
|
|
139
140
|
config.expect_with(:rspec) do |c|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shellwords'
|
4
|
+
require 'open3'
|
5
|
+
require 'rspec/expectations'
|
6
|
+
|
7
|
+
def puppet_lint(args = [])
|
8
|
+
raise "Parameter 'args' should an Array but it was of type #{args.class}." unless args.is_a?(Array) || args.empty?
|
9
|
+
|
10
|
+
bin_path = File.join(File.dirname(__FILE__), '..', 'bin', 'puppet-lint')
|
11
|
+
|
12
|
+
command = [bin_path]
|
13
|
+
command.concat(args) unless args.empty?
|
14
|
+
|
15
|
+
stdout, stderr, status = Open3.capture3(*command)
|
16
|
+
|
17
|
+
{
|
18
|
+
stdout: stdout.chomp,
|
19
|
+
stderr: stderr.chomp,
|
20
|
+
exit_code: status.exitstatus,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec::Matchers.define :have_errors do |expected|
|
25
|
+
match do |actual|
|
26
|
+
actual.split("\n").count { |line| line.include?('ERROR') } == expected
|
27
|
+
end
|
28
|
+
|
29
|
+
diffable
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec::Matchers.define :have_warnings do |expected|
|
33
|
+
match do |actual|
|
34
|
+
actual.split("\n").count { |line| line.include?('WARNING') } == expected
|
35
|
+
end
|
36
|
+
|
37
|
+
diffable
|
38
|
+
end
|