puppet-lint 0.1.13 → 0.2.0.pre1
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.
- 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'
|