Class: PuppetLint

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet-lint.rb,
lib/puppet-lint/lexer.rb,
lib/puppet-lint/plugins.rb,
lib/puppet-lint/version.rb,
lib/puppet-lint/lexer/token.rb,
lib/puppet-lint/configuration.rb,
lib/puppet-lint/tasks/puppet-lint.rb

Overview

Public: The public interface to puppet-lint.

Defined Under Namespace

Classes: Bin, CheckPlugin, Checks, Configuration, Data, Lexer, LexerError, NoCodeError, NoFix, OptParser, Plugins, RakeTask

Constant Summary collapse

VERSION =
'2.3.3'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePuppetLint

Public: Initialise a new PuppetLint object.



50
51
52
53
54
# File 'lib/puppet-lint.rb', line 50

def initialize
  @code = nil
  @statistics = { :error => 0, :warning => 0, :fixed => 0, :ignored => 0 }
  @manifest = ''
end

Instance Attribute Details

#codeObject

Public: Gets/Sets the String manifest code to be checked.



19
20
21
# File 'lib/puppet-lint.rb', line 19

def code
  @code
end

#manifestObject (readonly)

Public: Gets the String manifest with the errors fixed.



22
23
24
# File 'lib/puppet-lint.rb', line 22

def manifest
  @manifest
end

#pathObject

Public: Gets/Sets the String path to the manifest to be checked.



39
40
41
# File 'lib/puppet-lint.rb', line 39

def path
  @path
end

#problemsObject (readonly)

Public: Returns an Array of Hashes describing the problems found in the manifest.

Each Hash will contain *at least*:

:check   - The Symbol name of the check that generated the problem.
:kind    - The Symbol kind of the problem (:error, :warning, or
           :fixed).
:line    - The Integer line number of the location of the problem in
           the manifest.
:column  - The Integer column number of the location of the problem in
           the manifest.
:message - The String message describing the problem that was found.


36
37
38
# File 'lib/puppet-lint.rb', line 36

def problems
  @problems
end

#statisticsObject (readonly)

Public: Returns a Hash of linter statistics

:error   - An Integer count of errors found in the manifest.
:warning - An Integer count of warnings found in the manifest.
:fixed   - An Integer count of problems found in the manifest that were
           automatically fixed.


47
48
49
# File 'lib/puppet-lint.rb', line 47

def statistics
  @statistics
end

Class Method Details

.configurationObject

Public: Access PuppetLint’s configuration from outside the class.

Returns a PuppetLint::Configuration object.



59
60
61
# File 'lib/puppet-lint.rb', line 59

def self.configuration
  @configuration ||= PuppetLint::Configuration.new
end

.new_check(name, &block) ⇒ Object

Public: Define a new check.

