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