puppet-lint 0.4.0.pre1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/.travis.yml +3 -4
  2. data/Gemfile +2 -5
  3. data/README.md +2 -149
  4. data/Rakefile +0 -5
  5. data/lib/puppet-lint.rb +74 -20
  6. data/lib/puppet-lint/bin.rb +20 -85
  7. data/lib/puppet-lint/checkplugin.rb +158 -12
  8. data/lib/puppet-lint/checks.rb +39 -222
  9. data/lib/puppet-lint/configuration.rb +12 -31
  10. data/lib/puppet-lint/data.rb +329 -0
  11. data/lib/puppet-lint/lexer.rb +37 -30
  12. data/lib/puppet-lint/lexer/token.rb +14 -16
  13. data/lib/puppet-lint/monkeypatches/string_prepend.rb +6 -0
  14. data/lib/puppet-lint/optparser.rb +105 -0
  15. data/lib/puppet-lint/plugins.rb +28 -9
  16. data/lib/puppet-lint/plugins/check_classes.rb +162 -238
  17. data/lib/puppet-lint/plugins/check_comments.rb +40 -25
  18. data/lib/puppet-lint/plugins/check_conditionals.rb +16 -20
  19. data/lib/puppet-lint/plugins/check_documentation.rb +14 -20
  20. data/lib/puppet-lint/plugins/check_nodes.rb +23 -0
  21. data/lib/puppet-lint/plugins/check_resources.rb +127 -141
  22. data/lib/puppet-lint/plugins/check_strings.rb +133 -107
  23. data/lib/puppet-lint/plugins/check_variables.rb +11 -11
  24. data/lib/puppet-lint/plugins/check_whitespace.rb +86 -92
  25. data/lib/puppet-lint/tasks/puppet-lint.rb +17 -1
  26. data/lib/puppet-lint/version.rb +1 -1
  27. data/puppet-lint.gemspec +4 -2
  28. data/spec/fixtures/test/manifests/ignore.pp +1 -0
  29. data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
  30. data/spec/puppet-lint/bin_spec.rb +104 -84
  31. data/spec/puppet-lint/configuration_spec.rb +19 -19
  32. data/spec/puppet-lint/ignore_overrides_spec.rb +97 -0
  33. data/spec/puppet-lint/lexer/token_spec.rb +9 -9
  34. data/spec/puppet-lint/lexer_spec.rb +352 -325
  35. data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +77 -23
  36. data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +14 -12
  37. data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +18 -14
  38. data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +30 -30
  39. data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +31 -26
  40. data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +34 -28
  41. data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +14 -12
  42. data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +74 -30
  43. data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +27 -20
  44. data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +78 -13
  45. data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +17 -12
  46. data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +13 -10
  47. data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +21 -16
  48. data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +69 -0
  49. data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +42 -38
  50. data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +22 -10
  51. data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +81 -18
  52. data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +69 -112
  53. data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +27 -20
  54. data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +177 -171
  55. data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +165 -88
  56. data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +97 -22
  57. data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +25 -0
  58. data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +97 -111
  59. data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +10 -9
  60. data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +53 -53
  61. data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +26 -14
  62. data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +10 -9
  63. data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +31 -15
  64. data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +340 -322
  65. data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +30 -23
  66. data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +42 -41
  67. data/spec/puppet-lint_spec.rb +3 -3
  68. data/spec/spec_helper.rb +109 -116
  69. metadata +109 -50
  70. data/spec/puppet-lint/plugins/check_classes/class_parameter_defaults_spec.rb +0 -60
@@ -1,40 +1,55 @@
1
- class PuppetLint::Plugins::CheckComments < PuppetLint::CheckPlugin
2
- # Public: Check the manifest tokens for any comments started with slashes
3
- # (//) and record a warning for each instance found.
4
- #
5
- # Returns nothing.
6
- check 'slash_comments' do
1
+ # Public: Check the manifest tokens for any comments started with slashes
2
+ # (//) and record a warning for each instance found.
3
+ PuppetLint.new_check(:slash_comments) do
4
+ def check
7
5
  tokens.select { |token|
8
6
  token.type == :SLASH_COMMENT
9
7
  }.each do |token|