name - A unique name for the check as a Symbol. block - The check logic. This must contain a ‘check` method and optionally

a `fix` method.

Returns nothing.

Examples

PuppetLint.new_check(:foo) do
  def check
  end
end


223
224
225
226
227
228
229
230
# File 'lib/puppet-lint.rb', line 223

def self.new_check(name, &block)
  class_name = name.to_s.split('_').map(&:capitalize).join
  klass = PuppetLint.const_set("Check#{class_name}", Class.new(PuppetLint::CheckPlugin))
  klass.const_set('NAME', name)
  klass.class_exec(&block)
  PuppetLint.configuration.add_check(name, klass)
  PuppetLint::Data.ignore_overrides[name] ||= {}
end

Instance Method Details

#configurationObject

Public: Access PuppetLint’s configuration from inside the class.

Returns a PuppetLint::Configuration object.



66
67
68
# File 'lib/puppet-lint.rb', line 66

def configuration
  self.class.configuration
end

#errors?Boolean

Public: Determine if PuppetLint found any errors in the manifest.

Returns true if errors were found, otherwise returns false.

Returns:

  • (Boolean)


170
171
172
# File 'lib/puppet-lint.rb', line 170

def errors?
  @statistics[:error] != 0
end

#file=(path) ⇒ Object

Public: Set the path of the manifest file to be tested and read the contents of the file.

Returns nothing.



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/puppet-lint.rb', line 74

def file=(path)
  return unless File.exist?(path)

  @path = path
  File.open(path, 'r:UTF-8') do |f|
    @code = f.read
  end

  # Check if the input is an SE Linux policy package file (which also use
  # the .pp extension), which all have the first 4 bytes 0xf97cff8f.
  @code = '' if @code[0..3].unpack('V').first == 0xf97cff8f
end

#format_message(message) ⇒ Object

Internal: Format a problem message and print it to STDOUT.

message - A Hash containing all the information about a problem.

Returns nothing.



108
109
110
111
112
113
# File 'lib/puppet-lint.rb', line 108

def format_message(message)
  format = log_format
  puts format % message

  puts "  #{message[:reason]}" if message[:kind] == :ignored && !message[:reason].nil?
end

#get_context(message) ⇒ Object

Internal: Get the line of the manifest on which the problem was found

message - A Hash containing all the information about a problem.

Returns the problematic line as a string.



120
121
122
# File 'lib/puppet-lint.rb', line 120

def get_context(message)
  PuppetLint::Data.manifest_lines[message[:line] - 1].strip
end

#log_formatObject

Internal: Retrieve the format string to be used when writing problems to STDOUT. If the user has not specified a custom log format, build one for them.

Returns a format String to be used with String#%.



92
93
94
95
96
97
98
99
100
101
# File 'lib/puppet-lint.rb', line 92

def log_format
  if configuration.log_format.nil? || configuration.log_format.empty?
    ## recreate previous old log format as far as thats possible.
    format = '%{KIND}: %{message} on line %{line}'
    format.prepend('%{path} - ') if configuration.with_filename
    configuration.log_format = format
  end

  configuration.log_format
end

Internal: Print out the line of the manifest on which the problem was found as well as a marker pointing to the location on the line.

message - A Hash containing all the information about a problem.

Returns nothing.



130
131
132
133
134
135
136
137
# File 'lib/puppet-lint.rb', line 130

def print_context(message)
  return if message[:check] == 'documentation'
  return if message[:kind] == :fixed
  line = get_context(message)
  offset = line.index(%r{\S}) || 1
  puts "\n  #{line.strip}"
  printf("%#{message[:column] + 2 - offset}s\n\n", '^')
end

Public: Print any problems that were found out to stdout.

Returns nothing.



205
206
207
# File 'lib/puppet-lint.rb', line 205

def print_problems
  report(@problems)
end

#report(problems) ⇒ Object

Internal: Print the reported problems with a manifest to stdout.

problems - An Array of problem Hashes as returned by

PuppetLint::Checks#run.

Returns nothing.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/puppet-lint.rb', line 145

def report(problems)
  json = []
  problems.each do |message|
    next if message[:kind] == :ignored && !PuppetLint.configuration.show_ignored

    message[:KIND] = message[:kind].to_s.upcase

    if message[:kind] == :fixed || [message[:kind], :all].include?(configuration.error_level)
      if configuration.json
        message['context'] = get_context(message) if configuration.with_context
        json << message
      else
        format_message(message)
        print_context(message) if configuration.with_context
      end
    end
  end
  puts JSON.pretty_generate(json) if configuration.json

  $stderr.puts 'Try running `puppet parser validate <file>`' if problems.any? { |p| p[:check] == :syntax }
end

#runObject

Public: Run the loaded manifest code through the lint checks and print the results of the checks to stdout.

Returns nothing. Raises PuppetLint::NoCodeError if no manifest code has been loaded.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/puppet-lint.rb', line 186

def run
  raise PuppetLint::NoCodeError if @code.nil?

  if @code.empty?
    @problems = []
    @manifest = ''
    return
  end

  linter = PuppetLint::Checks.new
  @problems = linter.run(@path, @code)
  @problems.each { |problem| @statistics[problem[:kind]] += 1 }

  @manifest = linter.manifest if PuppetLint.configuration.fix
end

#warnings?Boolean

Public: Determine if PuppetLint found any warnings in the manifest.

Returns true if warnings were found, otherwise returns false.

Returns:

  • (Boolean)


177
178
179
# File 'lib/puppet-lint.rb', line 177

def warnings?
  @statistics[:warning] != 0
end