lib/bait/build.rb in bait-0.4.1 vs lib/bait/build.rb in bait-0.5.0

- old
+ new

@@ -1,7 +1,9 @@ require 'bait/object' require 'bait/tester' +require 'json' +require 'bait/pubsub' module Bait class Build < Bait::Object adapter :memory, Moneta.new(:YAML, :file => Bait.db_file('builds')) @@ -9,41 +11,105 @@ attribute :ref, String attribute :owner_name, String attribute :owner_email, String attribute :name, String attribute :clone_url, String - attribute :passed, Boolean attribute :output, String, default: "" - attribute :tested, Boolean, default: false + attribute :status, String, default: "queued" validates_presence_of :name validates_presence_of :clone_url - def tester - @tester ||= Bait::Tester.new(self) + after_create do + Bait.broadcast(:global, :new_build, self) end + after_destroy do + self.broadcast(:remove) + self.cleanup! + end + + def test! + Open3.popen2e(self.script) do |stdin, oe, wait_thr| + self.status = "testing" + self.broadcast :status, self.status + self.save + oe.each do |line| + self.output << line + self.broadcast(:output, line) + end + if wait_thr.value.exitstatus == 0 + self.status = "passed" + else + self.status = "failed" + end + end + rescue Errno::ENOENT => ex + self.output << "A test script was expected but missing.\nError: #{ex.message}" + self.status = "script missing" + ensure + self.save + self.broadcast(:status, status) + end + def test_later - self.tested = false + self.status = "queued" + self.output = "" self.save - fork do - self.tester.clone! - self.tester.test! - end + Bait::Tester.new.async.perform(self.id) unless Bait.env == "test" self end def queued? - !self.reload.tested? + self.reload.status == "queued" end - def status - if queued? - "queued" - elsif tested? - passed? ? "passed" : "failed" + def passed? + self.reload.status == "passed" + end + + def clone_path + File.join(sandbox_directory, self.name) + end + + def bait_dir + File.join(clone_path, ".bait") + end + + def script + File.join(bait_dir, "test.sh") + end + + def cloned? + Dir.exists? File.join(clone_path, ".git/") + end + + def cleanup! + FileUtils.rm_rf(sandbox_directory) if Dir.exists?(sandbox_directory) + end + + def sandbox_directory + File.join Bait.storage_dir, "tester", self.name, self.id + end + + def clone! + unless cloned? + unless Dir.exists?(sandbox_directory) + FileUtils.mkdir_p sandbox_directory + end + begin + Git.clone(clone_url, name, :path => sandbox_directory) + rescue => ex + msg = "Failed to clone #{clone_url}" + self.output << "#{msg}\n\n#{ex.message}\n\n#{ex.backtrace.join("\n")}" + self.save + end end end - after_destroy { tester.cleanup! } + protected + + def broadcast attr, *args + Bait.broadcast :build, attr, self.id, *args + end end end