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