puppet-lint 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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