Permalink
Browse files

Support passing :head as a valid commit_id to Bob.build

  • Loading branch information...
1 parent 80315f0 commit 9907a5bb5f28ed75ccd563f24a0cf0eb95d11fad @foca foca committed May 13, 2009
Showing with 87 additions and 13 deletions.
  1. +20 −6 lib/bob.rb
  2. +11 −1 lib/bob/builder.rb
  3. +13 −5 lib/bob/scm/abstract.rb
  4. +4 −0 lib/bob/scm/git.rb
  5. +5 −0 lib/bob/scm/svn.rb
  6. +8 −1 test/helper.rb
  7. +13 −0 test/scm/git_test.rb
  8. +13 −0 test/scm/svn_test.rb
View
@@ -12,26 +12,40 @@
module Bob
# Builds the specified <tt>buildable</tt>. This object must understand
# the API described in the README.
+ #
+ # The second argument will take an array of commit_ids, which should be
+ # strings with the relevant identifier (a SHA1 hash for git repositories,
+ # a numerical revision for svn repositories, etc).
+ #
+ # You can pass :head as a commit identifier to build the latest commit
+ # in the repo. Examples:
+ #
+ # Bob.build(buildable, :head) # just build the head
+ # Bob.build(buildable, ["4", "3", "2"]) # build revision 4, 3, and 2
+ # # (in that order)
+ # Bob.build(buildable, [:head, "a30fb12"]) # build the HEAD and a30fb12
+ # # commits in this repo.
def self.build(buildable, commit_ids)
Array(commit_ids).each do |commit_id|
Builder.new(buildable, commit_id).build
end
end
- # Directory where the code for the different buildables will be checked out. Make sure
- # the user running Bob is allowed to write to this directory.
+ # Directory where the code for the different buildables will be checked out.
+ # Make sure the user running Bob is allowed to write to this directory.
def self.directory
@directory || "/tmp"
end
- # What will you use to build in background. Must respond to <tt>call</tt> and take a block
- # which will be run "in background". The default is to run in foreground.
+ # What will you use to build in background. Must respond to <tt>call</tt> and
+ # take a block which will be run "in background". The default is to run in
+ # foreground.
def self.engine
@engine || BackgroundEngines::Foreground
end
- # What to log with (must implement ruby's Logger interface). Logs to STDOUT by
- # default.
+ # What to log with (must implement ruby's Logger interface). Logs to STDOUT
+ # by default.
def self.logger
@logger || Logger.new(STDOUT)
end
View
@@ -2,8 +2,14 @@ module Bob
# A Builder will take care of building a buildable (wow, you didn't see that coming,
# right?).
class Builder
- attr_reader :buildable, :commit_id
+ attr_reader :buildable
+ # Instantiate the Builder, passing an object that understands the <tt>Buildable</tt>
+ # interface, and a <tt>commit_id</tt>.
+ #
+ # You can pass <tt>:head</tt> as the commit id, in which case it will resolve to the
+ # head commit of the current branch (for example, "HEAD" under git, or the latest
+ # revision under svn)
def initialize(buildable, commit_id)
@buildable = buildable
@commit_id = commit_id
@@ -28,6 +34,10 @@ def build
private
+ def commit_id
+ @commit_id == :head ? scm.head : @commit_id
+ end
+
def run_build_script
build_output = nil
View
@@ -8,16 +8,17 @@ def initialize(uri, branch)
@branch = branch
end
- # Checkout the code into <tt>working_dir</tt> at the specified revision and
- # call the passed block
+ # Checkout the code into <tt>working_dir</tt> at the specified revision
+ # and call the passed block
def with_commit(commit_id)
update_code
checkout(commit_id)
yield
end
- # Directory where the code will be checked out. Make sure the user running Bob is
- # allowed to write to this directory (or you'll get a <tt>Errno::EACCESS</tt>)
+ # Directory where the code will be checked out. Make sure the user
+ # running Bob is allowed to write to this directory (or you'll get a
+ # <tt>Errno::EACCESS</tt>)
def working_dir
@working_dir ||= "#{Bob.directory}/#{path_from_uri}".tap do |path|
FileUtils.mkdir_p path
@@ -33,10 +34,17 @@ def info(commit_id)
raise NotImplementedError
end
+ # Return the identifier for the last commit in this branch of the
+ # repository.
+ def head
+ raise NotImplementedError
+ end
+
protected
def run(command, cd_into_working_dir=true)
- command = "(#{cd_into_working_dir ? "cd #{working_dir} && " : ""}#{command} &>/dev/null)"
+ command_prefix = cd_into_working_dir ? "cd #{working_dir} && " : ""
+ command = "(#{command_prefix}#{command} &>/dev/null)"
Bob.logger.debug command
system(command) || raise(CantRunCommand, "Couldn't run SCM command `#{command}`")
end
View
@@ -8,6 +8,10 @@ def info(commit_id)
end
end
+ def head
+ `git ls-remote --heads #{uri} #{branch} | cut -f1`.chomp
+ end
+
protected
def path_from_uri
View
@@ -12,6 +12,11 @@ def info(revision)
:committed_at => Time.parse(meta[2]) }
end
+ def head
+ %x[svn info #{uri}].split("\n").detect {|line| line =~ /^Revision: (\d+)/ }
+ $1.to_s
+ end
+
def with_commit(commit_id)
update_code
checkout(commit_id)
View
@@ -4,10 +4,17 @@
begin
require "redgreen"
- require "ruby-debug"
rescue LoadError
end
+if ENV["DEBUG"]
+ require "ruby-debug"
+else
+ def debugger
+ puts "Run your tests with DEBUG=1 to use the debugger"
+ end
+end
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"),
File.expand_path(File.dirname(__FILE__) + "/../test/helper"))
View
@@ -56,4 +56,17 @@ def setup
assert_equal 2, buildable.metadata.length
assert_equal 2, buildable.builds.length
end
+
+ test "can build the head of a repository" do
+ repo.add_failing_commit
+ repo.add_successful_commit
+
+ buildable.build(:head)
+
+ assert_equal 1, buildable.builds.length
+
+ status, output = buildable.builds[repo.head]
+ assert_equal :successful, status
+ assert_equal "Running tests...\n", output
+ end
end
View
@@ -54,4 +54,17 @@ def setup
assert_equal 3, buildable.metadata.length
assert_equal 3, buildable.builds.length
end
+
+ test "can build the head of a repository" do
+ repo.add_failing_commit
+ repo.add_successful_commit
+
+ buildable.build(:head)
+
+ assert_equal 1, buildable.builds.length
+
+ status, output = buildable.builds["3"]
+ assert_equal :successful, status
+ assert_equal "Running tests...\n", output
+ end
end

0 comments on commit 9907a5b

Please sign in to comment.