#!/usr/local/bin/ruby require 'rubygems' require_gem 'ikko' require 'yaml' require '/home/tom/rubyforge/ruby-doom/trunk/ruby-doom/lib/doom.rb' # add timeout thingy to the Thread class, thx to Rich Kilmer for the code class MyThread < Thread def MyThread.ttl=(timeout) Thread.new(Thread.current) do |thread| sleep timeout if thread.alive? thread.exit end end end end class PMDMap MIN_NOOKS = 2 MAX_NOOKS = 12 def initialize(problems) @problems = problems end def nooks if @problems < MIN_NOOKS return MIN_NOOKS elsif @problems > 100 return MAX_NOOKS end (@problems/10).to_i + MIN_NOOKS end end class SFCVSROOTPattern def munge(name) ":pserver:anonymous@#{name}.cvs.sourceforge.net:/cvsroot/#{name}" end end class Job JAVANCSS_BINARY="/usr/local/javancss/bin/javancss" ROOT="/home/tom/pmd/pmd-web/src" REMOTE_REPORT_DIR="/home/groups/p/pm/pmd/htdocs/reports/" attr_reader :unix_name, :mod, :title, :src attr_accessor :barrels def initialize(title, data) @title, @unix_name, @mod, @src, @cvsroot = title, data["unix_name"], data["module"], data["srcdir"] @cvsroot = SFCVSROOTPattern.new.munge(@unix_name) @data = data end def jdk15? @data["jdk15"] == true end def checkout_code t = MyThread.new { MyThread.ttl = 120 cmd = "cvs -Q -d#{@cvsroot} export -D tomorrow \"#{@src}\"" puts cmd `#{cmd}` } t.join if @data["delete"] && File.exist?(@data["delete"]) `rm -rf #{@data["delete"]}` end end def run_ncss cmd="#{JAVANCSS_BINARY} -ncss -recursive \"#{@src}\" > \"#{ncss_report}\"" `#{cmd}` end def run_pmd cmd="java -Xmx512m -cp /home/tom/pmd/pmd/lib/jaxen-1.1-beta-7.jar:/home/tom/pmd/pmd-web/src/pmd-3.6.jar net.sourceforge.pmd.PMD \"#{ROOT}/#{@src}\" html unusedcode -shortnames #{self.jdk15? ? "-targetjdk 1.5" : ""} > #{report}" puts cmd `#{cmd}` if File.exists?(report) arr = IO.readlines(report) File.read(report) {|f| arr.each {|x| f << x if x =~ /Error while parsing/ } } end puts "PMD report contains #{pmd_lines} violations" end def run_cpd cmd="java -Xmx512m -cp /home/tom/pmd/pmd/lib/jaxen-1.1-beta-7.jar:/home/tom/pmd/pmd-web/src/pmd-3.6.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files #{@src} > #{cpd_file}" `#{cmd}` puts "CPD report contains #{cpd_lines} violations" end def copy_up `scp #{wad} #{report} #{cpd_file} #{ncss_report} tomcopeland@pmd.sf.net:#{REMOTE_REPORT_DIR}` end def report "reports/" + @unix_name + "_" + @mod.sub(/ /, '') + ".html" end def wad "reports/" + @unix_name + "_" + @mod.sub(/ /, '') + ".wad" end def cpd_file "reports/cpd_" + @unix_name + "_" + @mod.sub(/ /, '') + ".txt" end def ncss_report "reports/" + @unix_name + "_" + @mod.sub(/ /, '') + "_ncss.txt" end def clear `rm -rf "#{@mod}" reports/#{report} reports/#{cpd_file} reports/#{ncss_report}` end def homepage_html "http://" + @unix_name + ".sf.net/" end def ncss return 0 if File.size(ncss_report) < 5 File.read(ncss_report).split(":")[1].strip.chomp end def cpd_lines count = 0 File.read(cpd_file).each {|line| count += 1 if line["================================="] } count end def pmd_lines count = 0 File.read(report).each {|line| count += 1 if line[""] } unless !File.exists?(report) count == 0 ? 0 : (count/4).to_i end def pctg sprintf("%.2f", (pmd_lines.to_f/(ncss == 0 ? 1 : ncss.to_i))*100) end def color if pctg.to_f < 0.2 "#00ff00" elsif pctg.to_f < 0.8 "yellow" else "red" end end def to_s @title + ":" + @unix_name + ":" + @mod + ":" + @src end end class PreviousTracker def initialize(jobs) @jobs = jobs @counter = 0 end def bump @counter += 1 end def anchor_idx @counter end def previous_anchor_idx if (@counter + 2) > (@jobs.size-1) return @jobs.size - 1 end @counter + 2 end end if __FILE__ == $0 puts "Starting at #{Time.now}" Dir.chdir(Job::ROOT) ENV['JAVA_HOME']="/usr/local/java" ENV['PATH']="#{ENV['PATH']}:#{ENV['JAVA_HOME']}/bin" jobs = [] tree = YAML.load(File.open("jobs.yaml")) tree.keys.each {|key| jobs << Job.new(key, tree[key]) } jobs.sort! {|a,b| a.unix_name <=> b.unix_name } if ARGV.include?("-build") jobs.each do |job| if ARGV.include?("-job") && job.unix_name != ARGV.at(ARGV.index("-job")+1) puts "Skipping " + job.unix_name next end puts "Processing #{job.unix_name}; jdk15 = #{job.jdk15?}" job.checkout_code if File.exists?(job.src) if Dir.glob("#{job.src}/**/*.java").empty? puts "Skipping #{job} because no source files got checked out" else job.run_pmd job.run_cpd job.run_ncss job.copy_up job.clear end end end end jobs.sort! {|x,y| if !File.exists?(x.ncss_report) || !File.exists?(y.ncss_report) -1 else x.pctg <=> y.pctg end } if ARGV.include?("-doom") jobs.each do |j| begin pmd = PMDMap.new(j.pmd_lines) p = Path.new(0, 1000) p.add("e200/n200/e200/s200/e200/", pmd.nooks) p.add("s400/") p.add("w200/s200/w200/n200/w200/", pmd.nooks) p.add("n400/") m = SimpleLineMap.new(p) m.set_player(Point.new(50,900)) 0.upto(pmd.nooks-1) do |x| m.add_barrel(Point.new((x*600)+300, 1100)) m.add_barrel(Point.new((x*600)+300, 500)) end j.barrels = pmd.nooks * 2 m.create_wad(j.wad + ".tmp") cmd = "./bsp " + j.wad + ".tmp -o " + j.wad + " && rm -f " + j.wad + ".tmp" `#{cmd}` rescue end end end jobs.each {|j| next if ARGV.include?("-job") && j.unix_name != ARGV.at(ARGV.index("-job")+1) puts "Copying up #{j}" j.copy_up } if ARGV.include?("-copy") fm = Ikko::FragmentManager.new fm.base_path="./" pt = PreviousTracker.new(jobs) out = fm["header.frag", {"lastruntime"=>Time.now, "prev2header1"=>jobs[0].unix_name, "prev2header2"=>jobs[1].unix_name}] jobs.each {|j| out << fm["row.frag", { "title"=>fm["title.frag", {"file"=>j.report, "title"=>j.title}], "homepage"=>fm["homepage.frag", {"name"=>j.unix_name}], "ncss"=>j.ncss, "unix_name"=>j.unix_name, "anchor"=>jobs[pt.anchor_idx].unix_name, "previous_anchor"=>jobs[pt.previous_anchor_idx].unix_name, "pmd"=>j.pmd_lines.to_s, "pctg"=>fm["pctg.frag", {"color"=>j.color, "pctg"=>j.pctg.to_s}], "dupe"=>fm["cpd.frag", {"file"=>j.cpd_file, "dupes"=>j.cpd_lines.to_s}], "doom"=>fm["doom.frag", {"file"=>j.wad, "barrels"=>j.barrels}] }] unless !File.exists?(j.report) || !File.exists?(j.ncss_report) || j.ncss == 0 pt.bump } File.open("scoreboard.html", "w") {|f| f.syswrite(out)} `scp scoreboard.html tomcopeland@pmd.sf.net:/home/groups/p/pm/pmd/htdocs/` puts "Done at #{Time.now}" end