puppet-lint 0.1.13 → 0.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/README.md +19 -5
- data/bin/puppet-lint +2 -0
- data/lib/puppet-lint.rb +2 -11
- data/lib/puppet-lint/configuration.rb +4 -0
- data/lib/puppet-lint/lexer.rb +244 -0
- data/lib/puppet-lint/plugin.rb +125 -54
- data/lib/puppet-lint/plugins/check_classes.rb +135 -49
- data/lib/puppet-lint/plugins/check_conditionals.rb +34 -23
- data/lib/puppet-lint/plugins/check_resources.rb +114 -28
- data/lib/puppet-lint/plugins/check_strings.rb +67 -79
- data/lib/puppet-lint/plugins/check_variables.rb +13 -18
- data/lib/puppet-lint/plugins/check_whitespace.rb +70 -40
- data/lib/puppet-lint/tasks/puppet-lint.rb +11 -3
- data/lib/puppet-lint/version.rb +3 -0
- data/puppet-lint.gemspec +8 -29
- data/spec/puppet-lint/check_classes_spec.rb +72 -23
- data/spec/puppet-lint/check_conditionals_spec.rb +19 -3
- data/spec/puppet-lint/check_resources_spec.rb +9 -16
- data/spec/puppet-lint/check_strings_spec.rb +94 -7
- data/spec/puppet-lint/check_variables_spec.rb +20 -10
- data/spec/puppet-lint/check_whitespace_spec.rb +13 -0
- data/spec/spec_helper.rb +15 -10
- metadata +30 -17
@@ -1,106 +1,94 @@
|
|
1
1
|
class PuppetLint::Plugins::CheckStrings < PuppetLint::CheckPlugin
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
TOKENS.add_tokens("<single quotes string>" => :SSTRING)
|
10
|
-
TOKENS.del_token(:SQUOTE)
|
11
|
-
|
12
|
-
if Puppet::PUPPETVERSION =~ /^0\.2/
|
13
|
-
TOKENS.add_token :SQUOTE, "'" do |lexer, value|
|
14
|
-
value = lexer.slurpstring(value)
|
15
|
-
[TOKENS[:SSTRING], value]
|
16
|
-
end
|
17
|
-
else
|
18
|
-
TOKENS.add_token :SQUOTE, "'" do |lexer, value|
|
19
|
-
[ TOKENS[:SSTRING], lexer.slurpstring(value,["'"],:ignore_invalid_escapes).first ]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
2
|
+
# Public: Check the manifest tokens for any double quoted strings that don't
|
3
|
+
# contain any variables or common escape characters and record a warning for
|
4
|
+
# each instance found.
|
5
|
+
#
|
6
|
+
# Returns nothing.
|
24
7
|
check 'double_quoted_strings' do
|
25
|
-
tokens.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
8
|
+
tokens.select { |r|
|
9
|
+
r.type == :STRING
|
10
|
+
}.reject { |r|
|
11
|
+
r.value.include?('\t') || r.value.include?('\n')
|
12
|
+
}.each do |token|
|
13
|
+
notify :warning, {
|
14
|
+
:message => 'double quoted string containing no variables',
|
15
|
+
:linenumber => token.line,
|
16
|
+
:column => token.column,
|
17
|
+
}
|
37
18
|
end
|
38
19
|
end
|
39
20
|
|
21
|
+
# Public: Check the manifest tokens for double quoted strings that contain
|
22
|
+
# a single variable only and record a warning for each instance found.
|
23
|
+
#
|
24
|
+
# Returns nothing.
|
40
25
|
check 'only_variable_string' do
|
41
26
|
tokens.each_index do |token_idx|
|
42
27
|
token = tokens[token_idx]
|
43
28
|
|
44
|
-
if token.
|
45
|
-
if tokens[token_idx + 1].
|
46
|
-
if tokens[token_idx + 2].
|
47
|
-
|
29
|
+
if token.type == :DQPRE and token.value == ''
|
30
|
+
if [:VARIABLE, :UNENC_VARIABLE].include? tokens[token_idx + 1].type
|
31
|
+
if tokens[token_idx + 2].type == :DQPOST
|
32
|
+
if tokens[token_idx + 2].value == ''
|
33
|
+
notify :warning, {
|
34
|
+
:message => 'string containing only a variable',
|
35
|
+
:linenumber => tokens[token_idx + 1].line,
|
36
|
+
:column => tokens[token_idx + 1].column,
|
37
|
+
}
|
38
|
+
end
|
48
39
|
end
|
49
40
|
end
|
50
41
|
end
|
51
|
-
if token.first == :DQTEXT and token.last[:value] =~ /\A\$\{.+\}\Z/
|
52
|
-
notify :warning, :message => "string containing only a variable", :linenumber => token.last[:line]
|
53
|
-
end
|
54
42
|
end
|
55
43
|
end
|
56
44
|
|
45
|
+
# Public: Check the manifest tokens for any variables in a string that have
|
46
|
+
# not been enclosed by braces ({}) and record a warning for each instance
|
47
|
+
# found.
|
48
|
+
#
|
49
|
+
# Returns nothing.
|
57
50
|
check 'variables_not_enclosed' do
|
58
|
-
tokens.
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if line.is_a? String and line.include? "$#{t.last[:value]}"
|
67
|
-
notify :warning, :message => "variable not enclosed in {}", :linenumber => t.last[:line]
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
elsif token.first == :DQTEXT and token.last[:value] =~ /\$\w+/
|
72
|
-
notify :warning, :message => "variable not enclosed in {}", :linenumber => token.last[:line]
|
73
|
-
end
|
51
|
+
tokens.select { |r|
|
52
|
+
r.type == :UNENC_VARIABLE
|
53
|
+
}.each do |token|
|
54
|
+
notify :warning, {
|
55
|
+
:message => 'variable not enclosed in {}',
|
56
|
+
:linenumber => token.line,
|
57
|
+
:column => token.column,
|
58
|
+
}
|
74
59
|
end
|
75
60
|
end
|
76
61
|
|
62
|
+
# Public: Check the manifest tokens for any single quoted strings containing
|
63
|
+
# a enclosed variable and record an error for each instance found.
|
64
|
+
#
|
65
|
+
# Returns nothing.
|
77
66
|
check 'single_quote_string_with_variables' do
|
78
|
-
tokens.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
notify :error, :message => "single quoted string containing a variable found", :linenumber => token.last[:line]
|
87
|
-
end
|
88
|
-
end
|
67
|
+
tokens.select { |r|
|
68
|
+
r.type == :SSTRING && r.value.include?('${')
|
69
|
+
}.each do |token|
|
70
|
+
notify :error, {
|
71
|
+
:message => 'single quoted string containing a variable found',
|
72
|
+
:linenumber => token.line,
|
73
|
+
:column => token.column,
|
74
|
+
}
|
89
75
|
end
|
90
76
|
end
|
91
77
|
|
78
|
+
# Public: Check the manifest tokens for any double or single quoted strings
|
79
|
+
# containing only a boolean value and record a warning for each instance
|
80
|
+
# found.
|
81
|
+
#
|
82
|
+
# Returns nothing.
|
92
83
|
check 'quoted_booleans' do
|
93
|
-
tokens.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
notify :warning, :message => "quoted boolean value found", :linenumber => token.last[:line]
|
102
|
-
end
|
103
|
-
end
|
84
|
+
tokens.select { |r|
|
85
|
+
[:STRING, :SSTRING].include?(r.type) && %w{true false}.include?(r.value)
|
86
|
+
}.each do |token|
|
87
|
+
notify :warning, {
|
88
|
+
:message => 'quoted boolean value found',
|
89
|
+
:linenumber => token.line,
|
90
|
+
:column => token.column,
|
91
|
+
}
|
104
92
|
end
|
105
93
|
end
|
106
94
|
end
|
@@ -1,23 +1,18 @@
|
|
1
1
|
class PuppetLint::Plugins::CheckVariables < PuppetLint::CheckPlugin
|
2
|
+
# Public: Test the manifest tokens for variables that contain a dash and
|
3
|
+
# record a warning for each instance found.
|
4
|
+
#
|
5
|
+
# Returns nothing.
|
2
6
|
check 'variable_contains_dash' do
|
3
|
-
tokens.
|
4
|
-
|
5
|
-
|
6
|
-
if token.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
if token.first == :DQPRE
|
15
|
-
end_of_string_idx = tokens[token_idx..-1].index { |r| r.first == :DQPOST }
|
16
|
-
tokens[token_idx..end_of_string_idx].each do |t|
|
17
|
-
if t.first == :VARIABLE and t.last[:value].match(/-/)
|
18
|
-
notify :warning, :message => "variable contains a dash", :linenumber => t.last[:line]
|
19
|
-
end
|
20
|
-
end
|
7
|
+
tokens.select { |r|
|
8
|
+
[:VARIABLE, :UNENC_VARIABLE].include? r.type
|
9
|
+
}.each do |token|
|
10
|
+
if token.value.match(/-/)
|
11
|
+
notify :warning, {
|
12
|
+
:message => 'variable contains a dash',
|
13
|
+
:linenumber => token.line,
|
14
|
+
:column => token.column,
|
15
|
+
}
|
21
16
|
end
|
22
17
|
end
|
23
18
|
end
|
@@ -1,61 +1,83 @@
|
|
1
|
-
# Spacing, Identation & Whitespace
|
2
|
-
# http://docs.puppetlabs.com/guides/style_guide.html#spacing-indentation--whitespace
|
3
|
-
|
4
1
|
class PuppetLint::Plugins::CheckWhitespace < PuppetLint::CheckPlugin
|
2
|
+
# Check the raw manifest string for lines containing hard tab characters and
|
3
|
+
# record an error for each instance found.
|
4
|
+
#
|
5
|
+
# Returns nothing.
|
5
6
|
check 'hard_tabs' do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
manifest_lines.each_with_index do |line, idx|
|
8
|
+
if line.include? "\t"
|
9
|
+
notify :error, {
|
10
|
+
:message => 'tab character found',
|
11
|
+
:linenumber => idx + 1,
|
12
|
+
:column => line.index("\t") + 1,
|
13
|
+
}
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
18
|
+
# Check the raw manifest string for lines ending with whitespace and record
|
19
|
+
# an error for each instance found.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
15
22
|
check 'trailing_whitespace' do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
manifest_lines.each_with_index do |line, idx|
|
24
|
+
if line.end_with? ' '
|
25
|
+
notify :error, {
|
26
|
+
:message => 'trailing whitespace found',
|
27
|
+
:linenumber => idx + 1,
|
28
|
+
:column => line.rindex(' ') + 1,
|
29
|
+
}
|
30
|
+
end
|
22
31
|
end
|
23
32
|
end
|
24
33
|
|
34
|
+
# Test the raw manifest string for lines containing more than 80 characters
|
35
|
+
# and record a warning for each instance found. The only exception to this
|
36
|
+
# rule is lines containing puppet:// URLs which would hurt readability if
|
37
|
+
# split.
|
38
|
+
#
|
39
|
+
# Returns nothing.
|
25
40
|
check '80chars' do
|
26
|
-
|
27
|
-
manifest_lines.each do |line|
|
28
|
-
line_no += 1
|
29
|
-
|
30
|
-
# SHOULD NOT exceed an 80 character line width
|
41
|
+
manifest_lines.each_with_index do |line, idx|
|
31
42
|
unless line =~ /puppet:\/\//
|
32
|
-
|
43
|
+
if line.scan(/./mu).size > 80
|
44
|
+
notify :warning, {
|
45
|
+
:message => 'line has more than 80 characters',
|
46
|
+
:linenumber => idx + 1,
|
47
|
+
:column => 80,
|
48
|
+
}
|
49
|
+
end
|
33
50
|
end
|
34
51
|
end
|
35
52
|
end
|
36
53
|
|
54
|
+
# Check the manifest tokens for any indentation not using 2 space soft tabs
|
55
|
+
# and record an error for each instance found.
|
56
|
+
#
|
57
|
+
# Returns nothing.
|
37
58
|
check '2sp_soft_tabs' do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
59
|
+
tokens.select { |r|
|
60
|
+
r.type == :INDENT
|
61
|
+
}.reject { |r|
|
62
|
+
r.value.length % 2 == 0
|
63
|
+
}.each do |token|
|
64
|
+
notify :error, {
|
65
|
+
:message => 'two-space soft tabs not used',
|
66
|
+
:linenumber => token.line,
|
67
|
+
:column => token.column,
|
68
|
+
}
|
48
69
|
end
|
49
70
|
end
|
50
71
|
|
72
|
+
# Check the raw manifest strings for any arrows (=>) in a grouping ({}) that
|
73
|
+
# are not aligned with other arrows in that grouping.
|
74
|
+
#
|
75
|
+
# Returns nothing.
|
51
76
|
check 'arrow_alignment' do
|
52
|
-
line_no = 0
|
53
77
|
in_resource = false
|
54
78
|
selectors = []
|
55
79
|
resource_indent_length = 0
|
56
|
-
manifest_lines.
|
57
|
-
line_no += 1
|
58
|
-
|
80
|
+
manifest_lines.each_with_index do |line, idx|
|
59
81
|
# SHOULD align fat comma arrows (=>) within blocks of attributes
|
60
82
|
if line =~ /^( +.+? +)=>/
|
61
83
|
line_indent = $1
|
@@ -67,28 +89,36 @@ class PuppetLint::Plugins::CheckWhitespace < PuppetLint::CheckPlugin
|
|
67
89
|
|
68
90
|
# check for length first
|
69
91
|
unless line_indent.length == selectors.last
|
70
|
-
notify :warning,
|
92
|
+
notify :warning, {
|
93
|
+
:message => '=> is not properly aligned for selector',
|
94
|
+
:linenumber => idx + 1,
|
95
|
+
:column => line_indent.length,
|
96
|
+
}
|
71
97
|
end
|
72
98
|
|
73
99
|
# then for a new selector or selector finish
|
74
|
-
if line.strip.end_with?
|
100
|
+
if line.strip.end_with? '{'
|
75
101
|
selectors.push(0)
|
76
102
|
elsif line.strip =~ /\}[,;]?$/
|
77
103
|
selectors.pop
|
78
104
|
end
|
79
105
|
else
|
80
106
|
unless line_indent.length == resource_indent_length
|
81
|
-
notify :warning,
|
107
|
+
notify :warning, {
|
108
|
+
:message => '=> is not properly aligned for resource',
|
109
|
+
:linenumber => idx + 1,
|
110
|
+
:column => line_indent.length,
|
111
|
+
}
|
82
112
|
end
|
83
113
|
|
84
|
-
if line.strip.end_with?
|
114
|
+
if line.strip.end_with? '{'
|
85
115
|
selectors.push(0)
|
86
116
|
end
|
87
117
|
end
|
88
118
|
else
|
89
119
|
resource_indent_length = line_indent.length
|
90
120
|
in_resource = true
|
91
|
-
if line.strip.end_with?
|
121
|
+
if line.strip.end_with? '{'
|
92
122
|
selectors.push(0)
|
93
123
|
end
|
94
124
|
end
|
@@ -9,13 +9,21 @@ class PuppetLint
|
|
9
9
|
|
10
10
|
task :lint do
|
11
11
|
RakeFileUtils.send(:verbose, true) do
|
12
|
-
linter =
|
13
|
-
|
12
|
+
linter = PuppetLint.new
|
13
|
+
matched_files = FileList['**/*.pp']
|
14
|
+
|
15
|
+
if ignore_paths = PuppetLint.configuration.ignore_paths
|
16
|
+
matched_files = matched_files.exclude(*ignore_paths)
|
17
|
+
end
|
18
|
+
|
19
|
+
matched_files.to_a.each do |puppet_file|
|
14
20
|
puts "Evaluating #{puppet_file}"
|
15
21
|
linter.file = puppet_file
|
16
22
|
linter.run
|
17
23
|
end
|
18
|
-
fail if linter.errors?
|
24
|
+
fail if linter.errors? || (
|
25
|
+
linter.warnings? && PuppetLint.configuration.fail_on_warnings
|
26
|
+
)
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
data/puppet-lint.gemspec
CHANGED
@@ -1,39 +1,18 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'puppet-lint/version'
|
3
|
+
|
1
4
|
Gem::Specification.new do |s|
|
2
5
|
s.name = 'puppet-lint'
|
3
|
-
s.version =
|
6
|
+
s.version = PuppetLint::VERSION
|
4
7
|
s.homepage = 'https://github.com/rodjek/puppet-lint/'
|
5
8
|
s.summary = 'Ensure your Puppet manifests conform with the Puppetlabs style guide'
|
6
9
|
s.description = 'Checks your Puppet manifests against the Puppetlabs
|
7
10
|
style guide and alerts you to any discrepancies.'
|
8
11
|
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
|
12
|
-
|
13
|
-
'Gemfile',
|
14
|
-
'lib/puppet-lint/configuration.rb',
|
15
|
-
'lib/puppet-lint/plugin.rb',
|
16
|
-
'lib/puppet-lint/plugins/check_classes.rb',
|
17
|
-
'lib/puppet-lint/plugins/check_conditionals.rb',
|
18
|
-
'lib/puppet-lint/plugins/check_resources.rb',
|
19
|
-
'lib/puppet-lint/plugins/check_strings.rb',
|
20
|
-
'lib/puppet-lint/plugins/check_variables.rb',
|
21
|
-
'lib/puppet-lint/plugins/check_whitespace.rb',
|
22
|
-
'lib/puppet-lint/plugins.rb',
|
23
|
-
'lib/puppet-lint/tasks/puppet-lint.rb',
|
24
|
-
'lib/puppet-lint.rb',
|
25
|
-
'LICENSE',
|
26
|
-
'puppet-lint.gemspec',
|
27
|
-
'Rakefile',
|
28
|
-
'README.md',
|
29
|
-
'spec/puppet-lint/check_classes_spec.rb',
|
30
|
-
'spec/puppet-lint/check_conditionals_spec.rb',
|
31
|
-
'spec/puppet-lint/check_resources_spec.rb',
|
32
|
-
'spec/puppet-lint/check_strings_spec.rb',
|
33
|
-
'spec/puppet-lint/check_variables_spec.rb',
|
34
|
-
'spec/puppet-lint/check_whitespace_spec.rb',
|
35
|
-
'spec/spec_helper.rb',
|
36
|
-
]
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
s.require_paths = ["lib"]
|
37
16
|
|
38
17
|
s.add_development_dependency 'rspec'
|
39
18
|
s.add_development_dependency 'rdoc'
|