puppet-lint 2.2.1 → 2.3.0

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -19
  3. data/README.md +181 -174
  4. data/Rakefile +1 -1
  5. data/lib/puppet-lint/bin.rb +6 -0
  6. data/lib/puppet-lint/lexer.rb +1 -1
  7. data/lib/puppet-lint/plugins.rb +16 -10
  8. data/lib/puppet-lint/plugins/check_classes/arrow_on_right_operand_line.rb +46 -0
  9. data/lib/puppet-lint/plugins/check_classes/autoloader_layout.rb +33 -0
  10. data/lib/puppet-lint/plugins/check_classes/class_inherits_from_params_class.rb +20 -0
  11. data/lib/puppet-lint/plugins/check_classes/code_on_top_scope.rb +20 -0
  12. data/lib/puppet-lint/plugins/check_classes/inherits_across_namespaces.rb +22 -0
  13. data/lib/puppet-lint/plugins/check_classes/names_containing_dash.rb +23 -0
  14. data/lib/puppet-lint/plugins/check_classes/names_containing_uppercase.rb +28 -0
  15. data/lib/puppet-lint/plugins/check_classes/nested_classes_or_defines.rb +28 -0
  16. data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +44 -0
  17. data/lib/puppet-lint/plugins/check_classes/right_to_left_relationship.rb +15 -0
  18. data/lib/puppet-lint/plugins/check_classes/variable_scope.rb +143 -0
  19. data/lib/puppet-lint/plugins/check_comments/slash_comments.rb +22 -0
  20. data/lib/puppet-lint/plugins/{check_comments.rb → check_comments/star_comments.rb} +1 -24
  21. data/lib/puppet-lint/plugins/{check_conditionals.rb → check_conditionals/case_without_default.rb} +1 -27
  22. data/lib/puppet-lint/plugins/check_conditionals/selector_inside_resource.rb +25 -0
  23. data/lib/puppet-lint/plugins/{check_documentation.rb → check_documentation/documentation.rb} +0 -0
  24. data/lib/puppet-lint/plugins/{check_nodes.rb → check_nodes/unquoted_node_name.rb} +0 -0
  25. data/lib/puppet-lint/plugins/check_resources/duplicate_params.rb +37 -0
  26. data/lib/puppet-lint/plugins/check_resources/ensure_first_param.rb +70 -0
  27. data/lib/puppet-lint/plugins/check_resources/ensure_not_symlink_target.rb +44 -0
  28. data/lib/puppet-lint/plugins/check_resources/file_mode.rb +42 -0
  29. data/lib/puppet-lint/plugins/check_resources/unquoted_file_mode.rb +31 -0
  30. data/lib/puppet-lint/plugins/check_resources/unquoted_resource_title.rb +22 -0
  31. data/lib/puppet-lint/plugins/check_strings/double_quoted_strings.rb +27 -0
  32. data/lib/puppet-lint/plugins/check_strings/only_variable_string.rb +63 -0
  33. data/lib/puppet-lint/plugins/check_strings/puppet_url_without_modules.rb +25 -0
  34. data/lib/puppet-lint/plugins/check_strings/quoted_booleans.rb +26 -0
  35. data/lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb +17 -0
  36. data/lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb +23 -0
  37. data/lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb +21 -0
  38. data/lib/puppet-lint/plugins/{check_variables.rb → check_variables/variable_is_lowercase.rb} +0 -22
  39. data/lib/puppet-lint/plugins/check_whitespace/140chars.rb +21 -0
  40. data/lib/puppet-lint/plugins/check_whitespace/2sp_soft_tabs.rb +19 -0
  41. data/lib/puppet-lint/plugins/check_whitespace/80chars.rb +21 -0
  42. data/lib/puppet-lint/plugins/{check_whitespace.rb → check_whitespace/arrow_alignment.rb} +0 -118
  43. data/lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb +24 -0
  44. data/lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb +28 -0
  45. data/lib/puppet-lint/tasks/puppet-lint.rb +4 -0
  46. data/lib/puppet-lint/version.rb +1 -1
  47. data/spec/puppet-lint/bin_spec.rb +18 -1
  48. data/spec/puppet-lint/lexer_spec.rb +19 -0
  49. metadata +41 -68
  50. data/lib/puppet-lint/plugins/check_classes.rb +0 -433
  51. data/lib/puppet-lint/plugins/check_resources.rb +0 -251
  52. data/lib/puppet-lint/plugins/check_strings.rb +0 -186
