Skip to content

Instantly share code, notes, and snippets.

@acidprime
Created September 3, 2014 22:42
Show Gist options
  • Save acidprime/63fd049ce570b455cde1 to your computer and use it in GitHub Desktop.
Save acidprime/63fd049ce570b455cde1 to your computer and use it in GitHub Desktop.
This was pretty dirty but got the job done
#!/usr/bin/ruby
require 'rubygems'
require 'lint-report'
require 'json'
def sort_checks(breakdown)
result = breakdown.collect do |hash|
hash.collect do |name,checks|
result = Hash.new(0)
checks.each do |check|
result[check] += 1
end
sorted = result.collect{|k,v| Hash[ :check => k, :number => v]}.sort_by{|h| h[:number] }.reverse
Hash[ name.to_sym => sorted ]
end
end.flatten
result
end
manifests = Dir.glob("**/*.pp")
scan = {}
report = {}
# Sort by the files with the most lines of code
scan[:manifests] = manifests.map do |manifest|
line_count = `wc -l #{manifest}`
module_name = manifest.split("/").first
report[module_name.to_sym] = {}
Hash[:path => manifest,:line => line_count[/\d+/], :module_name => module_name]
end.sort_by {|k| k[:line].to_i}.reverse
scan[:manifests].each do |manifest|
module_name = manifest[:module_name]
module_report = report[module_name.to_sym]
puts "Processing #{manifest[:path]}"
found = open(manifest[:path]) { |f| f.grep(/^import/) }
( module_report[:imports] ||= []) << Hash[:file => manifest[:path], :import => found] unless found.empty?
lint = PuppetLintReport.new
lint.file = (manifest[:path])
lint.run
if lint.errors?
errors = lint.problems.select{|problem| problem[:kind] == :error }
( module_report[:errors] ||= [] ) << errors
module_report[:errors].flatten!
end
if lint.warnings?
warnings = lint.problems.select{|problem| problem[:kind] == :warning }
( module_report[:warnings] ||= [] ) << warnings
module_report[:warnings].flatten!
end
end
errors_total = report.select do |name,hash|
hash.has_key?(:errors)
end.collect{ |name,hash| Hash[:name => name , :lint_total => hash[:errors].size] }.compact.sort_by {|modules| modules[:lint_total]}.map.reverse
warnings_total = report.select do |name,hash|
hash.has_key?(:warnings)
end.collect{ |name,hash| Hash[:name => name , :lint_total => hash[:warnings].size] }.compact.sort_by {|modules| modules[:lint_total]}.map.reverse
warnings_breakdown = report.select do |name,hash|
hash.has_key?(:warnings)
end.collect do |name,hash|
results = {}
hash[:warnings].each do |warning|
(results[name] ||= []) << warning[:check]
end
results
end
errors_breakdown = report.select do |name,hash|
hash.has_key?(:errors)
end.collect do |name,hash|
results = {}
hash[:errors].each do |error|
(results[name] ||= []) << error[:check]
end
results
end
output = {}
errors_breakdown_sorted = sort_checks(errors_breakdown)
errors_final = errors_total.collect do |modules|
module_name = modules[:name]
module_breakdown = errors_breakdown_sorted.find {|hash| hash.keys.first == module_name }
Hash[ :name => module_name, :lint_total => modules[:lint_total], :breakdown => module_breakdown[module_name]]
end
warnings_breakdown_sorted = sort_checks(warnings_breakdown)
warnings_final = warnings_total.collect do |modules|
module_name = modules[:name]
module_breakdown = warnings_breakdown_sorted.find {|hash| hash.keys.first == module_name }
Hash[ :name => module_name, :lint_total => modules[:lint_total], :breakdown => module_breakdown[module_name]]
end
output[:scan] = scan
output[:details] = report
output[:errors_final] = errors_final
output[:warnings_final] = warnings_final
File.open("REPORT.json","w") do |f|
f.write(output.to_json)
end
@acidprime
Copy link
Author

This is the subclass i.e. lint-report.rb

require 'rubygems'
require 'puppet-lint'

class PuppetLintReport < PuppetLint
  attr_accessor :problems
  attr_accessor :statistics
end

@acidprime
Copy link
Author

Once I had the raw data I fed it through an ERB to make it pretty

Rakefile

require 'erb'
require 'json'
require 'rubygems'
require 'github/markup'

desc "Build final report"
task :build do
  @nodes = load_json("REPORT.json")
  build_file("output.md")
  GitHub::Markup.render("output.md")
end

def load_json(filename)
  cputs "Loading json file #{filename}"
  JSON.parse( IO.read(filename) )
end

def build_file(filename)
  template_path = "template.erb"
  target_dir = "."
  target_path = "#{target_dir}/#{filename}"
  FileUtils.mkdir(target_dir) unless File.directory?(target_dir)
  if File.file?(template_path)
    cputs "Building #{target_path}..."
    File.open(target_path,'w') do |f|
      template_content = ERB.new(File.read(template_path)).result
      f.write(template_content)
    end
  else
    cputs "No source template found: #{template_path}"
  end
end

def cputs(string)
  puts "\033[1m#{string}\033[0m"
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment