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.
@@ -1,106 +1,94 @@
1
1
  class PuppetLint::Plugins::CheckStrings < PuppetLint::CheckPlugin
2
- class ::Puppet::Parser::Lexer
3
- class TokenList
4
- def del_token(token)
5
- @tokens.delete(token)
6
- end
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.each_index do |token_idx|
26
- token = tokens[token_idx]
27
-
28
- if token.first == :STRING
29
- unless token.last[:value].include? "\t" or token.last[:value].include? "\n"
30
- notify :warning, :message => "double quoted string containing no variables", :linenumber => token.last[:line]
31
- end
32
- elsif token.first == :DQTEXT
33
- unless token.last[:value].include? "\\t" or token.last[:value].include? "\\n" or token.last[:value] =~ /[^\\]?\$\{?/
34
- notify :warning, :message => "double quoted string containing no variables", :linenumber => token.last[:line]
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.first == :DQPRE and token.last[:value] == ""
45
- if tokens[token_idx + 1].first == :VARIABLE
46
- if tokens[token_idx + 2].first == :DQPOST and tokens[token_idx + 2].last[:value] == ""
47
- notify :warning, :message => "string containing only a variable", :linenumber => tokens[token_idx + 1].last[:line]
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.each_index do |token_idx|
59
- token = tokens[token_idx]
60
-
61
- if token.first == :DQPRE
62
- end_of_string_idx = tokens[token_idx..-1].index { |r| r.first == :DQPOST }
63
- tokens[token_idx..end_of_string_idx].each do |t|
64
- if t.first == :VARIABLE
65
- line = data.split("\n")[t.last[:line] - 1]
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.each_index do |token_idx|
79
- token = tokens[token_idx]
80
-
81
- if token.first == :SSTRING
82
- contents = token.last[:value]
83
- line_no = token.last[:line]
84
-
85
- if contents.include? '${'
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.each_index do |token_idx|
94
- token = tokens[token_idx]
95
-
96
- if token.first == :SSTRING
97
- contents = token.last[:value]
98
- line_no = token.last[:line]
99
-
100
- if ['true', 'false'].include? contents
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.each_index do |token_idx|
4
- token = tokens[token_idx]
5
-
6
- if token.first == :VARIABLE
7
- variable = token.last[:value]
8
- line_no = token.last[:line]
9
- if variable.match(/-/)
10
- notify :warning, :message => "variable contains a dash", :linenumber => line_no
11
- end
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
- line_no = 0
7
- manifest_lines.each do |line|
8
- line_no += 1
9
-
10
- # MUST NOT use literal tab characters
11
- notify :error, :message => "tab character found", :linenumber => line_no if line.include? "\t"
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
- line_no = 0
17
- manifest_lines.each do |line|
18
- line_no += 1
19
-
20
- # MUST NOT contain trailing white space
21
- notify :error, :message => "trailing whitespace found", :linenumber => line_no if line.end_with? " "
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
- line_no = 0
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
- notify :warning, :message => "line has more than 80 characters", :linenumber => line_no if line.length > 80
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
- line_no = 0
39
- manifest_lines.each do |line|
40
- line_no += 1
41
-
42
- # MUST use two-space soft tabs
43
- line.scan(/^ +/) do |prefix|
44
- unless prefix.length % 2 == 0
45
- notify :error, :message => "two-space soft tabs not used", :linenumber => line_no
46
- end
47
- end
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.each do |line|
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, :message => "=> on line isn't properly aligned for selector", :linenumber => line_no
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, :message => "=> on line isn't properly aligned for resource", :linenumber => line_no
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 = PuppetLint.new
13
- Dir.glob('**/*.pp').each do |puppet_file|
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
@@ -0,0 +1,3 @@
1
+ class PuppetLint
2
+ VERSION = '0.2.0.pre1'
3
+ 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 = '0.1.13'
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.executables = ['puppet-lint']
10
- s.files = [
11
- '.travis.yml',
12
- 'bin/puppet-lint',
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'