10
- if PuppetLint.configuration.fix
11
- token.type = :COMMENT
12
- notify_type = :fixed
13
- else
14
- notify_type = :warning
15
- end
16
-
17
- notify notify_type, {
18
- :message => '// comment found',
19
- :linenumber => token.line,
20
- :column => token.column,
8
+ notify :warning, {
9
+ :message => '// comment found',
10
+ :line => token.line,
11
+ :column => token.column,
12
+ :token => token,
21
13
  }
22
14
  end
23
15
  end
24
16
 
25
- # Public: Check the manifest tokens for any comments encapsulated with
26
- # slash-asterisks (/* */) and record a warning for each instance found.
27
- #
28
- # Returns nothing.
29
- check 'star_comments' do
17
+ def fix(problem)
18
+ problem[:token].type = :COMMENT
19
+ end
20
+ end
21
+
22
+ # Public: Check the manifest tokens for any comments encapsulated with
23
+ # slash-asterisks (/* */) and record a warning for each instance found.
24
+ PuppetLint.new_check(:star_comments) do
25
+ def check
30
26
  tokens.select { |token|
31
27
  token.type == :MLCOMMENT
32
28
  }.each do |token|
33
29
  notify :warning, {
34
- :message => '/* */ comment found',
35
- :linenumber => token.line,
36
- :column => token.column,
30
+ :message => '/* */ comment found',
31
+ :line => token.line,
32
+ :column => token.column,
33
+ :token => token,
37
34
  }
38
35
  end
39
36
  end
37
+
38
+ def fix(problem)
39
+ comment_lines = problem[:token].value.split("\n")
40
+ first_line = comment_lines.shift
41
+ problem[:token].type = :COMMENT
42
+ problem[:token].value = " #{first_line}"
43
+
44
+ index = tokens.index(problem[:token].next_token)
45
+ comment_lines.reverse.each do |line|
46
+ [
47
+ PuppetLint::Lexer::Token.new(:COMMENT, " #{line}", 0, 0),
48
+ PuppetLint::Lexer::Token.new(:INDENT, problem[:token].prev_token.value.dup, 0, 0),
49
+ PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
50
+ ].each do |new_token|
51
+ tokens.insert(index, new_token)
52
+ end
53
+ end
54
+ end
40
55
  end
@@ -1,21 +1,17 @@
1
- class PuppetLint::Plugins::CheckConditionals < PuppetLint::CheckPlugin
2
- # Public: Test the manifest tokens for any selectors embedded within resource
3
- # declarations and record a warning for each instance found.
4
- #
5
- # Returns nothing.
6
- check 'selector_inside_resource' do
1
+ # Public: Test the manifest tokens for any selectors embedded within resource
2
+ # declarations and record a warning for each instance found.
3
+ PuppetLint.new_check(:selector_inside_resource) do
4
+ def check
7
5
  resource_indexes.each do |resource|
8
- resource_tokens = tokens[resource[:start]..resource[:end]]
9
-
10
- resource_tokens.each do |token|
6
+ resource[:tokens].each do |token|
11
7
  if token.type == :FARROW
12
8
  if token.next_code_token.type == :VARIABLE
13
9
  unless token.next_code_token.next_code_token.nil?
14
10
  if token.next_code_token.next_code_token.type == :QMARK
15
11
  notify :warning, {
16
- :message => 'selector inside resource block',
17
- :linenumber => token.line,
18
- :column => token.column,
12
+ :message => 'selector inside resource block',
13
+ :line => token.line,
14
+ :column => token.column,
19
15
  }
20
16
  end
21
17
  end
@@ -24,12 +20,12 @@ class PuppetLint::Plugins::CheckConditionals < PuppetLint::CheckPlugin
24
20
  end
25
21
  end
26
22
  end
23
+ end
27
24
 
28
- # Public: Test the manifest tokens for any case statements that do not
29
- # contain a "default" case and record a warning for each instance found.
30
- #
31
- # Returns nothing.
32
- check 'case_without_default' do
25
+ # Public: Test the manifest tokens for any case statements that do not
26
+ # contain a "default" case and record a warning for each instance found.
27
+ PuppetLint.new_check(:case_without_default) do
28
+ def check
33
29
  case_indexes = []
34
30
 
35
31
  tokens.each_index do |token_idx|
@@ -55,9 +51,9 @@ class PuppetLint::Plugins::CheckConditionals < PuppetLint::CheckPlugin
55
51
 
56
52
  unless case_tokens.index { |r| r.type == :DEFAULT }
57
53
  notify :warning, {
58
- :message => 'case statement without a default case',
59
- :linenumber => case_tokens.first.line,
60
- :column => case_tokens.first.column,
54
+ :message => 'case statement without a default case',
55
+ :line => case_tokens.first.line,
56
+ :column => case_tokens.first.column,
61
57
  }
62
58
  end
63
59
  end
@@ -1,25 +1,19 @@
1
- class PuppetLint::Plugins::CheckDocumentation < PuppetLint::CheckPlugin
2
- check 'documentation' do
3
- comment_tokens = {
4
- :COMMENT => true,
5
- :MLCOMMENT => true,
6
- :SLASH_COMMENT => true,
7
- }
8
-
9
- whitespace_tokens = {
10
- :WHITESPACE => true,
11
- :NEWLINE => true,
12
- :INDENT => true,
13
- }
1
+ # Public: Check the manifest tokens for any class or defined type that does not
2
+ # have a comment directly above it (hopefully, explaining the usage of it) and
3
+ # record a warning for each instance found.
4
+ PuppetLint.new_check(:documentation) do
5
+ COMMENT_TOKENS = Set[:COMMENT, :MLCOMMENT, :SLASH_COMMENT]
6
+ WHITESPACE_TOKENS = Set[:WHITESPACE, :NEWLINE, :INDENT]
14
7
 
8
+ def check
15
9
  (class_indexes + defined_type_indexes).each do |item_idx|
16
- prev_token = tokens[item_idx[:start] - 1]
17
- while (!prev_token.nil?) && whitespace_tokens.include?(prev_token.type)
10
+ prev_token = item_idx[:tokens].first.prev_token
11
+ while (!prev_token.nil?) && WHITESPACE_TOKENS.include?(prev_token.type)
18
12
  prev_token = prev_token.prev_token
19
13
  end
20
14
 
21
- unless (!prev_token.nil?) && comment_tokens.include?(prev_token.type)
22
- first_token = tokens[item_idx[:start]]
15
+ unless (!prev_token.nil?) && COMMENT_TOKENS.include?(prev_token.type)
16
+ first_token = item_idx[:tokens].first
23
17
  if first_token.type == :CLASS
24
18
  type = 'class'
25
19
  else
@@ -27,9 +21,9 @@ class PuppetLint::Plugins::CheckDocumentation < PuppetLint::CheckPlugin
27
21
  end
28
22
 
29
23
  notify :warning, {
30
- :message => "#{type} not documented",
31
- :linenumber => first_token.line,
32
- :column => first_token.column,
24
+ :message => "#{type} not documented",
25
+ :line => first_token.line,
26
+ :column => first_token.column,
33
27
  }
34
28
  end
35
29
  end
@@ -0,0 +1,23 @@
1
+ # Public: Check the manifest for unquoted node names and record a warning for
2
+ # each instance found.
3
+ PuppetLint.new_check(:unquoted_node_name) do
4
+ def check
5
+ tokens.select { |r|
6
+ r.type == :NODE && r.next_code_token.type == :NAME
7
+ }.each do |token|
8
+ value_token = token.next_code_token
9
+ unless value_token.value == 'default'
10
+ notify :warning, {
11
+ :message => 'unquoted node name found',
12
+ :line => value_token.line,
13
+ :column => value_token.column,
14
+ :token => value_token,
15
+ }
16
+ end
17
+ end
18
+ end
19
+
20
+ def fix(problem)
21
+ problem[:token].type = :SSTRING
22
+ end
23
+ end
@@ -1,208 +1,194 @@
1
- class PuppetLint::Plugins::CheckResources < PuppetLint::CheckPlugin
2
- # Public: Check the manifest tokens for any resource titles / namevars that
3
- # are not quoted and record a warning for each instance found.
4
- #
5
- # Return nothing.
6
- check 'unquoted_resource_title' do
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
+ PuppetLint.new_check(:unquoted_resource_title) do
4
+ def check
7
5
  title_tokens.each do |token|
8
6
  if token.type == :NAME
9
- if PuppetLint.configuration.fix
10
- token.type = :SSTRING
11
- notify_type = :fixed
12
- else
13
- notify_type = :warning
14
- end
15
-
16
- notify notify_type, {
17
- :message => 'unquoted resource title',
18
- :linenumber => token.line,
19
- :column => token.column,
7
+ notify :warning, {
8
+ :message => 'unquoted resource title',
9
+ :line => token.line,
10
+ :column => token.column,
11
+ :token => token,
20
12
  }
21
13
  end
22
14
  end
23
15
  end
24
16
 
25
- # Public: Check the tokens of each resource instance for an ensure parameter
26
- # and if found, check that it is the first parameter listed. If it is not
27
- # the first parameter, record a warning.
28
- #
29
- # Returns nothing.
30
- check 'ensure_first_param' do
31
- resource_indexes.each do |resource|
32
- resource_tokens = tokens[resource[:start]..resource[:end]]
17
+ def fix(problem)
18
+ problem[:token].type = :SSTRING
19
+ end
20
+ end
33
21
 
34
- param_tokens = resource_tokens.select { |resource_token|
35
- resource_token.type == :NAME && resource_token.next_code_token.type == :FARROW
36
- }
37
- ensure_attr_index = param_tokens.index { |resource_token|
38
- resource_token.value == 'ensure'
22
+ # Public: Check the tokens of each resource instance for an ensure parameter
23
+ # and if found, check that it is the first parameter listed. If it is not
24
+ # the first parameter, record a warning.
25
+ PuppetLint.new_check(:ensure_first_param) do
26
+ def check
27
+ resource_indexes.each do |resource|
28
+ ensure_attr_index = resource[:param_tokens].index { |param_token|
29
+ param_token.value == 'ensure'
39
30
  }
40
31
 
41
32
  unless ensure_attr_index.nil?
42
33
  if ensure_attr_index > 0
43
- ensure_token = param_tokens[ensure_attr_index]
34
+ ensure_token = resource[:param_tokens][ensure_attr_index]
44
35
  notify :warning, {
45
- :message => "ensure found on line but it's not the first attribute",
46
- :linenumber => ensure_token.line,
47
- :column => ensure_token.column,
36
+ :message => "ensure found on line but it's not the first attribute",
37
+ :line => ensure_token.line,
38
+ :column => ensure_token.column,
48
39
  }
49
40
  end
50
41
  end
51
42
  end
52
43
  end
44
+ end
53
45
 
54
- check 'duplicate_params' do
46
+ # Public: Check the tokens of each resource instance for any duplicate
47
+ # parameters and record a warning for each instance found.
48
+ PuppetLint.new_check(:duplicate_params) do
49
+ def check
55
50
  resource_indexes.each do |resource|
56
- resource_tokens = tokens[resource[:start]..resource[:end]].reject { |r|
57
- formatting_tokens.include? r.type
58
- }
59
-
60
51
  seen_params = {}
61
52
  level = 0
62
- resource_tokens.each_with_index do |token, idx|
53
+
54
+ resource[:tokens].each_with_index do |token, idx|
63
55
  case token.type
64
56
  when :LBRACE
65
57
  level += 1
66
58
  next
67
59
  when :RBRACE
68
- seen_params[level] = {}
60
+ seen_params.delete(level)
69
61
  level -= 1
70
62
  next
71
- end
72
- seen_params[level] ||= {}
73
-
74
- if token.type == :FARROW
75
- prev_token = resource_tokens[idx - 1]
63
+ when :FARROW
64
+ prev_token = token.prev_code_token
76
65
  next unless prev_token.type == :NAME
77
- if seen_params[level].include? prev_token.value
66
+
67
+ if (seen_params[level] ||= Set.new).include?(prev_token.value)
78
68
  notify :error, {
79
- :message => 'duplicate parameter found in resource',
80
- :linenumber => prev_token.line,
81
- :column => prev_token.column,
69
+ :message => 'duplicate parameter found in resource',
70
+ :line => prev_token.line,
71
+ :column => prev_token.column,
82
72
  }
83
73
  else
84
- seen_params[level][prev_token.value] = true
74
+ seen_params[level] << prev_token.value
85
75
  end
86
76
  end
87
77
  end
88
78
  end
89
79
  end
80
+ end
90
81
 
91
- # Public: Check the tokens of each File resource instance for a mode
92
- # parameter and if found, record a warning if the value of that parameter is
93
- # not a quoted string.
94
- #
95
- # Returns nothing.
96
- check 'unquoted_file_mode' do
97
- resource_indexes.each do |resource|
98
- resource_tokens = tokens[resource[:start]..resource[:end]]
99
- prev_tokens = tokens[0..resource[:start]]
82
+ # Public: Check the tokens of each File resource instance for a mode
83
+ # parameter and if found, record a warning if the value of that parameter is
84
+ # not a quoted string.
85
+ PuppetLint.new_check(:unquoted_file_mode) do
86
+ TOKEN_TYPES = Set[:NAME, :NUMBER]
100
87
 
101
- lbrace_idx = prev_tokens.rindex { |r|
102
- r.type == :LBRACE
103
- }
104
-
105
- resource_type_token = tokens[lbrace_idx].prev_code_token
106
- if resource_type_token.value == "file"
107
- resource_tokens.select { |resource_token|
108
- resource_token.type == :NAME and resource_token.value == 'mode'
109
- }.each do |resource_token|
110
- value_token = resource_token.next_code_token.next_code_token
111
- if {:NAME => true, :NUMBER => true}.include? value_token.type
112
- if PuppetLint.configuration.fix
113
- value_token.type = :SSTRING
114
- notify_type = :fixed
115
- else
116
- notify_type = :warning
117
- end
118
-
119
- notify notify_type, {
120
- :message => 'unquoted file mode',
121
- :linenumber => value_token.line,
122
- :column => value_token.column,
123
- }
124
- end
88
+ def check
89
+ resource_indexes.each do |resource|
90
+ if resource[:type].value == "file"
91
+ resource[:param_tokens].select { |param_token|
92
+ param_token.value == 'mode' &&
93
+ TOKEN_TYPES.include?(param_token.next_code_token.next_code_token.type)
94
+ }.each do |param_token|
95
+ value_token = param_token.next_code_token.next_code_token
96
+ notify :warning, {
97
+ :message => 'unquoted file mode',
98
+ :line => value_token.line,
99
+ :column => value_token.column,
100
+ :token => value_token,
101
+ }
125
102
  end
126
103
  end
127
104
  end
128
105
  end
129
106
 
130
- # Public: Check the tokens of each File resource instance for a mode
131
- # parameter and if found, record a warning if the value of that parameter is
132
- # not a 4 digit octal value (0755) or a symbolic mode ('o=rwx,g+r').
133
- #
134
- # Returns nothing.
135
- check 'file_mode' do
136
- msg = 'mode should be represented as a 4 digit octal value or symbolic mode'
137
- sym_mode = /\A([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*\Z/
138
-
139
- resource_indexes.each do |resource|
140
- resource_tokens = tokens[resource[:start]..resource[:end]]
141
- prev_tokens = tokens[0..resource[:start]]
142
-
143
- lbrace_idx = prev_tokens.rindex { |r|
144
- r.type == :LBRACE
145
- }
146
-
147
- resource_type_token = tokens[lbrace_idx].prev_code_token
148
- if resource_type_token.value == "file"
149
- resource_tokens.select { |resource_token|
150
- resource_token.type == :NAME and resource_token.value == 'mode'
151
- }.each do |resource_token|
152
- value_token = resource_token.next_code_token.next_code_token
107
+ def fix(problem)
108
+ problem[:token].type = :SSTRING
109
+ end
110
+ end
153
111
 
154
- break if value_token.value =~ /\A[0-7]{4}\Z/
155
- break if value_token.type == :VARIABLE
156
- break if value_token.value =~ sym_mode
157
- break if value_token.type == :UNDEF
112
+ # Public: Check the tokens of each File resource instance for a mode
113
+ # parameter and if found, record a warning if the value of that parameter is
114
+ # not a 4 digit octal value (0755) or a symbolic mode ('o=rwx,g+r').
115
+ PuppetLint.new_check(:file_mode) do
116
+ MSG = 'mode should be represented as a 4 digit octal value or symbolic mode'
117
+ SYM_RE = "([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*"
118
+ IGNORE_TYPES = Set[:VARIABLE, :UNDEF]
119
+ MODE_RE = Regexp.new(/\A([0-7]{4}|#{SYM_RE})\Z/)
158
120
 
159
- notify_type = :warning
121
+ def check
122
+ resource_indexes.each do |resource|
123
+ if resource[:type].value == "file"
124
+ resource[:param_tokens].select { |param_token|
125
+ param_token.value == 'mode'
126
+ }.each do |param_token|
127
+ value_token = param_token.next_code_token.next_code_token
160
128
 
161
- if PuppetLint.configuration.fix && value_token.value =~ /\A[0-7]{3}\Z/
162
- value_token.value = "0#{value_token.value.to_s}"
163
- value_token.type = :SSTRING
164
- notify_type = :fixed
165
- end
129
+ break if IGNORE_TYPES.include?(value_token.type)
130
+ break if value_token.value =~ MODE_RE
166
131
 
167
- notify notify_type, {
168
- :message => msg,
169
- :linenumber => value_token.line,
170
- :column => value_token.column,
132
+ notify :warning, {
133
+ :message => MSG,
134
+ :line => value_token.line,
135
+ :column => value_token.column,
136
+ :token => value_token,
171
137
  }
172
138
  end
173
139
  end
174
140
  end
175
141
  end
176
142
 
177
- # Public: Check the tokens of each File resource instance for an ensure
178
- # parameter and record a warning if the value of that parameter looks like
179
- # a symlink target (starts with a '/').
180
- #
181
- # Returns nothing.
182
- check 'ensure_not_symlink_target' do
183
- resource_indexes.each do |resource|
184
- resource_tokens = tokens[resource[:start]..resource[:end]]
185
- prev_tokens = tokens[0..resource[:start]]
186
-
187
- lbrace_idx = prev_tokens.rindex { |r|
188
- r.type == :LBRACE
189
- }
143
+ def fix(problem)
144
+ if problem[:token].value =~ /\A[0-7]{3}\Z/
145
+ problem[:token].type = :SSTRING
146
+ problem[:token].value = "0#{problem[:token].value.to_s}"
147
+ else
148
+ raise PuppetLint::NoFix
149
+ end
150
+ end
151
+ end
190
152
 
191
- resource_type_token = tokens[lbrace_idx].prev_code_token
192
- if resource_type_token.value == "file"
193
- resource_tokens.select { |resource_token|
194
- resource_token.type == :NAME and resource_token.value == 'ensure'
153
+ # Public: Check the tokens of each File resource instance for an ensure
154
+ # parameter and record a warning if the value of that parameter looks like
155
+ # a symlink target (starts with a '/').
156
+ PuppetLint.new_check(:ensure_not_symlink_target) do
157
+ def check
158
+ resource_indexes.each do |resource|
159
+ if resource[:type].value == "file"
160
+ resource[:param_tokens].select { |param_token|
161
+ param_token.value == 'ensure'
195
162
  }.each do |ensure_token|
196
163
  value_token = ensure_token.next_code_token.next_code_token
197
164
  if value_token.value.start_with? '/'
198
165
  notify :warning, {
199
- :message => 'symlink target specified in ensure attr',
200
- :linenumber => value_token.line,
201
- :column => value_token.column,
166
+ :message => 'symlink target specified in ensure attr',
167
+ :line => value_token.line,
168
+ :column => value_token.column,
169
+ :param_token => ensure_token,
170
+ :value_token => value_token,
202
171
  }
203
172
  end
204
173
  end
205
174
  end
206
175
  end
207
176
  end
177
+
178
+ def fix(problem)
179
+ index = tokens.index(problem[:value_token])
180
+
181
+ [
182
+ PuppetLint::Lexer::Token.new(:NAME, 'symlink', 0, 0),
183
+ PuppetLint::Lexer::Token.new(:COMMA, ',', 0, 0),
184
+ PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
185
+ PuppetLint::Lexer::Token.new(:INDENT, problem[:param_token].prev_token.value.dup, 0, 0),
186
+ PuppetLint::Lexer::Token.new(:NAME, 'target', 0, 0),
187
+ PuppetLint::Lexer::Token.new(:WHITESPACE, problem[:param_token].next_token.value.dup, 0, 0),
188
+ PuppetLint::Lexer::Token.new(:FARROW, '=>', 0, 0),
189
+ PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
190
+ ].reverse.each do |new_token|
191
+ tokens.insert(index, new_token)
192
+ end
193
+ end
208
194
  end