puppet-lint 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +74 -0
- data/.rubocop_todo.yml +89 -0
- data/.travis.yml +11 -9
- data/CHANGELOG.md +54 -0
- data/Gemfile +3 -0
- data/Rakefile +14 -3
- data/appveyor.yml +1 -4
- data/bin/puppet-lint +1 -1
- data/lib/puppet-lint.rb +25 -21
- data/lib/puppet-lint/bin.rb +15 -19
- data/lib/puppet-lint/checkplugin.rb +24 -17
- data/lib/puppet-lint/checks.rb +42 -31
- data/lib/puppet-lint/configuration.rb +11 -8
- data/lib/puppet-lint/data.rb +236 -164
- data/lib/puppet-lint/lexer.rb +225 -203
- data/lib/puppet-lint/lexer/token.rb +34 -18
- data/lib/puppet-lint/optparser.rb +33 -30
- data/lib/puppet-lint/plugins.rb +42 -38
- data/lib/puppet-lint/plugins/check_classes/arrow_on_right_operand_line.rb +26 -28
- data/lib/puppet-lint/plugins/check_classes/autoloader_layout.rb +21 -20
- data/lib/puppet-lint/plugins/check_classes/class_inherits_from_params_class.rb +8 -9
- data/lib/puppet-lint/plugins/check_classes/code_on_top_scope.rb +9 -8
- data/lib/puppet-lint/plugins/check_classes/inherits_across_namespaces.rb +12 -11
- data/lib/puppet-lint/plugins/check_classes/names_containing_dash.rb +13 -12
- data/lib/puppet-lint/plugins/check_classes/names_containing_uppercase.rb +14 -13
- data/lib/puppet-lint/plugins/check_classes/nested_classes_or_defines.rb +9 -10
- data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +40 -31
- data/lib/puppet-lint/plugins/check_classes/right_to_left_relationship.rb +3 -2
- data/lib/puppet-lint/plugins/check_classes/variable_scope.rb +21 -24
- data/lib/puppet-lint/plugins/check_comments/slash_comments.rb +3 -2
- data/lib/puppet-lint/plugins/check_comments/star_comments.rb +6 -5
- data/lib/puppet-lint/plugins/check_conditionals/case_without_default.rb +21 -20
- data/lib/puppet-lint/plugins/check_conditionals/selector_inside_resource.rb +10 -13
- data/lib/puppet-lint/plugins/check_documentation/documentation.rb +26 -17
- data/lib/puppet-lint/plugins/check_nodes/unquoted_node_name.rb +11 -11
- data/lib/puppet-lint/plugins/check_resources/duplicate_params.rb +4 -3
- data/lib/puppet-lint/plugins/check_resources/ensure_first_param.rb +17 -18
- data/lib/puppet-lint/plugins/check_resources/ensure_not_symlink_target.rb +17 -16
- data/lib/puppet-lint/plugins/check_resources/file_mode.rb +22 -23
- data/lib/puppet-lint/plugins/check_resources/unquoted_file_mode.rb +14 -13
- data/lib/puppet-lint/plugins/check_resources/unquoted_resource_title.rb +9 -8
- data/lib/puppet-lint/plugins/check_strings/double_quoted_strings.rb +8 -8
- data/lib/puppet-lint/plugins/check_strings/only_variable_string.rb +29 -42
- data/lib/puppet-lint/plugins/check_strings/puppet_url_without_modules.rb +5 -4
- data/lib/puppet-lint/plugins/check_strings/quoted_booleans.rb +3 -2
- data/lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb +4 -3
- data/lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb +3 -2
- data/lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb +9 -8
- data/lib/puppet-lint/plugins/check_variables/variable_is_lowercase.rb +9 -8
- data/lib/puppet-lint/plugins/check_whitespace/140chars.rb +9 -9
- data/lib/puppet-lint/plugins/check_whitespace/2sp_soft_tabs.rb +4 -3
- data/lib/puppet-lint/plugins/check_whitespace/80chars.rb +10 -10
- data/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb +23 -22
- data/lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb +3 -2
- data/lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb +3 -2
- data/lib/puppet-lint/tasks/puppet-lint.rb +3 -3
- data/lib/puppet-lint/version.rb +1 -1
- data/puppet-lint.gemspec +4 -4
- data/spec/puppet-lint/bin_spec.rb +268 -140
- data/spec/puppet-lint/checks_spec.rb +229 -0
- data/spec/puppet-lint/configuration_spec.rb +10 -9
- data/spec/puppet-lint/data_spec.rb +84 -0
- data/spec/puppet-lint/ignore_overrides_spec.rb +71 -40
- data/spec/puppet-lint/lexer/token_spec.rb +1 -1
- data/spec/puppet-lint/lexer_spec.rb +306 -73
- data/spec/puppet-lint/plugins/check_classes/arrow_on_right_operand_line_spec.rb +12 -6
- data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +10 -10
- data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +15 -11
- data/spec/puppet-lint/plugins/check_classes/code_on_top_scope_spec.rb +26 -21
- data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +3 -3
- data/spec/puppet-lint/plugins/check_classes/name_contains_uppercase_spec.rb +4 -5
- data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +13 -0
- data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +33 -25
- data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +80 -55
- data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +2 -2
- data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +165 -130
- data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +2 -2
- data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +53 -35
- data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +59 -49
- data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +18 -14
- data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +14 -10
- data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +7 -7
- data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +54 -44
- data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +114 -89
- data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +41 -30
- data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +46 -40
- data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +46 -40
- data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +95 -71
- data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +28 -24
- data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +11 -9
- data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +1 -2
- data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +18 -14
- data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +1 -1
- data/spec/puppet-lint/plugins/check_variables/variable_is_lowercase_spec.rb +1 -1
- data/spec/puppet-lint/plugins/check_whitespace/140chars_spec.rb +22 -15
- data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +8 -6
- data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +23 -29
- data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +588 -494
- data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +1 -1
- data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +27 -19
- data/spec/puppet-lint_spec.rb +2 -12
- data/spec/spec_helper.rb +35 -30
- metadata +6 -5
- data/lib/puppet-lint/monkeypatches.rb +0 -2
- data/lib/puppet-lint/monkeypatches/string_percent.rb +0 -52
- data/lib/puppet-lint/monkeypatches/string_prepend.rb +0 -13
@@ -5,13 +5,14 @@
|
|
5
5
|
PuppetLint.new_check(:single_quote_string_with_variables) do
|
6
6
|
def check
|
7
7
|
tokens.select { |r|
|
8
|
-
r.type == :SSTRING && r.value.include?('${') &&
|
8
|
+
r.type == :SSTRING && r.value.include?('${') && !r.prev_token.prev_token.value.match(%r{inline_(epp|template)})
|
9
9
|
}.each do |token|
|
10
|
-
notify
|
10
|
+
notify(
|
11
|
+
:error,
|
11
12
|
:message => 'single quoted string containing a variable found',
|
12
13
|
:line => token.line,
|
13
14
|
:column => token.column,
|
14
|
-
|
15
|
+
)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
@@ -8,12 +8,13 @@ PuppetLint.new_check(:variables_not_enclosed) do
|
|
8
8
|
tokens.select { |r|
|
9
9
|
r.type == :UNENC_VARIABLE
|
10
10
|
}.each do |token|
|
11
|
-
notify
|
11
|
+
notify(
|
12
|
+
:warning,
|
12
13
|
:message => 'variable not enclosed in {}',
|
13
14
|
:line => token.line,
|
14
15
|
:column => token.column,
|
15
16
|
:token => token,
|
16
|
-
|
17
|
+
)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
@@ -7,15 +7,16 @@ PuppetLint.new_check(:variable_contains_dash) do
|
|
7
7
|
|
8
8
|
def check
|
9
9
|
tokens.select { |r|
|
10
|
-
VARIABLE_DASH_TYPES.include?
|
10
|
+
VARIABLE_DASH_TYPES.include?(r.type)
|
11
11
|
}.each do |token|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
next unless token.value.gsub(%r{\[.+?\]}, '') =~ %r{-}
|
13
|
+
|
14
|
+
notify(
|
15
|
+
:warning,
|
16
|
+
:message => 'variable contains a dash',
|
17
|
+
:line => token.line,
|
18
|
+
:column => token.column,
|
19
|
+
)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -7,15 +7,16 @@ PuppetLint.new_check(:variable_is_lowercase) do
|
|
7
7
|
|
8
8
|
def check
|
9
9
|
tokens.select { |r|
|
10
|
-
VARIABLE_LOWERCASE_TYPES.include?
|
10
|
+
VARIABLE_LOWERCASE_TYPES.include?(r.type)
|
11
11
|
}.each do |token|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
next unless token.value.gsub(%r{\[.+?\]}, '') =~ %r{[A-Z]}
|
13
|
+
|
14
|
+
notify(
|
15
|
+
:warning,
|
16
|
+
:message => 'variable contains an uppercase letter',
|
17
|
+
:line => token.line,
|
18
|
+
:column => token.column,
|
19
|
+
)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -7,15 +7,15 @@
|
|
7
7
|
PuppetLint.new_check(:'140chars') do
|
8
8
|
def check
|
9
9
|
manifest_lines.each_with_index do |line, idx|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
next if line =~ %r{://} || line =~ %r{template\(}
|
11
|
+
next unless line.scan(%r{.}mu).size > 140
|
12
|
+
|
13
|
+
notify(
|
14
|
+
:warning,
|
15
|
+
:message => 'line has more than 140 characters',
|
16
|
+
:line => idx + 1,
|
17
|
+
:column => 140,
|
18
|
+
)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -7,13 +7,14 @@ PuppetLint.new_check(:'2sp_soft_tabs') do
|
|
7
7
|
tokens.select { |r|
|
8
8
|
r.type == :INDENT
|
9
9
|
}.reject { |r|
|
10
|
-
r.value.length
|
10
|
+
r.value.length.even?
|
11
11
|
}.each do |token|
|
12
|
-
notify
|
12
|
+
notify(
|
13
|
+
:error,
|
13
14
|
:message => 'two-space soft tabs not used',
|
14
15
|
:line => token.line,
|
15
16
|
:column => token.column,
|
16
|
-
|
17
|
+
)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -6,16 +6,16 @@
|
|
6
6
|
PuppetLint.new_check(:'80chars') do
|
7
7
|
def check
|
8
8
|
manifest_lines.each_with_index do |line, idx|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
next if line =~ %r{://} || line =~ %r{template\(}
|
10
|
+
next unless line.scan(%r{.}mu).size > 80
|
11
|
+
|
12
|
+
notify(
|
13
|
+
:warning,
|
14
|
+
:message => 'line has more than 80 characters',
|
15
|
+
:line => idx + 1,
|
16
|
+
:column => 80,
|
17
|
+
)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
PuppetLint.configuration.send(
|
21
|
+
PuppetLint.configuration.send('disable_80chars')
|
@@ -13,7 +13,7 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
13
13
|
param_column = [nil]
|
14
14
|
resource_tokens = res_idx[:tokens]
|
15
15
|
resource_tokens.reject! do |token|
|
16
|
-
COMMENT_TYPES.include?
|
16
|
+
COMMENT_TYPES.include?(token.type)
|
17
17
|
end
|
18
18
|
|
19
19
|
# If this is a single line resource, skip it
|
@@ -23,7 +23,7 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
23
23
|
next if last_arrow.nil?
|
24
24
|
next if resource_tokens[first_arrow].line == resource_tokens[last_arrow].line
|
25
25
|
|
26
|
-
resource_tokens.
|
26
|
+
resource_tokens.each do |token|
|
27
27
|
if token.type == :FARROW
|
28
28
|
(level_tokens[level_idx] ||= []) << token
|
29
29
|
param_token = token.prev_code_token
|
@@ -31,7 +31,7 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
31
31
|
if param_token.type == :DQPOST
|
32
32
|
param_length = 0
|
33
33
|
iter_token = param_token
|
34
|
-
while iter_token.type != :DQPRE
|
34
|
+
while iter_token.type != :DQPRE
|
35
35
|
param_length += iter_token.to_manifest.length
|
36
36
|
iter_token = iter_token.prev_token
|
37
37
|
end
|
@@ -41,11 +41,11 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
if param_column[level_idx].nil?
|
44
|
-
if param_token.type == :DQPOST
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
param_column[level_idx] = if param_token.type == :DQPOST
|
45
|
+
iter_token.column
|
46
|
+
else
|
47
|
+
param_token.column
|
48
|
+
end
|
49
49
|
end
|
50
50
|
|
51
51
|
this_arrow_column = param_column[level_idx] + param_length + 1
|
@@ -62,18 +62,19 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
62
62
|
elsif token.type == :RBRACE || token.type == :SEMIC
|
63
63
|
if (level_tokens[level_idx] ||= []).map(&:line).uniq.length > 1
|
64
64
|
level_tokens[level_idx].each do |arrow_tok|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
65
|
+
next if arrow_tok.column == arrow_column[level_idx] || level_tokens[level_idx].size == 1
|
66
|
+
|
67
|
+
arrows_on_line = level_tokens[level_idx].select { |t| t.line == arrow_tok.line }
|
68
|
+
notify(
|
69
|
+
:warning,
|
70
|
+
:message => "indentation of => is not properly aligned (expected in column #{arrow_column[level_idx]}, but found it in column #{arrow_tok.column})",
|
71
|
+
:line => arrow_tok.line,
|
72
|
+
:column => arrow_tok.column,
|
73
|
+
:token => arrow_tok,
|
74
|
+
:arrow_column => arrow_column[level_idx],
|
75
|
+
:newline => arrows_on_line.index(arrow_tok) != 0,
|
76
|
+
:newline_indent => param_column[level_idx] - 1,
|
77
|
+
)
|
77
78
|
end
|
78
79
|
end
|
79
80
|
arrow_column[level_idx] = 0
|
@@ -89,7 +90,7 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
89
90
|
if problem[:newline]
|
90
91
|
index = tokens.index(problem[:token].prev_code_token.prev_token)
|
91
92
|
|
92
|
-
#insert newline
|
93
|
+
# insert newline
|
93
94
|
tokens.insert(index, PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0))
|
94
95
|
|
95
96
|
# indent the parameter to the correct depth
|
@@ -99,7 +100,7 @@ PuppetLint.new_check(:arrow_alignment) do
|
|
99
100
|
|
100
101
|
end_param_idx = tokens.index(problem[:token].prev_code_token)
|
101
102
|
start_param_idx = tokens.index(problem[:token].prev_token_of([:INDENT, :NEWLINE])) + 1
|
102
|
-
param_length = tokens[start_param_idx..end_param_idx].map { |r| r.to_manifest.length }.
|
103
|
+
param_length = tokens[start_param_idx..end_param_idx].map { |r| r.to_manifest.length }.reduce(0) { |sum, x| sum + x }
|
103
104
|
new_ws_len = (problem[:arrow_column] - (problem[:newline_indent] + param_length + 1))
|
104
105
|
new_ws = ' ' * new_ws_len
|
105
106
|
|
@@ -9,12 +9,13 @@ PuppetLint.new_check(:hard_tabs) do
|
|
9
9
|
tokens.select { |r|
|
10
10
|
WHITESPACE_TYPES.include?(r.type) && r.value.include?("\t")
|
11
11
|
}.each do |token|
|
12
|
-
notify
|
12
|
+
notify(
|
13
|
+
:error,
|
13
14
|
:message => 'tab character found',
|
14
15
|
:line => token.line,
|
15
16
|
:column => token.column,
|
16
17
|
:token => token,
|
17
|
-
|
18
|
+
)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -9,12 +9,13 @@ PuppetLint.new_check(:trailing_whitespace) do
|
|
9
9
|
}.select { |token|
|
10
10
|
token.next_token.nil? || token.next_token.type == :NEWLINE
|
11
11
|
}.each do |token|
|
12
|
-
notify
|
12
|
+
notify(
|
13
|
+
:error,
|
13
14
|
:message => 'trailing whitespace found',
|
14
15
|
:line => token.line,
|
15
16
|
:column => token.column,
|
16
17
|
:token => token,
|
17
|
-
|
18
|
+
)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -13,7 +13,7 @@ class PuppetLint
|
|
13
13
|
class RakeTask < ::Rake::TaskLib
|
14
14
|
include ::Rake::DSL if defined?(::Rake::DSL)
|
15
15
|
|
16
|
-
DEFAULT_PATTERN = '**/*.pp'
|
16
|
+
DEFAULT_PATTERN = '**/*.pp'.freeze
|
17
17
|
|
18
18
|
attr_accessor :name
|
19
19
|
attr_accessor :pattern
|
@@ -59,7 +59,7 @@ class PuppetLint
|
|
59
59
|
PuppetLint.configuration.send("disable_#{check}")
|
60
60
|
end
|
61
61
|
|
62
|
-
%w
|
62
|
+
%w[with_filename fail_on_warnings error_level log_format with_context fix show_ignored relative].each do |config|
|
63
63
|
value = instance_variable_get("@#{config}")
|
64
64
|
PuppetLint.configuration.send("#{config}=".to_sym, value) unless value.nil?
|
65
65
|
end
|
@@ -83,7 +83,7 @@ class PuppetLint
|
|
83
83
|
linter.run
|
84
84
|
linter.print_problems
|
85
85
|
|
86
|
-
if PuppetLint.configuration.fix &&
|
86
|
+
if PuppetLint.configuration.fix && linter.problems.none? { |e| e[:check] == :syntax }
|
87
87
|
IO.write(puppet_file, linter.manifest)
|
88
88
|
end
|
89
89
|
end
|
data/lib/puppet-lint/version.rb
CHANGED
data/puppet-lint.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.push(File.expand_path('../lib', __FILE__))
|
2
2
|
require 'puppet-lint/version'
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'puppet-lint'
|
6
|
-
s.version = PuppetLint::VERSION
|
6
|
+
s.version = PuppetLint::VERSION.dup
|
7
7
|
s.homepage = 'https://github.com/rodjek/puppet-lint/'
|
8
8
|
s.summary = 'Ensure your Puppet manifests conform with the Puppetlabs style guide'
|
9
9
|
s.description = 'Checks your Puppet manifests against the Puppetlabs
|
@@ -11,8 +11,8 @@ Gem::Specification.new do |s|
|
|
11
11
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
13
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
-
s.require_paths = [
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
15
|
+
s.require_paths = ['lib']
|
16
16
|
|
17
17
|
s.authors = ['Tim Sharpe']
|
18
18
|
s.email = 'tim@sharpe.id.au'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rspec/mocks'
|
3
3
|
require 'optparse'
|
4
|
+
require 'tempfile'
|
4
5
|
|
5
6
|
class CommandRun
|
6
7
|
attr_accessor :stdout, :stderr, :exitstatus
|
@@ -26,11 +27,11 @@ end
|
|
26
27
|
|
27
28
|
describe PuppetLint::Bin do
|
28
29
|
subject do
|
29
|
-
if args.is_a?
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
sane_args = if args.is_a?(Array)
|
31
|
+
args
|
32
|
+
else
|
33
|
+
[args]
|
34
|
+
end
|
34
35
|
|
35
36
|
CommandRun.new(sane_args)
|
36
37
|
end
|
@@ -55,209 +56,267 @@ describe PuppetLint::Bin do
|
|
55
56
|
end
|
56
57
|
|
57
58
|
context 'when passed multiple files' do
|
58
|
-
let(:args)
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
let(:args) do
|
60
|
+
[
|
61
|
+
'spec/fixtures/test/manifests/warning.pp',
|
62
|
+
'spec/fixtures/test/manifests/fail.pp',
|
63
|
+
]
|
64
|
+
end
|
62
65
|
|
63
66
|
its(:exitstatus) { is_expected.to eq(1) }
|
64
|
-
its(:stdout)
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
its(:stdout) do
|
68
|
+
is_expected.to eq(
|
69
|
+
[
|
70
|
+
"#{args[0]} - WARNING: optional parameter listed before required parameter on line 2",
|
71
|
+
"#{args[1]} - ERROR: test::foo not in autoload module layout on line 2",
|
72
|
+
].join("\n"),
|
73
|
+
)
|
74
|
+
end
|
68
75
|
end
|
69
76
|
|
70
77
|
context 'when passed a malformed file' do
|
71
78
|
let(:args) { 'spec/fixtures/test/manifests/malformed.pp' }
|
72
79
|
|
73
80
|
its(:exitstatus) { is_expected.to eq(1) }
|
74
|
-
its(:stdout) { is_expected.to eq('ERROR: Syntax error
|
81
|
+
its(:stdout) { is_expected.to eq('ERROR: Syntax error on line 1') }
|
82
|
+
its(:stderr) { is_expected.to eq('Try running `puppet parser validate <file>`') }
|
75
83
|
end
|
76
84
|
|
77
85
|
context 'when limited to errors only' do
|
78
|
-
let(:args)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
86
|
+
let(:args) do
|
87
|
+
[
|
88
|
+
'--error-level',
|
89
|
+
'error',
|
90
|
+
'spec/fixtures/test/manifests/warning.pp',
|
91
|
+
'spec/fixtures/test/manifests/fail.pp',
|
92
|
+
]
|
93
|
+
end
|
83
94
|
|
84
95
|
its(:exitstatus) { is_expected.to eq(1) }
|
85
|
-
its(:stdout) { is_expected.to match(
|
96
|
+
its(:stdout) { is_expected.to match(%r{^#{args.last} - ERROR}) }
|
86
97
|
end
|
87
98
|
|
88
99
|
context 'when limited to warnings only' do
|
89
|
-
let(:args)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
let(:args) do
|
101
|
+
[
|
102
|
+
'--error-level',
|
103
|
+
'warning',
|
104
|
+
'spec/fixtures/test/manifests/warning.pp',
|
105
|
+
'spec/fixtures/test/manifests/fail.pp',
|
106
|
+
]
|
107
|
+
end
|
94
108
|
|
95
109
|
its(:exitstatus) { is_expected.to eq(1) }
|
96
|
-
its(:stdout) { is_expected.to match(
|
97
|
-
its(:stdout) { is_expected.to_not match(
|
110
|
+
its(:stdout) { is_expected.to match(%r{WARNING}) }
|
111
|
+
its(:stdout) { is_expected.to_not match(%r{ERROR}) }
|
98
112
|
end
|
99
113
|
|
100
114
|
context 'when specifying a specific check to run' do
|
101
|
-
let(:args)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
115
|
+
let(:args) do
|
116
|
+
[
|
117
|
+
'--only-checks',
|
118
|
+
'parameter_order',
|
119
|
+
'spec/fixtures/test/manifests/warning.pp',
|
120
|
+
'spec/fixtures/test/manifests/fail.pp',
|
121
|
+
]
|
122
|
+
end
|
106
123
|
|
107
124
|
its(:exitstatus) { is_expected.to eq(0) }
|
108
|
-
its(:stdout) { is_expected.to_not match(
|
109
|
-
its(:stdout) { is_expected.to match(
|
125
|
+
its(:stdout) { is_expected.to_not match(%r{ERROR}) }
|
126
|
+
its(:stdout) { is_expected.to match(%r{WARNING}) }
|
110
127
|
end
|
111
128
|
|
112
129
|
context 'when asked to display filenames ' do
|
113
|
-
let(:args)
|
130
|
+
let(:args) do
|
131
|
+
[
|
132
|
+
'--with-filename',
|
133
|
+
'spec/fixtures/test/manifests/fail.pp',
|
134
|
+
]
|
135
|
+
end
|
114
136
|
|
115
137
|
its(:exitstatus) { is_expected.to eq(1) }
|
116
138
|
its(:stdout) { is_expected.to match(%r{^spec/fixtures/test/manifests/fail\.pp -}) }
|
117
139
|
end
|
118
140
|
|
119
141
|
context 'when not asked to fail on warnings' do
|
120
|
-
let(:args)
|
142
|
+
let(:args) do
|
143
|
+
[
|
144
|
+
'spec/fixtures/test/manifests/warning.pp',
|
145
|
+
]
|
146
|
+
end
|
121
147
|
|
122
148
|
its(:exitstatus) { is_expected.to eq(0) }
|
123
|
-
its(:stdout) { is_expected.to match(
|
149
|
+
its(:stdout) { is_expected.to match(%r{optional parameter}) }
|
124
150
|
end
|
125
151
|
|
126
152
|
context 'when asked to provide context to problems' do
|
127
|
-
let(:args)
|
128
|
-
|
129
|
-
|
130
|
-
|
153
|
+
let(:args) do
|
154
|
+
[
|
155
|
+
'--with-context',
|
156
|
+
'spec/fixtures/test/manifests/warning.pp',
|
157
|
+
]
|
158
|
+
end
|
131
159
|
|
132
160
|
its(:exitstatus) { is_expected.to eq(0) }
|
133
|
-
its(:stdout)
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
161
|
+
its(:stdout) do
|
162
|
+
is_expected.to eq(
|
163
|
+
[
|
164
|
+
'WARNING: optional parameter listed before required parameter on line 2',
|
165
|
+
'',
|
166
|
+
" define test::warning($foo='bar', $baz) { }",
|
167
|
+
' ^',
|
168
|
+
].join("\n"),
|
169
|
+
)
|
170
|
+
end
|
140
171
|
end
|
141
172
|
|
142
173
|
context 'when asked to fail on warnings' do
|
143
|
-
let(:args)
|
144
|
-
|
145
|
-
|
146
|
-
|
174
|
+
let(:args) do
|
175
|
+
[
|
176
|
+
'--fail-on-warnings',
|
177
|
+
'spec/fixtures/test/manifests/warning.pp',
|
178
|
+
]
|
179
|
+
end
|
147
180
|
|
148
181
|
its(:exitstatus) { is_expected.to eq(1) }
|
149
|
-
its(:stdout) { is_expected.to match(
|
182
|
+
its(:stdout) { is_expected.to match(%r{optional parameter}) }
|
150
183
|
end
|
151
184
|
|
152
185
|
context 'when used with an invalid option' do
|
153
186
|
let(:args) { '--foo-bar-baz' }
|
154
187
|
|
155
188
|
its(:exitstatus) { is_expected.to eq(1) }
|
156
|
-
its(:stdout) { is_expected.to match(
|
189
|
+
its(:stdout) { is_expected.to match(%r{invalid option}) }
|
157
190
|
end
|
158
191
|
|
159
192
|
context 'when passed a file that does not exist' do
|
160
193
|
let(:args) { 'spec/fixtures/test/manifests/enoent.pp' }
|
161
194
|
|
162
195
|
its(:exitstatus) { is_expected.to eq(1) }
|
163
|
-
its(:stdout) { is_expected.to match(
|
196
|
+
its(:stdout) { is_expected.to match(%r{specified file does not exist}) }
|
164
197
|
end
|
165
198
|
|
166
199
|
context 'when passed a directory' do
|
167
200
|
let(:args) { 'spec/fixtures/' }
|
168
201
|
|
169
202
|
its(:exitstatus) { is_expected.to eq(1) }
|
170
|
-
its(:stdout) { is_expected.to match(
|
203
|
+
its(:stdout) { is_expected.to match(%r{ERROR}) }
|
171
204
|
end
|
172
205
|
|
173
206
|
context 'when disabling a check' do
|
174
|
-
let(:args)
|
175
|
-
|
176
|
-
|
177
|
-
|
207
|
+
let(:args) do
|
208
|
+
[
|
209
|
+
'--no-autoloader_layout',
|
210
|
+
'spec/fixtures/test/manifests/fail.pp',
|
211
|
+
]
|
212
|
+
end
|
178
213
|
|
179
214
|
its(:exitstatus) { is_expected.to eq(0) }
|
180
|
-
its(:stdout) { is_expected.to eq(
|
215
|
+
its(:stdout) { is_expected.to eq('') }
|
181
216
|
end
|
182
217
|
|
183
218
|
context 'when changing the log format' do
|
184
219
|
context 'to print %{filename}' do
|
185
|
-
let(:args)
|
186
|
-
|
187
|
-
|
188
|
-
|
220
|
+
let(:args) do
|
221
|
+
[
|
222
|
+
'--log-format',
|
223
|
+
'%{filename}',
|
224
|
+
'spec/fixtures/test/manifests/fail.pp',
|
225
|
+
]
|
226
|
+
end
|
189
227
|
|
190
228
|
its(:exitstatus) { is_expected.to eq(1) }
|
191
229
|
its(:stdout) { is_expected.to eq('fail.pp') }
|
192
230
|
end
|
193
231
|
|
194
232
|
context 'to print %{path}' do
|
195
|
-
let(:args)
|
196
|
-
|
197
|
-
|
198
|
-
|
233
|
+
let(:args) do
|
234
|
+
[
|
235
|
+
'--log-format',
|
236
|
+
'%{path}',
|
237
|
+
'spec/fixtures/test/manifests/fail.pp',
|
238
|
+
]
|
239
|
+
end
|
199
240
|
|
200
241
|
its(:exitstatus) { is_expected.to eq(1) }
|
201
242
|
its(:stdout) { is_expected.to eq('spec/fixtures/test/manifests/fail.pp') }
|
202
243
|
end
|
203
244
|
|
204
245
|
context 'to print %{fullpath}' do
|
205
|
-
let(:args)
|
206
|
-
|
207
|
-
|
208
|
-
|
246
|
+
let(:args) do
|
247
|
+
[
|
248
|
+
'--log-format',
|
249
|
+
'%{fullpath}',
|
250
|
+
'spec/fixtures/test/manifests/fail.pp',
|
251
|
+
]
|
252
|
+
end
|
209
253
|
|
210
254
|
its(:exitstatus) { is_expected.to eq(1) }
|
211
|
-
its(:stdout)
|
255
|
+
its(:stdout) do
|
212
256
|
is_expected.to match(%r{^(/|[A-Za-z]\:).+/spec/fixtures/test/manifests/fail\.pp$})
|
213
|
-
|
257
|
+
end
|
214
258
|
end
|
215
259
|
|
216
260
|
context 'to print %{line}' do
|
217
|
-
let(:args)
|
218
|
-
|
219
|
-
|
220
|
-
|
261
|
+
let(:args) do
|
262
|
+
[
|
263
|
+
'--log-format',
|
264
|
+
'%{line}',
|
265
|
+
'spec/fixtures/test/manifests/fail.pp',
|
266
|
+
]
|
267
|
+
end
|
221
268
|
|
222
269
|
its(:exitstatus) { is_expected.to eq(1) }
|
223
270
|
its(:stdout) { is_expected.to eq('2') }
|
224
271
|
end
|
225
272
|
|
226
273
|
context 'to print %{kind}' do
|
227
|
-
let(:args)
|
228
|
-
|
229
|
-
|
230
|
-
|
274
|
+
let(:args) do
|
275
|
+
[
|
276
|
+
'--log-format',
|
277
|
+
'%{kind}',
|
278
|
+
'spec/fixtures/test/manifests/fail.pp',
|
279
|
+
]
|
280
|
+
end
|
231
281
|
|
232
282
|
its(:exitstatus) { is_expected.to eq(1) }
|
233
283
|
its(:stdout) { is_expected.to eq('error') }
|
234
284
|
end
|
235
285
|
|
236
286
|
context 'to print %{KIND}' do
|
237
|
-
let(:args)
|
238
|
-
|
239
|
-
|
240
|
-
|
287
|
+
let(:args) do
|
288
|
+
[
|
289
|
+
'--log-format',
|
290
|
+
'%{KIND}',
|
291
|
+
'spec/fixtures/test/manifests/fail.pp',
|
292
|
+
]
|
293
|
+
end
|
241
294
|
|
242
295
|
its(:exitstatus) { is_expected.to eq(1) }
|
243
296
|
its(:stdout) { is_expected.to eq('ERROR') }
|
244
297
|
end
|
245
298
|
|
246
299
|
context 'to print %{check}' do
|
247
|
-
let(:args)
|
248
|
-
|
249
|
-
|
250
|
-
|
300
|
+
let(:args) do
|
301
|
+
[
|
302
|
+
'--log-format',
|
303
|
+
'%{check}',
|
304
|
+
'spec/fixtures/test/manifests/fail.pp',
|
305
|
+
]
|
306
|
+
end
|
251
307
|
|
252
308
|
its(:exitstatus) { is_expected.to eq(1) }
|
253
309
|
its(:stdout) { is_expected.to eq('autoloader_layout') }
|
254
310
|
end
|
255
311
|
|
256
312
|
context 'to print %{message}' do
|
257
|
-
let(:args)
|
258
|
-
|
259
|
-
|
260
|
-
|
313
|
+
let(:args) do
|
314
|
+
[
|
315
|
+
'--log-format',
|
316
|
+
'%{message}',
|
317
|
+
'spec/fixtures/test/manifests/fail.pp',
|
318
|
+
]
|
319
|
+
end
|
261
320
|
|
262
321
|
its(:exitstatus) { is_expected.to eq(1) }
|
263
322
|
its(:stdout) { is_expected.to eq('test::foo not in autoload module layout') }
|
@@ -265,100 +324,169 @@ describe PuppetLint::Bin do
|
|
265
324
|
end
|
266
325
|
|
267
326
|
context 'when displaying results as json' do
|
268
|
-
let(:args)
|
269
|
-
|
270
|
-
|
271
|
-
|
327
|
+
let(:args) do
|
328
|
+
[
|
329
|
+
'--json',
|
330
|
+
'spec/fixtures/test/manifests/warning.pp',
|
331
|
+
]
|
332
|
+
end
|
333
|
+
|
272
334
|
its(:exitstatus) { is_expected.to eq(0) }
|
273
335
|
its(:stdout) do
|
274
336
|
if respond_to?(:include_json)
|
275
|
-
is_expected.to include_json([[{'KIND' => 'WARNING'}]])
|
337
|
+
is_expected.to include_json([[{ 'KIND' => 'WARNING' }]])
|
276
338
|
else
|
277
|
-
is_expected.to match(
|
339
|
+
is_expected.to match(%r{\[\n \{})
|
278
340
|
end
|
279
341
|
end
|
280
342
|
end
|
281
343
|
|
282
344
|
context 'when displaying results for multiple targets as json' do
|
345
|
+
let(:args) do
|
346
|
+
[
|
347
|
+
'--json',
|
348
|
+
'spec/fixtures/test/manifests/fail.pp',
|
349
|
+
'spec/fixtures/test/manifests/warning.pp',
|
350
|
+
]
|
351
|
+
end
|
283
352
|
|
284
|
-
let(:args) { [
|
285
|
-
'--json',
|
286
|
-
'spec/fixtures/test/manifests/fail.pp',
|
287
|
-
'spec/fixtures/test/manifests/warning.pp',
|
288
|
-
] }
|
289
353
|
its(:exitstatus) { is_expected.to eq(1) }
|
290
354
|
its(:stdout) do
|
291
355
|
if respond_to?(:include_json)
|
292
|
-
is_expected.to include_json([[{'KIND' => 'ERROR'}],[{'KIND' => 'WARNING'}]])
|
356
|
+
is_expected.to include_json([[{ 'KIND' => 'ERROR' }], [{ 'KIND' => 'WARNING' }]])
|
293
357
|
else
|
294
|
-
is_expected.to match(
|
358
|
+
is_expected.to match(%r{\[\n \{})
|
295
359
|
end
|
296
360
|
end
|
297
361
|
end
|
298
362
|
|
299
363
|
context 'when hiding ignored problems' do
|
300
|
-
let(:args)
|
301
|
-
|
302
|
-
|
364
|
+
let(:args) do
|
365
|
+
[
|
366
|
+
'spec/fixtures/test/manifests/ignore.pp',
|
367
|
+
]
|
368
|
+
end
|
303
369
|
|
304
370
|
its(:exitstatus) { is_expected.to eq(0) }
|
305
|
-
its(:stdout) { is_expected.to_not match(
|
371
|
+
its(:stdout) { is_expected.to_not match(%r{IGNORED}) }
|
306
372
|
end
|
307
373
|
|
308
374
|
context 'when showing ignored problems' do
|
309
|
-
let(:args)
|
310
|
-
|
311
|
-
|
312
|
-
|
375
|
+
let(:args) do
|
376
|
+
[
|
377
|
+
'--show-ignored',
|
378
|
+
'spec/fixtures/test/manifests/ignore.pp',
|
379
|
+
]
|
380
|
+
end
|
313
381
|
|
314
382
|
its(:exitstatus) { is_expected.to eq(0) }
|
315
|
-
its(:stdout) { is_expected.to match(
|
383
|
+
its(:stdout) { is_expected.to match(%r{IGNORED}) }
|
316
384
|
end
|
317
385
|
|
318
386
|
context 'when showing ignored problems with a reason' do
|
319
|
-
let(:args)
|
320
|
-
|
321
|
-
|
322
|
-
|
387
|
+
let(:args) do
|
388
|
+
[
|
389
|
+
'--show-ignored',
|
390
|
+
'spec/fixtures/test/manifests/ignore_reason.pp',
|
391
|
+
]
|
392
|
+
end
|
323
393
|
|
324
394
|
its(:exitstatus) { is_expected.to eq(0) }
|
325
|
-
its(:stdout)
|
326
|
-
|
327
|
-
|
328
|
-
|
395
|
+
its(:stdout) do
|
396
|
+
is_expected.to eq(
|
397
|
+
[
|
398
|
+
'IGNORED: double quoted string containing no variables on line 3',
|
399
|
+
' for a good reason',
|
400
|
+
].join("\n"),
|
401
|
+
)
|
402
|
+
end
|
329
403
|
end
|
330
404
|
|
331
405
|
context 'ignoring multiple checks on a line' do
|
332
|
-
let(:args)
|
333
|
-
|
334
|
-
|
406
|
+
let(:args) do
|
407
|
+
[
|
408
|
+
'spec/fixtures/test/manifests/ignore_multiple_line.pp',
|
409
|
+
]
|
410
|
+
end
|
335
411
|
|
336
412
|
its(:exitstatus) { is_expected.to eq(0) }
|
337
413
|
end
|
338
414
|
|
339
415
|
context 'ignoring multiple checks in a block' do
|
340
|
-
let(:args)
|
341
|
-
|
342
|
-
|
416
|
+
let(:args) do
|
417
|
+
[
|
418
|
+
'spec/fixtures/test/manifests/ignore_multiple_block.pp',
|
419
|
+
]
|
420
|
+
end
|
343
421
|
|
344
422
|
its(:exitstatus) { is_expected.to eq(0) }
|
345
|
-
its(:stdout) { is_expected.to match(
|
423
|
+
its(:stdout) { is_expected.to match(%r{^.*line 6$}) }
|
346
424
|
end
|
347
425
|
|
348
426
|
context 'when an lint:endignore control comment exists with no opening lint:ignore comment' do
|
349
|
-
let(:args)
|
350
|
-
|
351
|
-
|
427
|
+
let(:args) do
|
428
|
+
[
|
429
|
+
'spec/fixtures/test/manifests/mismatched_control_comment.pp',
|
430
|
+
]
|
431
|
+
end
|
352
432
|
|
353
433
|
its(:exitstatus) { is_expected.to eq(0) }
|
354
|
-
its(:stdout) { is_expected.to match(
|
434
|
+
its(:stdout) { is_expected.to match(%r{WARNING: lint:endignore comment with no opening lint:ignore:<check> comment found on line 1}) }
|
355
435
|
end
|
356
436
|
|
357
437
|
context 'when a lint:ignore control comment block is not terminated properly' do
|
358
|
-
let(:args)
|
359
|
-
|
360
|
-
|
438
|
+
let(:args) do
|
439
|
+
[
|
440
|
+
'spec/fixtures/test/manifests/unterminated_control_comment.pp',
|
441
|
+
]
|
442
|
+
end
|
443
|
+
|
444
|
+
its(:stdout) { is_expected.to match(%r{WARNING: lint:ignore:140chars comment on line 2 with no closing lint:endignore comment}) }
|
445
|
+
end
|
446
|
+
|
447
|
+
context 'when fixing a file with \n line endings' do
|
448
|
+
before(:context) do
|
449
|
+
@windows_file = Tempfile.new('windows')
|
450
|
+
@posix_file = Tempfile.new('posix')
|
361
451
|
|
362
|
-
|
452
|
+
@windows_file.binmode
|
453
|
+
@posix_file.binmode
|
454
|
+
|
455
|
+
@windows_file.write("\r\n")
|
456
|
+
@posix_file.write("\n")
|
457
|
+
|
458
|
+
@windows_file.close
|
459
|
+
@posix_file.close
|
460
|
+
end
|
461
|
+
|
462
|
+
after(:context) do
|
463
|
+
@windows_file.unlink
|
464
|
+
@posix_file.unlink
|
465
|
+
end
|
466
|
+
|
467
|
+
let(:args) do
|
468
|
+
[
|
469
|
+
'--fix',
|
470
|
+
@posix_file.path,
|
471
|
+
@windows_file.path,
|
472
|
+
]
|
473
|
+
end
|
474
|
+
|
475
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
476
|
+
|
477
|
+
it 'does not change the line endings' do
|
478
|
+
File.open(@posix_file.path, 'rb') do |f|
|
479
|
+
data = f.read
|
480
|
+
|
481
|
+
expect(data).to match(%r{\n\Z}m)
|
482
|
+
expect(data).to_not match(%r{\r\n\Z}m)
|
483
|
+
end
|
484
|
+
|
485
|
+
File.open(@windows_file.path, 'rb') do |f|
|
486
|
+
data = f.read
|
487
|
+
|
488
|
+
expect(data).to match(%r{\r\n\Z}m)
|
489
|
+
end
|
490
|
+
end
|
363
491
|
end
|
364
492
|
end
|