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.
- 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
|