puppet-lint-halyard 1.1.0.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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +20 -0
  6. data/README.md +210 -0
  7. data/Rakefile +14 -0
  8. data/bin/puppet-lint +7 -0
  9. data/lib/puppet-lint.rb +214 -0
  10. data/lib/puppet-lint/bin.rb +79 -0
  11. data/lib/puppet-lint/checkplugin.rb +176 -0
  12. data/lib/puppet-lint/checks.rb +91 -0
  13. data/lib/puppet-lint/configuration.rb +153 -0
  14. data/lib/puppet-lint/data.rb +521 -0
  15. data/lib/puppet-lint/lexer.rb +373 -0
  16. data/lib/puppet-lint/lexer/token.rb +101 -0
  17. data/lib/puppet-lint/monkeypatches.rb +2 -0
  18. data/lib/puppet-lint/monkeypatches/string_percent.rb +52 -0
  19. data/lib/puppet-lint/monkeypatches/string_prepend.rb +13 -0
  20. data/lib/puppet-lint/optparser.rb +118 -0
  21. data/lib/puppet-lint/plugins.rb +74 -0
  22. data/lib/puppet-lint/plugins/check_classes.rb +285 -0
  23. data/lib/puppet-lint/plugins/check_comments.rb +55 -0
  24. data/lib/puppet-lint/plugins/check_conditionals.rb +65 -0
  25. data/lib/puppet-lint/plugins/check_documentation.rb +31 -0
  26. data/lib/puppet-lint/plugins/check_nodes.rb +29 -0
  27. data/lib/puppet-lint/plugins/check_resources.rb +194 -0
  28. data/lib/puppet-lint/plugins/check_strings.rb +174 -0
  29. data/lib/puppet-lint/plugins/check_variables.rb +19 -0
  30. data/lib/puppet-lint/plugins/check_whitespace.rb +170 -0
  31. data/lib/puppet-lint/tasks/puppet-lint.rb +91 -0
  32. data/lib/puppet-lint/version.rb +3 -0
  33. data/puppet-lint.gemspec +24 -0
  34. data/spec/fixtures/test/manifests/fail.pp +2 -0
  35. data/spec/fixtures/test/manifests/ignore.pp +1 -0
  36. data/spec/fixtures/test/manifests/ignore_multiple_block.pp +6 -0
  37. data/spec/fixtures/test/manifests/ignore_multiple_line.pp +2 -0
  38. data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
  39. data/spec/fixtures/test/manifests/init.pp +3 -0
  40. data/spec/fixtures/test/manifests/malformed.pp +1 -0
  41. data/spec/fixtures/test/manifests/url_interpolation.pp +12 -0
  42. data/spec/fixtures/test/manifests/warning.pp +2 -0
  43. data/spec/puppet-lint/bin_spec.rb +326 -0
  44. data/spec/puppet-lint/configuration_spec.rb +56 -0
  45. data/spec/puppet-lint/ignore_overrides_spec.rb +109 -0
  46. data/spec/puppet-lint/lexer/token_spec.rb +18 -0
  47. data/spec/puppet-lint/lexer_spec.rb +783 -0
  48. data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +105 -0
  49. data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +35 -0
  50. data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +33 -0
  51. data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +45 -0
  52. data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +76 -0
  53. data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +73 -0
  54. data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +25 -0
  55. data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +196 -0
  56. data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +45 -0
  57. data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +84 -0
  58. data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +98 -0
  59. data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +36 -0
  60. data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +52 -0
  61. data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +146 -0
  62. data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +100 -0
  63. data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +55 -0
  64. data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +89 -0
  65. data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +113 -0
  66. data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +45 -0
  67. data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +216 -0
  68. data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +199 -0
  69. data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +114 -0
  70. data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +62 -0
  71. data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +129 -0
  72. data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +17 -0
  73. data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +73 -0
  74. data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +37 -0
  75. data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +21 -0
  76. data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +54 -0
  77. data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +524 -0
  78. data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +45 -0
  79. data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +101 -0
  80. data/spec/puppet-lint_spec.rb +20 -0
  81. data/spec/spec_helper.rb +129 -0
  82. metadata +229 -0
