puppet-lint-halyard 1.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +210 -0
- data/Rakefile +14 -0
- data/bin/puppet-lint +7 -0
- data/lib/puppet-lint.rb +214 -0
- data/lib/puppet-lint/bin.rb +79 -0
- data/lib/puppet-lint/checkplugin.rb +176 -0
- data/lib/puppet-lint/checks.rb +91 -0
- data/lib/puppet-lint/configuration.rb +153 -0
- data/lib/puppet-lint/data.rb +521 -0
- data/lib/puppet-lint/lexer.rb +373 -0
- data/lib/puppet-lint/lexer/token.rb +101 -0
- data/lib/puppet-lint/monkeypatches.rb +2 -0
- data/lib/puppet-lint/monkeypatches/string_percent.rb +52 -0
- data/lib/puppet-lint/monkeypatches/string_prepend.rb +13 -0
- data/lib/puppet-lint/optparser.rb +118 -0
- data/lib/puppet-lint/plugins.rb +74 -0
- data/lib/puppet-lint/plugins/check_classes.rb +285 -0
- data/lib/puppet-lint/plugins/check_comments.rb +55 -0
- data/lib/puppet-lint/plugins/check_conditionals.rb +65 -0
- data/lib/puppet-lint/plugins/check_documentation.rb +31 -0
- data/lib/puppet-lint/plugins/check_nodes.rb +29 -0
- data/lib/puppet-lint/plugins/check_resources.rb +194 -0
- data/lib/puppet-lint/plugins/check_strings.rb +174 -0
- data/lib/puppet-lint/plugins/check_variables.rb +19 -0
- data/lib/puppet-lint/plugins/check_whitespace.rb +170 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +91 -0
- data/lib/puppet-lint/version.rb +3 -0
- data/puppet-lint.gemspec +24 -0
- data/spec/fixtures/test/manifests/fail.pp +2 -0
- data/spec/fixtures/test/manifests/ignore.pp +1 -0
- data/spec/fixtures/test/manifests/ignore_multiple_block.pp +6 -0
- data/spec/fixtures/test/manifests/ignore_multiple_line.pp +2 -0
- data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
- data/spec/fixtures/test/manifests/init.pp +3 -0
- data/spec/fixtures/test/manifests/malformed.pp +1 -0
- data/spec/fixtures/test/manifests/url_interpolation.pp +12 -0
- data/spec/fixtures/test/manifests/warning.pp +2 -0
- data/spec/puppet-lint/bin_spec.rb +326 -0
- data/spec/puppet-lint/configuration_spec.rb +56 -0
- data/spec/puppet-lint/ignore_overrides_spec.rb +109 -0
- data/spec/puppet-lint/lexer/token_spec.rb +18 -0
- data/spec/puppet-lint/lexer_spec.rb +783 -0
- data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +105 -0
- data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +35 -0
- data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +33 -0
- data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +76 -0
- data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +25 -0
- data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +196 -0
- data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +84 -0
- data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +98 -0
- data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +52 -0
- data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +146 -0
- data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +100 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +55 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +89 -0
- data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +113 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +216 -0
- data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +199 -0
- data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +114 -0
- data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +62 -0
- data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +129 -0
- data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +17 -0
- data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +21 -0
- data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +54 -0
- data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +524 -0
- data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +101 -0
- data/spec/puppet-lint_spec.rb +20 -0
- data/spec/spec_helper.rb +129 -0
- metadata +229 -0
@@ -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
|