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,
lib/puppet-lint/lexer/string_slurper.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, SyntaxError

Constant Summary collapse

VERSION =
'2.4.2'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePuppetLint

Public: Initialise a new PuppetLint object.



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

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.



28
29
30
# File 'lib/puppet-lint.rb', line 28

def code
  @code
end

#manifestObject (readonly)

Public: Gets the String manifest with the errors fixed.



31
32
33
# File 'lib/puppet-lint.rb', line 31

def manifest
  @manifest
end

#pathObject

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



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

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.


45
46
47
# File 'lib/puppet-lint.rb', line 45

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.


56
57
58
# File 'lib/puppet-lint.rb', line 56

def statistics
  @statistics
end

Class Method Details

.configurationObject

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

Returns a PuppetLint::Configuration object.



68
69
70
# File 'lib/puppet-lint.rb', line 68

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


232
233
234
235
236
237
238
239
# File 'lib/puppet-lint.rb', line 232

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.



75
76
77
# File 'lib/puppet-lint.rb', line 75

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)


179
180
181
# File 'lib/puppet-lint.rb', line 179

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.



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/puppet-lint.rb', line 83

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

  @path = path
  File.open(path, 'rb: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.



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

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.



129
130
131
# File 'lib/puppet-lint.rb', line 129

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#%.



101
102
103
104
105
106
107
108
109
110
# File 'lib/puppet-lint.rb', line 101

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.



139
140
141
142
143
144
145
146
# File 'lib/puppet-lint.rb', line 139

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.



214
215
216
# File 'lib/puppet-lint.rb', line 214

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.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/puppet-lint.rb', line 154

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.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/puppet-lint.rb', line 195

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)


186
187
188
# File 'lib/puppet-lint.rb', line 186

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