@@ -1,251 +0,0 @@
1
- # Public: Check the manifest tokens for any resource titles / namevars that
2
- # are not quoted and record a warning for each instance found.
3
- #
4
- # https://docs.puppet.com/guides/style_guide.html#resource-names
5
- PuppetLint.new_check(:unquoted_resource_title) do
6
- def check
7
- title_tokens.each do |token|
8
- if token.type == :NAME
9
- notify :warning, {
10
- :message => 'unquoted resource title',
11
- :line => token.line,
12
- :column => token.column,
13
- :token => token,
14
- }
15
- end
16
- end
17
- end
18
-
19
- def fix(problem)
20
- problem[:token].type = :SSTRING
21
- end
22
- end
23
-
24
- # Public: Check the tokens of each resource instance for an ensure parameter
25
- # and if found, check that it is the first parameter listed. If it is not
26
- # the first parameter, record a warning.
27
- #
28
- # https://docs.puppet.com/guides/style_guide.html#attribute-ordering
29
- PuppetLint.new_check(:ensure_first_param) do
30
- def check
31
- resource_indexes.each do |resource|
32
- next if [:CLASS].include? resource[:type].type
33
- ensure_attr_index = resource[:param_tokens].index { |param_token|
34
- param_token.value == 'ensure'
35
- }
36
-
37
- unless ensure_attr_index.nil?
38
- if ensure_attr_index > 0
39
- ensure_token = resource[:param_tokens][ensure_attr_index]
40
- notify :warning, {
41
- :message => "ensure found on line but it's not the first attribute",
42
- :line => ensure_token.line,
43
- :column => ensure_token.column,
44
- :resource => resource,
45
- }
46
- end
47
- end
48
- end
49
- end
50
-
51
- def fix(problem)
52
- first_param_name_token = tokens[problem[:resource][:start]].next_token_of(:NAME)
53
- first_param_comma_token = first_param_name_token.next_token_of(:COMMA)
54
- ensure_param_name_token = first_param_comma_token.next_token_of(:NAME, :value => 'ensure')
55
- ensure_param_comma_token = ensure_param_name_token.next_token_of([:COMMA, :SEMIC])
56
-
57
- if first_param_name_token.nil? or first_param_comma_token.nil? or ensure_param_name_token.nil? or ensure_param_comma_token.nil?
58
- raise PuppetLint::NoFix
59
- end
60
-
61
- first_param_name_idx = tokens.index(first_param_name_token)
62
- first_param_comma_idx = tokens.index(first_param_comma_token)
63
- ensure_param_name_idx = tokens.index(ensure_param_name_token)
64
- ensure_param_comma_idx = tokens.index(ensure_param_comma_token)
65
-
66
- # Flip params
67
- prev_token = first_param_name_token.prev_token
68
- first_param_name_token.prev_token = ensure_param_name_token.prev_token
69
- ensure_param_name_token.prev_token = prev_token
70
-
71
- prev_code_token = first_param_name_token.prev_code_token
72
- first_param_name_token.prev_code_token = ensure_param_name_token.prev_code_token
73
- ensure_param_name_token.prev_code_token = prev_code_token
74
-
75
- next_token = first_param_comma_token.next_token
76
- first_param_comma_token = ensure_param_comma_token.next_token
77
- ensure_param_comma_token.next_token = next_token
78
-
79
- next_code_token = first_param_comma_token.next_code_token
80
- first_param_comma_code_token = ensure_param_comma_token.next_code_token
81
- ensure_param_comma_token.next_code_token = next_code_token
82
-
83
- # Update index
84
- ensure_tmp = tokens.slice!(ensure_param_name_idx..ensure_param_comma_idx-1)
85
- first_tmp = tokens.slice!(first_param_name_idx..first_param_comma_idx-1)
86
- ensure_tmp.reverse_each do |item|
87
- tokens.insert(first_param_name_idx, item)
88
- end
89
- first_tmp.reverse_each do |item|
90
- tokens.insert(ensure_param_name_idx + ensure_tmp.length - first_tmp.length, item)
91
- end
92
- end
93
- end
94
-
95
- # Public: Check the tokens of each resource instance for any duplicate
96
- # parameters and record a warning for each instance found.
97
- #
98
- # No style guide reference
99
- PuppetLint.new_check(:duplicate_params) do
100
- def check
101
- resource_indexes.each do |resource|
102
- seen_params = {}
103
- level = 0
104
-
105
- resource[:tokens].each_with_index do |token, idx|
106
- case token.type
107
- when :LBRACE
108
- level += 1
109
- next
110
- when :RBRACE
111
- seen_params.delete(level)
112
- level -= 1
113
- next
114
- when :FARROW
115
- prev_token = token.prev_code_token
116
- next unless prev_token.type == :NAME
117
-
118
- if (seen_params[level] ||= Set.new).include?(prev_token.value)
119
- notify :error, {
120
- :message => 'duplicate parameter found in resource',
121
- :line => prev_token.line,
122
- :column => prev_token.column,
123
- }
124
- else
125
- seen_params[level] << prev_token.value
126
- end
127
- end
128
- end
129
- end
130
- end
131
- end
132
-
133
- # Public: Check the tokens of each File resource instance for a mode
134
- # parameter and if found, record a warning if the value of that parameter is
135
- # not a quoted string.
136
- #
137
- # https://docs.puppet.com/guides/style_guide.html#file-modes
138
- PuppetLint.new_check(:unquoted_file_mode) do
139
- TOKEN_TYPES = Set[:NAME, :NUMBER]
140
-
141
- def check
142
- resource_indexes.each do |resource|
143
- if resource[:type].value == "file" or resource[:type].value == "concat"
144
- resource[:param_tokens].select { |param_token|
145
- param_token.value == 'mode' &&
146
- TOKEN_TYPES.include?(param_token.next_code_token.next_code_token.type)
147
- }.each do |param_token|
148
- value_token = param_token.next_code_token.next_code_token
149
- notify :warning, {
150
- :message => 'unquoted file mode',
151
- :line => value_token.line,
152
- :column => value_token.column,
153
- :token => value_token,
154
- }
155
- end
156
- end
157
- end
158
- end
159
-
160
- def fix(problem)
161
- problem[:token].type = :SSTRING
162
- end
163
- end
164
-
165
- # Public: Check the tokens of each File resource instance for a mode
166
- # parameter and if found, record a warning if the value of that parameter is
167
- # not a 4 digit octal value (0755) or a symbolic mode ('o=rwx,g+r').
168
- #
169
- # https://docs.puppet.com/guides/style_guide.html#file-modes
170
- PuppetLint.new_check(:file_mode) do
171
- MSG = 'mode should be represented as a 4 digit octal value or symbolic mode'
172
- SYM_RE = "([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*"
173
- IGNORE_TYPES = Set[:VARIABLE, :UNDEF, :FUNCTION_NAME]
174
- MODE_RE = Regexp.new(/\A([0-7]{4}|#{SYM_RE})\Z/)
175
-
176
- def check
177
- resource_indexes.each do |resource|
178
- if resource[:type].value == "file" or resource[:type].value == "concat"
179
- resource[:param_tokens].select { |param_token|
180
- param_token.value == 'mode'
181
- }.each do |param_token|
182
- value_token = param_token.next_code_token.next_code_token
183
-
184
- break if IGNORE_TYPES.include?(value_token.type)
185
- break if value_token.value =~ MODE_RE
186
-
187
- notify :warning, {
188
- :message => MSG,
189
- :line => value_token.line,
190
- :column => value_token.column,
191
- :token => value_token,
192
- }
193
- end
194
- end
195
- end
196
- end
197
-
198
- def fix(problem)
199
- if problem[:token].value =~ /\A[0-7]{3}\Z/
200
- problem[:token].type = :SSTRING
201
- problem[:token].value = "0#{problem[:token].value.to_s}"
202
- else
203
- raise PuppetLint::NoFix
204
- end
205
- end
206
- end
207
-
208
- # Public: Check the tokens of each File resource instance for an ensure
209
- # parameter and record a warning if the value of that parameter looks like
210
- # a symlink target (starts with a '/').
211
- #
212
- # https://docs.puppet.com/guides/style_guide.html#symbolic-links
213
- PuppetLint.new_check(:ensure_not_symlink_target) do
214
- def check
215
- resource_indexes.each do |resource|
216
- if resource[:type].value == "file"
217
- resource[:param_tokens].select { |param_token|
218
- param_token.value == 'ensure'
219
- }.each do |ensure_token|
220
- value_token = ensure_token.next_code_token.next_code_token
221
- if value_token.value.start_with? '/'
222
- notify :warning, {
223
- :message => 'symlink target specified in ensure attr',
224
- :line => value_token.line,
225
- :column => value_token.column,
226
- :param_token => ensure_token,
227
- :value_token => value_token,
228
- }
229
- end
230
- end
231
- end
232
- end
233
- end
234
-
235
- def fix(problem)
236
- index = tokens.index(problem[:value_token])
237
-
238
- [
239
- PuppetLint::Lexer::Token.new(:NAME, 'symlink', 0, 0),
240
- PuppetLint::Lexer::Token.new(:COMMA, ',', 0, 0),
241
- PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
242
- PuppetLint::Lexer::Token.new(:INDENT, problem[:param_token].prev_token.value.dup, 0, 0),
243
- PuppetLint::Lexer::Token.new(:NAME, 'target', 0, 0),
244
- PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
245
- PuppetLint::Lexer::Token.new(:FARROW, '=>', 0, 0),
246
- PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
247
- ].reverse.each do |new_token|
248
- tokens.insert(index, new_token)
249
- end
250
- end
251
- end
@@ -1,186 +0,0 @@
1
- # Public: Check the manifest tokens for any double quoted strings that don't
2
- # contain any variables or common escape characters and record a warning for
3
- # each instance found.
4
- #
5
- # https://docs.puppet.com/guides/style_guide.html#quoting
6
- PuppetLint.new_check(:double_quoted_strings) do
7
- def check
8
- tokens.select { |token|
9
- token.type == :STRING
10
- }.map { |token|
11
- [token, token.value.gsub(' '*token.column, "\n")]
12
- }.select { |token, sane_value|
13
- sane_value[/(\\\$|\\"|\\'|'|\r|\t|\\t|\n|\\n|\\\\)/].nil?
14
- }.each do |token, sane_value|
15
- notify :warning, {
16
- :message => 'double quoted string containing no variables',
17
- :line => token.line,
18
- :column => token.column,
19
- :token => token,
20
- }
21
- end
22
- end
23
-
24
- def fix(problem)
25
- problem[:token].type = :SSTRING
26
- end
27
- end
28
-
29
- # Public: Check the manifest tokens for double quoted strings that contain
30
- # a single variable only and record a warning for each instance found.
31
- #
32
- # https://docs.puppet.com/guides/style_guide.html#quoting
33
- PuppetLint.new_check(:only_variable_string) do
34
- VAR_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
35
-
36
- def check
37
- tokens.each_with_index do |start_token, start_token_idx|
38
- if start_token.type == :DQPRE and start_token.value == ''
39
- var_token = start_token.next_token
40
- if VAR_TYPES.include? var_token.type
41
- eos_offset = 2
42
- loop do
43
- eos_token = tokens[start_token_idx + eos_offset]
44
- case eos_token.type
45
- when :LBRACK
46
- eos_offset += 3
47
- when :DQPOST
48
- if eos_token.value == ''
49
- if eos_token.next_code_token && eos_token.next_code_token.type == :FARROW
50
- break
51
- end
52
- notify :warning, {
53
- :message => 'string containing only a variable',
54
- :line => var_token.line,
55
- :column => var_token.column,
56
- :start_token => start_token,
57
- :var_token => var_token,
58
- :end_token => eos_token,
59
- }
60
- end
61
- break
62
- else
63
- break
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
70
-
71
- def fix(problem)
72
- prev_token = problem[:start_token].prev_token
73
- prev_code_token = problem[:start_token].prev_code_token
74
- next_token = problem[:end_token].next_token
75
- next_code_token = problem[:end_token].next_code_token
76
- var_token = problem[:var_token]
77
-
78
- tokens.delete(problem[:start_token])
79
- tokens.delete(problem[:end_token])
80
-
81
- prev_token.next_token = var_token unless prev_token.nil?
82
- prev_code_token.next_code_token = var_token unless prev_code_token.nil?
83
- next_code_token.prev_code_token = var_token unless next_code_token.nil?
84
- next_token.prev_token = var_token unless next_token.nil?
85
- var_token.type = :VARIABLE
86
- var_token.next_token = next_token
87
- var_token.next_code_token = next_code_token
88
- var_token.prev_code_token = prev_code_token
89
- var_token.prev_token = prev_token
90
- end
91
- end
92
-
93
- # Public: Check the manifest tokens for any variables in a string that have
94
- # not been enclosed by braces ({}) and record a warning for each instance
95
- # found.
96
- #
97
- # https://docs.puppet.com/guides/style_guide.html#quoting
98
- PuppetLint.new_check(:variables_not_enclosed) do
99
- def check
100
- tokens.select { |r|
101
- r.type == :UNENC_VARIABLE
102
- }.each do |token|
103
- notify :warning, {
104
- :message => 'variable not enclosed in {}',
105
- :line => token.line,
106
- :column => token.column,
107
- :token => token,
108
- }
109
- end
110
- end
111
-
112
- def fix(problem)
113
- problem[:token].type = :VARIABLE
114
- end
115
- end
116
-
117
- # Public: Check the manifest tokens for any single quoted strings containing
118
- # a enclosed variable and record an error for each instance found.
119
- #
120
- # https://docs.puppet.com/guides/style_guide.html#quoting
121
- PuppetLint.new_check(:single_quote_string_with_variables) do
122
- def check
123
- tokens.select { |r|
124
- r.type == :SSTRING && r.value.include?('${') && (! r.prev_token.prev_token.value.match(%r{inline_(epp|template)}) )
125
- }.each do |token|
126
- notify :error, {
127
- :message => 'single quoted string containing a variable found',
128
- :line => token.line,
129
- :column => token.column,
130
- }
131
- end
132
- end
133
- end
134
-
135
- # Public: Check the manifest tokens for any double or single quoted strings
136
- # containing only a boolean value and record a warning for each instance
137
- # found.
138
- #
139
- # No style guide reference
140
- PuppetLint.new_check(:quoted_booleans) do
141
- STRING_TYPES = Set[:STRING, :SSTRING]
142
- BOOLEANS = Set['true', 'false']
143
-
144
- def check
145
- tokens.select { |r|
146
- STRING_TYPES.include?(r.type) && BOOLEANS.include?(r.value)
147
- }.each do |token|
148
- notify :warning, {
149
- :message => 'quoted boolean value found',
150
- :line => token.line,
151
- :column => token.column,
152
- :token => token,
153
- }
154
- end
155
- end
156
-
157
- def fix(problem)
158
- problem[:token].type = problem[:token].value.upcase.to_sym
159
- end
160
- end
161
-
162
- # Public: Check the manifest tokens for any puppet:// URL strings where the
163
- # path section doesn't start with modules/ and record a warning for each
164
- # instance found.
165
- #
166
- # No style guide reference
167
- PuppetLint.new_check(:puppet_url_without_modules) do
168
- def check
169
- tokens.select { |token|
170
- (token.type == :SSTRING || token.type == :STRING || token.type == :DQPRE) && token.value.start_with?('puppet://')
171
- }.reject { |token|
172
- token.value[/puppet:\/\/.*?\/(.+)/, 1].start_with?('modules/') unless token.value[/puppet:\/\/.*?\/(.+)/, 1].nil?
173
- }.each do |token|
174
- notify :warning, {
175
- :message => 'puppet:// URL without modules/ found',
176
- :line => token.line,
177
- :column => token.column,
178
- :token => token,
179
- }
180
- end
181
- end
182
-
183
- def fix(problem)
184
- problem[:token].value.gsub!(/(puppet:\/\/.*?\/)/, '\1modules/')
185
- end
186
- end