@@ -0,0 +1,55 @@
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
5
+ tokens.select { |token|
6
+ token.type == :SLASH_COMMENT
7
+ }.each do |token|
8
+ notify :warning, {
9
+ :message => '// comment found',
10
+ :line => token.line,
11
+ :column => token.column,
12
+ :token => token,
13
+ }
14
+ end
15
+ end
16
+
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
26
+ tokens.select { |token|
27
+ token.type == :MLCOMMENT
28
+ }.each do |token|
29
+ notify :warning, {
30
+ :message => '/* */ comment found',
31
+ :line => token.line,
32
+ :column => token.column,
33
+ :token => token,
34
+ }
35
+ end
36
+ end
37
+
38
+ def fix(problem)
39
+ comment_lines = problem[:token].value.strip.split("\n").map(&:strip)
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
55
+ end
@@ -0,0 +1,65 @@
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
5
+ resource_indexes.each do |resource|
6
+ resource[:tokens].each do |token|
7
+ if token.type == :FARROW
8
+ if token.next_code_token.type == :VARIABLE
9
+ unless token.next_code_token.next_code_token.nil?
10
+ if token.next_code_token.next_code_token.type == :QMARK
11
+ notify :warning, {
12
+ :message => 'selector inside resource block',
13
+ :line => token.line,
14
+ :column => token.column,
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
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
29
+ case_indexes = []
30
+
31
+ tokens.each_index do |token_idx|
32
+ if tokens[token_idx].type == :CASE
33
+ depth = 0
34
+ tokens[(token_idx + 1)..-1].each_index do |case_token_idx|
35
+ idx = case_token_idx + token_idx + 1
36
+ if tokens[idx].type == :LBRACE
37
+ depth += 1
38
+ elsif tokens[idx].type == :RBRACE
39
+ depth -= 1
40
+ if depth == 0
41
+ case_indexes << {:start => token_idx, :end => idx}
42
+ break
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ case_indexes.each_with_index do |kase,kase_index|
50
+ case_tokens = tokens[kase[:start]..kase[:end]]
51
+
52
+ case_indexes[(kase_index + 1)..-1].each do |successor_kase|
53
+ case_tokens -= tokens[successor_kase[:start]..successor_kase[:end]]
54
+ end
55
+
56
+ unless case_tokens.index { |r| r.type == :DEFAULT }
57
+ notify :warning, {
58
+ :message => 'case statement without a default case',
59
+ :line => case_tokens.first.line,
60
+ :column => case_tokens.first.column,
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,31 @@
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]
7
+
8
+ def check
9
+ (class_indexes + defined_type_indexes).each do |item_idx|
10
+ prev_token = item_idx[:tokens].first.prev_token
11
+ while (!prev_token.nil?) && WHITESPACE_TOKENS.include?(prev_token.type)
12
+ prev_token = prev_token.prev_token
13
+ end
14
+
15
+ unless (!prev_token.nil?) && COMMENT_TOKENS.include?(prev_token.type)
16
+ first_token = item_idx[:tokens].first
17
+ if first_token.type == :CLASS
18
+ type = 'class'
19
+ else
20
+ type = 'defined type'
21
+ end
22
+
23
+ notify :warning, {
24
+ :message => "#{type} not documented",
25
+ :line => first_token.line,
26
+ :column => first_token.column,
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
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
+ node_tokens = tokens.select { |token| token.type == :NODE }
6
+ node_tokens.each do |node|
7
+ node_token_idx = tokens.index(node)
8
+ node_lbrace_tok = tokens[node_token_idx..-1].find { |token| token.type == :LBRACE }
9
+ node_lbrace_idx = tokens.index(node_lbrace_tok)
10
+
11
+ tokens[node_token_idx..node_lbrace_idx].select { |token|
12
+ token.type == :NAME
13
+ }.each do |token|
14
+ unless token.value == 'default'
15
+ notify :warning, {
16
+ :message => 'unquoted node name found',
17
+ :line => token.line,
18
+ :column => token.column,
19
+ :token => token,
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def fix(problem)
27
+ problem[:token].type = :SSTRING
28
+ end
29
+ end
@@ -0,0 +1,194 @@
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
5
+ title_tokens.each do |token|
6
+ if token.type == :NAME
7
+ notify :warning, {
8
+ :message => 'unquoted resource title',
9
+ :line => token.line,
10
+ :column => token.column,
11
+ :token => token,
12
+ }
13
+ end
14
+ end
15
+ end
16
+
17
+ def fix(problem)
18
+ problem[:token].type = :SSTRING
19
+ end
20
+ end
21
+
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'
30
+ }
31
+
32
+ unless ensure_attr_index.nil?
33
+ if ensure_attr_index > 0
34
+ ensure_token = resource[:param_tokens][ensure_attr_index]
35
+ notify :warning, {
36
+ :message => "ensure found on line but it's not the first attribute",
37
+ :line => ensure_token.line,
38
+ :column => ensure_token.column,
39
+ }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
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
50
+ resource_indexes.each do |resource|
51
+ seen_params = {}
52
+ level = 0
53
+
54
+ resource[:tokens].each_with_index do |token, idx|
55
+ case token.type
56
+ when :LBRACE
57
+ level += 1
58
+ next
59
+ when :RBRACE
60
+ seen_params.delete(level)
61
+ level -= 1
62
+ next
63
+ when :FARROW
64
+ prev_token = token.prev_code_token
65
+ next unless prev_token.type == :NAME
66
+
67
+ if (seen_params[level] ||= Set.new).include?(prev_token.value)
68
+ notify :error, {
69
+ :message => 'duplicate parameter found in resource',
70
+ :line => prev_token.line,
71
+ :column => prev_token.column,
72
+ }
73
+ else
74
+ seen_params[level] << prev_token.value
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
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]
87
+
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
+ }
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def fix(problem)
108
+ problem[:token].type = :SSTRING
109
+ end
110
+ end
111
+
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/)
120
+
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
128
+
129
+ break if IGNORE_TYPES.include?(value_token.type)
130
+ break if value_token.value =~ MODE_RE
131
+
132
+ notify :warning, {
133
+ :message => MSG,
134
+ :line => value_token.line,
135
+ :column => value_token.column,
136
+ :token => value_token,
137
+ }
138
+ end
139
+ end
140
+ end
141
+ end
142
+
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
152
+
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'
162
+ }.each do |ensure_token|
163
+ value_token = ensure_token.next_code_token.next_code_token
164
+ if value_token.value.start_with? '/'
165
+ notify :warning, {
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,
171
+ }
172
+ end
173
+ end
174
+ end
175
+ end
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
194
+ end
@@ -0,0 +1,174 @@
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
+ PuppetLint.new_check(:double_quoted_strings) do
5
+ def check
6
+ tokens.select { |token|
7
+ token.type == :STRING
8
+ }.map { |token|
9
+ [token, token.value.gsub(' '*token.column, "\n")]
10
+ }.select { |token, sane_value|
11
+ sane_value[/(\\\$|\\"|\\'|'|\r|\t|\\t|\n|\\n)/].nil?
12
+ }.each do |token, sane_value|
13
+ notify :warning, {
14
+ :message => 'double quoted string containing no variables',
15
+ :line => token.line,
16
+ :column => token.column,
17
+ :token => token,
18
+ }
19
+ end
20
+ end
21
+
22
+ def fix(problem)
23
+ problem[:token].type = :SSTRING
24
+ end
25
+ end
26
+
27
+ # Public: Check the manifest tokens for double quoted strings that contain
28
+ # a single variable only and record a warning for each instance found.
29
+ PuppetLint.new_check(:only_variable_string) do
30
+ VAR_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
31
+
32
+ def check
33
+ tokens.each_with_index do |start_token, start_token_idx|
34
+ if start_token.type == :DQPRE and start_token.value == ''
35
+ var_token = start_token.next_token
36
+ if VAR_TYPES.include? var_token.type
37
+ eos_offset = 2
38
+ loop do
39
+ eos_token = tokens[start_token_idx + eos_offset]
40
+ case eos_token.type
41
+ when :LBRACK
42
+ eos_offset += 3
43
+ when :DQPOST
44
+ if eos_token.value == ''
45
+ if eos_token.next_code_token && eos_token.next_code_token.type == :FARROW
46
+ break
47
+ end
48
+ notify :warning, {
49
+ :message => 'string containing only a variable',
50
+ :line => var_token.line,
51
+ :column => var_token.column,
52
+ :start_token => start_token,
53
+ :var_token => var_token,
54
+ :end_token => eos_token,
55
+ }
56
+ end
57
+ break
58
+ else
59
+ break
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def fix(problem)
68
+ prev_token = problem[:start_token].prev_token
69
+ prev_code_token = problem[:start_token].prev_code_token
70
+ next_token = problem[:end_token].next_token
71
+ next_code_token = problem[:end_token].next_code_token
72
+ var_token = problem[:var_token]
73
+
74
+ tokens.delete(problem[:start_token])
75
+ tokens.delete(problem[:end_token])
76
+
77
+ prev_token.next_token = var_token unless prev_token.nil?
78
+ prev_code_token.next_code_token = var_token unless prev_code_token.nil?
79
+ next_code_token.prev_code_token = var_token unless next_code_token.nil?
80
+ next_token.prev_token = var_token unless next_token.nil?
81
+ var_token.type = :VARIABLE
82
+ var_token.next_token = next_token
83
+ var_token.next_code_token = next_code_token
84
+ var_token.prev_code_token = prev_code_token
85
+ var_token.prev_token = prev_token
86
+ end
87
+ end
88
+
89
+ # Public: Check the manifest tokens for any variables in a string that have
90
+ # not been enclosed by braces ({}) and record a warning for each instance
91
+ # found.
92
+ PuppetLint.new_check(:variables_not_enclosed) do
93
+ def check
94
+ tokens.select { |r|
95
+ r.type == :UNENC_VARIABLE
96
+ }.each do |token|
97
+ notify :warning, {
98
+ :message => 'variable not enclosed in {}',
99
+ :line => token.line,
100
+ :column => token.column,
101
+ :token => token,
102
+ }
103
+ end
104
+ end
105
+
106
+ def fix(problem)
107
+ problem[:token].type = :VARIABLE
108
+ end
109
+ end
110
+
111
+ # Public: Check the manifest tokens for any single quoted strings containing
112
+ # a enclosed variable and record an error for each instance found.
113
+ PuppetLint.new_check(:single_quote_string_with_variables) do
114
+ def check
115
+ tokens.select { |r|
116
+ r.type == :SSTRING && r.value.include?('${')
117
+ }.each do |token|
118
+ notify :error, {
119
+ :message => 'single quoted string containing a variable found',
120
+ :line => token.line,
121
+ :column => token.column,
122
+ }
123
+ end
124
+ end
125
+ end
126
+
127
+ # Public: Check the manifest tokens for any double or single quoted strings
128
+ # containing only a boolean value and record a warning for each instance
129
+ # found.
130
+ PuppetLint.new_check(:quoted_booleans) do
131
+ STRING_TYPES = Set[:STRING, :SSTRING]
132
+ BOOLEANS = Set['true', 'false']
133
+
134
+ def check
135
+ tokens.select { |r|
136
+ STRING_TYPES.include?(r.type) && BOOLEANS.include?(r.value)
137
+ }.each do |token|
138
+ notify :warning, {
139
+ :message => 'quoted boolean value found',
140
+ :line => token.line,
141
+ :column => token.column,
142
+ :token => token,
143
+ }
144
+ end
145
+ end
146
+
147
+ def fix(problem)
148
+ problem[:token].type = problem[:token].value.upcase.to_sym
149
+ end
150
+ end
151
+
152
+ # Public: Check the manifest tokens for any puppet:// URL strings where the
153
+ # path section doesn't start with modules/ and record a warning for each
154
+ # instance found.
155
+ PuppetLint.new_check(:puppet_url_without_modules) do
156
+ def check
157
+ tokens.select { |token|
158
+ (token.type == :SSTRING || token.type == :STRING || token.type == :DQPRE) && token.value.start_with?('puppet://')
159
+ }.reject { |token|
160
+ token.value[/puppet:\/\/.*?\/(.+)/, 1].start_with?('modules/') unless token.value[/puppet:\/\/.*?\/(.+)/, 1].nil?
161
+ }.each do |token|
162
+ notify :warning, {
163
+ :message => 'puppet:// URL without modules/ found',
164
+ :line => token.line,
165
+ :column => token.column,
166
+ :token => token,
167
+ }
168
+ end
169
+ end
170
+
171
+ def fix(problem)
172
+ problem[:token].value.gsub!(/(puppet:\/\/.*?\/)/, '\1modules/')
173
+ end
174
+ end