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,2 @@
1
+ require 'puppet-lint/monkeypatches/string_prepend'
2
+ require 'puppet-lint/monkeypatches/string_percent'
@@ -0,0 +1,52 @@
1
+ # If we are using an older ruby version, we back-port the basic functionality
2
+ # we need for formatting output: 'somestring' % <hash>
3
+ begin
4
+ if ('%{test}' % {:test => 'replaced'} == 'replaced')
5
+ # If this works, we are all good to go.
6
+ end
7
+ rescue
8
+ # If the test failed (threw a error), monkeypatch String.
9
+ # Most of this code came from http://www.ruby-forum.com/topic/144310 but was
10
+ # simplified for our use.
11
+
12
+ # Basic implementation of 'string' % { } like we need it. needs work.
13
+ class String
14
+ Percent = instance_method '%' unless defined? Percent
15
+ def % *a, &b
16
+ a.flatten!
17
+
18
+ string = case a.last
19
+ when Hash
20
+ expand a.pop
21
+ else
22
+ self
23
+ end
24
+
25
+ if a.empty?
26
+ string
27
+ else
28
+ Percent.bind(string).call(a, &b)
29
+ end
30
+
31
+ end
32
+ def expand! vars = {}
33
+ loop do
34
+ changed = false
35
+ vars.each do |var, value|
36
+ var = var.to_s
37
+ var.gsub! %r/[^a-zA-Z0-9_]/, ''
38
+ [
39
+ %r/\%\{#{ var }\}/,
40
+ ].each do |pat|
41
+ changed = gsub! pat, "#{ value }"
42
+ end
43
+ end
44
+ break unless changed
45
+ end
46
+ self
47
+ end
48
+ def expand opts = {}
49
+ dup.expand! opts
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ unless String.respond_to?('prepend')
2
+ # Internal: Monkey patching String.
3
+ class String
4
+ # Internal: Prepends a String to self.
5
+ #
6
+ # lead - The String to prepend self with.
7
+ #
8
+ # Returns a String which is lead and self concatenated.
9
+ def prepend(lead)
10
+ self.replace "#{lead}#{self}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,118 @@
1
+ require 'optparse'
2
+
3
+ # Public: Contains the puppet-lint option parser so that it can be used easily
4
+ # in multiple places.
5
+ class PuppetLint::OptParser
6
+ HELP_TEXT = <<-EOF
7
+ puppet-lint
8
+
9
+ Basic Command Line Usage:
10
+ puppet-lint [OPTIONS] PATH
11
+
12
+ PATH The path to the Puppet manifest.
13
+
14
+ Option:
15
+ EOF
16
+
17
+ # Public: Initialise a new puppet-lint OptionParser.
18
+ #
19
+ # Returns an OptionParser object.
20
+ def self.build
21
+ OptionParser.new do |opts|
22
+ opts.banner = HELP_TEXT
23
+
24
+ opts.on('--version', 'Display the current version.') do
25
+ PuppetLint.configuration.display_version = true
26
+ end
27
+
28
+ opts.on('-c', '--config FILE', 'Load puppet-lint options from file.') do |file|
29
+ opts.load(file)
30
+ end
31
+
32
+ opts.on('--with-context', 'Show where in the manifest the problem is.') do
33
+ PuppetLint.configuration.with_context = true
34
+ end
35
+
36
+ opts.on('--with-filename', 'Display the filename before the warning.') do
37
+ PuppetLint.configuration.with_filename = true
38
+ end
39
+
40
+ opts.on('--fail-on-warnings', 'Return a non-zero exit status for warnings') do
41
+ PuppetLint.configuration.fail_on_warnings = true
42
+ end
43
+
44
+ opts.on('--error-level LEVEL', [:all, :warning, :error],
45
+ 'The level of error to return (warning, error or all).') do |el|
46
+ PuppetLint.configuration.error_level = el
47
+ end
48
+
49
+ opts.on('--show-ignored', 'Show problems that have been ignored by control comments') do
50
+ PuppetLint.configuration.show_ignored = true
51
+ end
52
+
53
+ opts.on('--relative', 'Compare module layout relative to the module root') do
54
+ PuppetLint.configuration.relative = true
55
+ end
56
+
57
+ opts.on('-l', '--load FILE', 'Load a file containing custom puppet-lint checks.') do |f|
58
+ load f
59
+ end
60
+
61
+ opts.on('--load-from-puppet MODULEPATH', 'Load plugins from the given Puppet module path.') do |path|
62
+ path.split(':').each do |p|
63
+ Dir["#{p}/*/lib/puppet-lint/plugins/*.rb"].each do |file|
64
+ load file
65
+ end
66
+ end
67
+ end
68
+
69
+ opts.on('-f', '--fix', 'Attempt to automatically fix errors') do
70
+ PuppetLint.configuration.fix = true
71
+ end
72
+
73
+ opts.on('--log-format FORMAT',
74
+ 'Change the log format.', 'Overrides --with-filename.',
75
+ 'The following placeholders can be used:',
76
+ '%{filename} - Filename without path.',
77
+ '%{path} - Path as provided to puppet-lint.',
78
+ '%{fullpath} - Expanded path to the file.',
79
+ '%{line} - Line number.',
80
+ '%{column} - Column number.',
81
+ '%{kind} - The kind of message (warning, error).',
82
+ '%{KIND} - Uppercase version of %{kind}.',
83
+ '%{check} - The name of the check.',
84
+ '%{message} - The message.'
85
+ ) do |format|
86
+ if format.include?('%{linenumber}')
87
+ $stderr.puts "DEPRECATION: Please use %{line} instead of %{linenumber}"
88
+ end
89
+ PuppetLint.configuration.log_format = format
90
+ end
91
+
92
+ opts.separator ''
93
+ opts.separator ' Checks:'
94
+
95
+ opts.on('--only-checks CHECKS', 'A comma separated list of checks that should be run') do |checks|
96
+ enable_checks = checks.split(',').map(&:to_sym)
97
+ (PuppetLint.configuration.checks - enable_checks).each do |check|
98
+ PuppetLint.configuration.send("disable_#{check}")
99
+ end
100
+ end
101
+
102
+ PuppetLint.configuration.checks.each do |check|
103
+ opts.on("--no-#{check}-check", "Skip the #{check} check.") do
104
+ PuppetLint.configuration.send("disable_#{check}")
105
+ end
106
+ end
107
+
108
+ opts.load('/etc/puppet-lint.rc')
109
+ begin
110
+ opts.load(File.expand_path('~/.puppet-lint.rc')) if ENV['HOME']
111
+ rescue Errno::EACCES
112
+ # silently skip loading this file if HOME is set to a directory that
113
+ # the user doesn't have read access to.
114
+ end
115
+ opts.load('.puppet-lint.rc')
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,74 @@
1
+ require 'pathname'
2
+
3
+ class PuppetLint
4
+ # Public: Various methods that implement puppet-lint's plugin system
5
+ #
6
+ # Examples
7
+ #
8
+ # PuppetLint::Plugins.load_spec_helper
9
+ class Plugins
10
+ # Internal: Find any gems containing puppet-lint plugins and load them.
11
+ #
12
+ # Returns nothing.
13
+ def self.load_from_gems
14
+ gem_directories.select { |path|
15
+ (path + 'puppet-lint/plugins').directory?
16
+ }.each do |gem_path|
17
+ Dir["#{(gem_path + 'puppet-lint/plugins').to_s}/*.rb"].each do |file|
18
+ load file
19
+ end
20
+ end
21
+ end
22
+
23
+ # Public: Load the puppet-lint spec_helper.rb
24
+ #
25
+ # Returns nothings.
26
+ def self.load_spec_helper
27
+ gemspec = gemspecs.select { |spec| spec.name == 'puppet-lint' }.first
28
+ load Pathname.new(gemspec.full_gem_path) + 'spec/spec_helper.rb'
29
+ end
30
+ private
31
+ # Internal: Check if RubyGems is loaded and available.
32
+ #
33
+ # Returns true if RubyGems is available, false if not.
34
+ def self.has_rubygems?
35
+ defined? ::Gem
36
+ end
37
+
38
+ # Internal: Retrieve a list of avaliable gemspecs.
39
+ #
40
+ # Returns an Array of Gem::Specification objects.
41
+ def self.gemspecs
42
+ @gemspecs ||= if Gem::Specification.respond_to?(:latest_specs)
43
+ Gem::Specification.latest_specs
44
+ else
45
+ Gem.searcher.init_gemspecs
46
+ end
47
+ end
48
+
49
+ # Internal: Retrieve a list of available gem paths from RubyGems.
50
+ #
51
+ # Returns an Array of Pathname objects.
52
+ def self.gem_directories
53
+ if has_rubygems?
54
+ gemspecs.reject { |spec| spec.name == 'puppet-lint' }.map do |spec|
55
+ Pathname.new(spec.full_gem_path) + 'lib'
56
+ end
57
+ else
58
+ []
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ require 'puppet-lint/plugins/check_classes'
65
+ require 'puppet-lint/plugins/check_comments'
66
+ require 'puppet-lint/plugins/check_conditionals'
67
+ require 'puppet-lint/plugins/check_documentation'
68
+ require 'puppet-lint/plugins/check_strings'
69
+ require 'puppet-lint/plugins/check_variables'
70
+ require 'puppet-lint/plugins/check_whitespace'
71
+ require 'puppet-lint/plugins/check_resources'
72
+ require 'puppet-lint/plugins/check_nodes'
73
+
74
+ PuppetLint::Plugins.load_from_gems
@@ -0,0 +1,285 @@
1
+ # Public: Test the manifest tokens for any right-to-left (<-) chaining
2
+ # operators and record a warning for each instance found.
3
+ PuppetLint.new_check(:right_to_left_relationship) do
4
+ def check
5
+ tokens.select { |r| r.type == :OUT_EDGE }.each do |token|
6
+ notify :warning, {
7
+ :message => 'right-to-left (<-) relationship',
8
+ :line => token.line,
9
+ :column => token.column,
10
+ }
11
+ end
12
+ end
13
+ end
14
+
15
+ # Public: Test the manifest tokens for any classes or defined types that are
16
+ # not in an appropriately named file for the autoloader to detect and record
17
+ # an error of each instance found.
18
+ PuppetLint.new_check(:autoloader_layout) do
19
+ def check
20
+ unless fullpath.nil? || fullpath == ''
21
+ (class_indexes + defined_type_indexes).each do |class_idx|
22
+ title_token = class_idx[:name_token]
23
+ split_title = title_token.value.split('::')
24
+ mod = split_title.first
25
+ if split_title.length > 1
26
+ expected_path = "/#{mod}/manifests/#{split_title[1..-1].join('/')}.pp"
27
+ else
28
+ expected_path = "/#{title_token.value}/manifests/init.pp"
29
+ end
30
+
31
+ if PuppetLint.configuration.relative
32
+ expected_path = expected_path.gsub(/^\//,'').split('/')[1..-1].join('/')
33
+ end
34
+
35
+ unless fullpath.end_with? expected_path
36
+ notify :error, {
37
+ :message => "#{title_token.value} not in autoload module layout",
38
+ :line => title_token.line,
39
+ :column => title_token.column,
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # Public: Check the manifest tokens for any classes or defined types that
48
+ # have a dash in their name and record an error for each instance found.
49
+ PuppetLint.new_check(:names_containing_dash) do
50
+ def check
51
+ (class_indexes + defined_type_indexes).each do |class_idx|
52
+ if class_idx[:name_token].value.include? '-'
53
+ if class_idx[:type] == :CLASS
54
+ obj_type = 'class'
55
+ else
56
+ obj_type = 'defined type'
57
+ end
58
+
59
+ notify :error, {
60
+ :message => "#{obj_type} name containing a dash",
61
+ :line => class_idx[:name_token].line,
62
+ :column => class_idx[:name_token].column,
63
+ }
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ # Public: Check the manifest tokens for any classes that inherit a params
70
+ # subclass and record a warning for each instance found.
71
+ PuppetLint.new_check(:class_inherits_from_params_class) do
72
+ def check
73
+ class_indexes.each do |class_idx|
74
+ unless class_idx[:inherited_token].nil?
75
+ if class_idx[:inherited_token].value.end_with? '::params'
76
+ notify :warning, {
77
+ :message => 'class inheriting from params class',
78
+ :line => class_idx[:inherited_token].line,
79
+ :column => class_idx[:inherited_token].column,
80
+ }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ # Public: Test the manifest tokens for any parameterised classes or defined
88
+ # types that take parameters and record a warning if there are any optional
89
+ # parameters listed before required parameters.
90
+ PuppetLint.new_check(:parameter_order) do
91
+ def check
92
+ defined_type_indexes.each do |class_idx|
93
+ unless class_idx[:param_tokens].nil?
94
+ paren_stack = []
95
+ class_idx[:param_tokens].each_with_index do |token, i|
96
+ if token.type == :LPAREN
97
+ paren_stack.push(true)
98
+ elsif token.type == :RPAREN
99
+ paren_stack.pop
100
+ end
101
+ next unless paren_stack.empty?
102
+
103
+ if token.type == :VARIABLE
104
+ if token.next_code_token.nil? || [:COMMA, :RPAREN].include?(token.next_code_token.type)
105
+ prev_tokens = class_idx[:param_tokens][0..i]
106
+ unless prev_tokens.rindex { |r| r.type == :EQUALS }.nil?
107
+ unless token.prev_code_token.nil? or token.prev_code_token.type == :EQUALS
108
+ msg = 'optional parameter listed before required parameter'
109
+ notify :warning, {
110
+ :message => msg,
111
+ :line => token.line,
112
+ :column => token.column,
113
+ }
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ # Public: Test the manifest tokens for any classes that inherit across
125
+ # namespaces and record a warning for each instance found.
126
+ PuppetLint.new_check(:inherits_across_namespaces) do
127
+ def check
128
+ class_indexes.each do |class_idx|
129
+ unless class_idx[:inherited_token].nil?
130
+ inherited_module_name = class_idx[:inherited_token].value.split('::').reject { |r| r.empty? }.first
131
+ class_module_name = class_idx[:name_token].value.split('::').reject { |r| r.empty? }.first
132
+
133
+ unless class_module_name == inherited_module_name
134
+ notify :warning, {
135
+ :message => "class inherits across module namespaces",
136
+ :line => class_idx[:inherited_token].line,
137
+ :column => class_idx[:inherited_token].column,
138
+ }
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ # Public: Test the manifest tokens for any classes or defined types that are
146
+ # defined inside another class.
147
+ PuppetLint.new_check(:nested_classes_or_defines) do
148
+ TOKENS = Set[:CLASS, :DEFINE]
149
+
150
+ def check
151
+ class_indexes.each do |class_idx|
152
+ # Skip the first token so that we don't pick up the first :CLASS
153
+ class_tokens = class_idx[:tokens][1..-1]
154
+
155
+ class_tokens.each do |token|
156
+ if TOKENS.include?(token.type)
157
+ if token.next_code_token.type != :LBRACE
158
+ type = token.type == :CLASS ? 'class' : 'defined type'
159
+
160
+ notify :warning, {
161
+ :message => "#{type} defined inside a class",
162
+ :line => token.line,
163
+ :column => token.column,
164
+ }
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ # Public: Test the manifest tokens for any variables that are referenced in
173
+ # the manifest. If the variables are not fully qualified or one of the
174
+ # variables automatically created in the scope, check that they have been
175
+ # defined in the local scope and record a warning for each variable that has
176
+ # not.
177
+ PuppetLint.new_check(:variable_scope) do
178
+ DEFAULT_SCOPE_VARS = Set[
179
+ 'name',
180
+ 'title',
181
+ 'module_name',
182
+ 'environment',
183
+ 'clientcert',
184
+ 'clientversion',
185
+ 'servername',
186
+ 'serverip',
187
+ 'serverversion',
188
+ 'caller_module_name',
189
+ 'alias',
190
+ 'audit',
191
+ 'before',
192
+ 'loglevel',
193
+ 'noop',
194
+ 'notify',
195
+ 'require',
196
+ 'schedule',
197
+ 'stage',
198
+ 'subscribe',
199
+ 'tag',
200
+ ]
201
+ POST_VAR_TOKENS = Set[:COMMA, :EQUALS, :RPAREN]
202
+
203
+ def check
204
+ variables_in_scope = DEFAULT_SCOPE_VARS.clone
205
+
206
+ (class_indexes + defined_type_indexes).each do |idx|
207
+ referenced_variables = Set[]
208
+ object_tokens = idx[:tokens]
209
+
210
+ unless idx[:param_tokens].nil?
211
+ idx[:param_tokens].each do |token|
212
+ if token.type == :VARIABLE
213
+ if POST_VAR_TOKENS.include? token.next_code_token.type
214
+ variables_in_scope << token.value
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ future_parser_scopes = {}
221
+ in_pipe = false
222
+ temp_scope_vars = []
223
+
224
+ object_tokens.each do |token|
225
+ if token.type == :VARIABLE
226
+ if in_pipe
227
+ temp_scope_vars << token.value
228
+ else
229
+ if token.next_code_token.type == :EQUALS
230
+ variables_in_scope << token.value
231
+ else
232
+ referenced_variables << token
233
+ end
234
+ end
235
+ elsif token.type == :PIPE
236
+ in_pipe = !in_pipe
237
+
238
+ if in_pipe
239
+ temp_scope_vars = []
240
+ else
241
+ start_idx = tokens.find_index(token)
242
+ end_token = nil
243
+ brace_depth = 0
244
+
245
+ tokens[start_idx..-1].each do |sub_token|
246
+ case sub_token.type
247
+ when :LBRACE
248
+ brace_depth += 1
249
+ when :RBRACE
250
+ brace_depth -= 1
251
+ if brace_depth == 0
252
+ end_token = sub_token
253
+ break
254
+ end
255
+ end
256
+ end
257
+
258
+ future_parser_scopes.merge!(Hash[(token.line..end_token.line).to_a.map { |i| [i, temp_scope_vars] }])
259
+ end
260
+ end
261
+ end
262
+
263
+ msg = "top-scope variable being used without an explicit namespace"
264
+ referenced_variables.each do |token|
265
+ unless future_parser_scopes[token.line].nil?
266
+ next if future_parser_scopes[token.line].include?(token.value)
267
+ end
268
+
269
+ unless token.value.include? '::'
270
+ unless token.value =~ /^(facts|trusted)\[.+\]/
271
+ unless variables_in_scope.include? token.value.gsub(/\[.+\]\Z/, '')
272
+ unless token.value =~ /\A\d+\Z/
273
+ notify :warning, {
274
+ :message => msg,
275
+ :line => token.line,
276
+ :column => token.column,
277
+ }
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
285
+ end