class Pedant::CommandCheck

Public Class Methods

binding() click to toggle source
# File lib/pedant/commands/check.rb, line 31
def self.binding
  'check'
end
help() click to toggle source
# File lib/pedant/commands/check.rb, line 35
def self.help
  @@optparse.to_s
end
optparse(options, args) click to toggle source
# File lib/pedant/commands/check.rb, line 39
def self.optparse(options, args)
  options[:checks] = Set.new

  @@optparse = OptionParser.new do |opts|
    opts.banner = "Usage: pedant [global-options] #{binding} [command-options] [args]"

    opts.separator ""
    opts.separator "Input formats:"

    opts.on('-f', '--filesystem', 'Read input from the filesystem.') do
      options[:input_mode] = :filesystem
    end

    opts.on('-g', '--git', 'Read input from a Git repository.') do
      options[:input_mode] = :git
    end

    opts.separator ""
    opts.separator "Output formats:"

    opts.on('-e', '--email', 'Output in a form suitable for an email.') do
      options[:output_mode] = :email
    end

    opts.on('-t', '--terminal', 'Output in a form suitable for a terminal.') do
      options[:output_mode] = :terminal
    end

    opts.separator ""
    opts.separator "Common operations:"

    opts.on('-c=NAME', '--check=NAME', 'Run only the check named, and its dependencies.') do |name|
      # Unmangle class name and be very forgiving.
      name = "Check" + name.gsub(/[-._ ]/, '')

      begin
        cls = Pedant.const_get(name)
      rescue NameError => e
        usage(e.message)
      end

      ([cls] + cls.depends).each { |cls| options[:checks] << cls }
    end

    opts.on('-h', '--help', 'Display this help screen.') do
      puts opts
      exit 1
    end

    opts.on('-l', '--list', 'List the available checks.') do
      puts Check.list
      exit 0
    end

    opts.on('-q', '--quiet', "Only speak up when something should be fixed.") do
      options[:quiet] = true
    end

    opts.on('-v', '--verbose', 'Output more information, use multiple time to increase verbosity.') do
      options[:verbosity] += 1
    end
  end

  # Load all of the checks.
  Check.initialize!

  @@optparse.order!(args)

  return options, args
end
run_all(opts, args) click to toggle source
# File lib/pedant/commands/check.rb, line 110
def self.run_all(opts, args)
  # Separate plugins and libraries from the rest of the arguments.
  paths = args.select { |a| a =~ /(\/|\.(inc|nasl|pasl|tasl))$/ }
  args -= paths

  # If we have paths that aren't acceptable, there's a problem.
  usage("One or more unacceptable files were specified.") unless args.empty?

  # If we have no paths to process, there's a problem.
  usage("No directories (/), libraries (.inc), or plugins (.nasl) were specified.") if paths.empty?

  # Collect all the paths together, recursively.
  dirents = []
  paths.each do |path|
    begin
      Pathname.new(path).find do |dirent|
        if dirent.file? && dirent.extname =~ /inc|nasl|pasl|tasl/
          dirents << dirent
        end
      end
    rescue SystemCallError => e
      usage(e.message)
    end
  end

  dirents.each { |d| run_one(opts, d) }
end
run_one(opts, path) click to toggle source
# File lib/pedant/commands/check.rb, line 138
def self.run_one(opts, path)
  # Get a list of the checks we're going to be running.
  if not opts[:checks].empty?
    pending = opts[:checks].to_a
  else
    pending = Array.new(Check.all)
  end

  # Initialize the knowledge base where checks can store information for
  # other checks.
  kb = KnowledgeBase.new(:file_mode, path)

  run_checks = Check.run_checks_in_dependency_order(kb, pending)
  # When in quiet mode, only make a report for this file if a check did not pass
  return if opts[:quiet] && run_checks.all? { |chk| [:skip, :pass].include? chk.result }

  puts Rainbow("CHECKING: #{path}").cyan
  run_checks.each do |chk|
    next if [:skip, :pass].include?(chk.result) && opts[:quiet]
    puts chk.report(opts[:verbosity])
  end
  # Notify the user if any checks did not run due to unsatisfied
  # dependencies or a fatal error occurring before they had the chance to
  # run.
  pending.each do |cls|
    # Special case. This check is a shim to set things up for unit tests.
    next if cls == CheckParseTestCode
    puts cls.new(kb).report(opts[:verbosity])
  end
  puts
end