Skip to content

Commit

Permalink
Support passing :head as a valid commit_id to Bob.build
Browse files Browse the repository at this point in the history
  • Loading branch information
foca committed May 13, 2009
1 parent 80315f0 commit 9907a5b
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 13 deletions.
26 changes: 20 additions & 6 deletions lib/bob.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,26 +12,40 @@
module Bob module Bob
# Builds the specified <tt>buildable</tt>. This object must understand # Builds the specified <tt>buildable</tt>. This object must understand
# the API described in the README. # 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) def self.build(buildable, commit_ids)
Array(commit_ids).each do |commit_id| Array(commit_ids).each do |commit_id|
Builder.new(buildable, commit_id).build Builder.new(buildable, commit_id).build
end end
end end


# Directory where the code for the different buildables will be checked out. Make sure # Directory where the code for the different buildables will be checked out.
# the user running Bob is allowed to write to this directory. # Make sure the user running Bob is allowed to write to this directory.
def self.directory def self.directory
@directory || "/tmp" @directory || "/tmp"
end end


# What will you use to build in background. Must respond to <tt>call</tt> and take a block # What will you use to build in background. Must respond to <tt>call</tt> and
# which will be run "in background". The default is to run in foreground. # take a block which will be run "in background". The default is to run in
# foreground.
def self.engine def self.engine
@engine || BackgroundEngines::Foreground @engine || BackgroundEngines::Foreground
end end


# What to log with (must implement ruby's Logger interface). Logs to STDOUT by # What to log with (must implement ruby's Logger interface). Logs to STDOUT
# default. # by default.
def self.logger def self.logger
@logger || Logger.new(STDOUT) @logger || Logger.new(STDOUT)
end end
Expand Down
12 changes: 11 additions & 1 deletion lib/bob/builder.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ module Bob
# A Builder will take care of building a buildable (wow, you didn't see that coming, # A Builder will take care of building a buildable (wow, you didn't see that coming,
# right?). # right?).
class Builder 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) def initialize(buildable, commit_id)
@buildable = buildable @buildable = buildable
@commit_id = commit_id @commit_id = commit_id
Expand All @@ -28,6 +34,10 @@ def build


private private


def commit_id
@commit_id == :head ? scm.head : @commit_id
end

def run_build_script def run_build_script
build_output = nil build_output = nil


Expand Down
18 changes: 13 additions & 5 deletions lib/bob/scm/abstract.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ def initialize(uri, branch)
@branch = branch @branch = branch
end end


# Checkout the code into <tt>working_dir</tt> at the specified revision and # Checkout the code into <tt>working_dir</tt> at the specified revision
# call the passed block # and call the passed block
def with_commit(commit_id) def with_commit(commit_id)
update_code update_code
checkout(commit_id) checkout(commit_id)
yield yield
end end


# Directory where the code will be checked out. Make sure the user running Bob is # Directory where the code will be checked out. Make sure the user
# allowed to write to this directory (or you'll get a <tt>Errno::EACCESS</tt>) # running Bob is allowed to write to this directory (or you'll get a
# <tt>Errno::EACCESS</tt>)
def working_dir def working_dir
@working_dir ||= "#{Bob.directory}/#{path_from_uri}".tap do |path| @working_dir ||= "#{Bob.directory}/#{path_from_uri}".tap do |path|
FileUtils.mkdir_p path FileUtils.mkdir_p path
Expand All @@ -33,10 +34,17 @@ def info(commit_id)
raise NotImplementedError raise NotImplementedError
end end


# Return the identifier for the last commit in this branch of the
# repository.
def head
raise NotImplementedError
end

protected protected


def run(command, cd_into_working_dir=true) 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 Bob.logger.debug command
system(command) || raise(CantRunCommand, "Couldn't run SCM command `#{command}`") system(command) || raise(CantRunCommand, "Couldn't run SCM command `#{command}`")
end end
Expand Down
4 changes: 4 additions & 0 deletions lib/bob/scm/git.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ def info(commit_id)
end end
end end


def head
`git ls-remote --heads #{uri} #{branch} | cut -f1`.chomp
end

protected protected


def path_from_uri def path_from_uri
Expand Down
5 changes: 5 additions & 0 deletions lib/bob/scm/svn.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ def info(revision)
:committed_at => Time.parse(meta[2]) } :committed_at => Time.parse(meta[2]) }
end end


def head
%x[svn info #{uri}].split("\n").detect {|line| line =~ /^Revision: (\d+)/ }
$1.to_s
end

def with_commit(commit_id) def with_commit(commit_id)
update_code update_code
checkout(commit_id) checkout(commit_id)
Expand Down
9 changes: 8 additions & 1 deletion test/helper.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@


begin begin
require "redgreen" require "redgreen"
require "ruby-debug"
rescue LoadError rescue LoadError
end 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"), $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"),
File.expand_path(File.dirname(__FILE__) + "/../test/helper")) File.expand_path(File.dirname(__FILE__) + "/../test/helper"))


Expand Down
13 changes: 13 additions & 0 deletions test/scm/git_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -56,4 +56,17 @@ def setup
assert_equal 2, buildable.metadata.length assert_equal 2, buildable.metadata.length
assert_equal 2, buildable.builds.length assert_equal 2, buildable.builds.length
end 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 end
13 changes: 13 additions & 0 deletions test/scm/svn_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -54,4 +54,17 @@ def setup
assert_equal 3, buildable.metadata.length assert_equal 3, buildable.metadata.length
assert_equal 3, buildable.builds.length assert_equal 3, buildable.builds.length
end 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 end

0 comments on commit 9907a5b

Please sign in to comment.