integrity-bob 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -27,7 +27,6 @@ desc "Run unit tests"
27
27
  task :test => SCMs.map { |scm| "test:#{scm}" } do
28
28
  ruby "test/bob_test.rb"
29
29
  ruby "test/test_test.rb"
30
- ruby "test/engine/threaded_test.rb"
31
30
  end
32
31
 
33
32
  SCMs.each { |scm|
data/bob.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "bob"
3
- s.version = "0.3.0"
3
+ s.version = "0.3.1"
4
4
  s.date = "2009-07-02"
5
5
 
6
6
  s.description = "Bob the Builder will build your code. Simple."
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.rubygems_version = "1.3.1"
17
17
 
18
18
  s.add_dependency "addressable"
19
+ s.add_dependency "ninja"
19
20
 
20
21
  if s.respond_to?(:add_development_dependency)
21
22
  s.add_development_dependency "sr-mg"
@@ -31,11 +32,8 @@ README.rdoc
31
32
  Rakefile
32
33
  bob.gemspec
33
34
  lib/bob.rb
34
- lib/bob/buildable.rb
35
35
  lib/bob/builder.rb
36
- lib/bob/engine.rb
37
- lib/bob/engine/foreground.rb
38
- lib/bob/engine/threaded.rb
36
+ lib/bob/buildable.rb
39
37
  lib/bob/scm.rb
40
38
  lib/bob/scm/abstract.rb
41
39
  lib/bob/scm/git.rb
@@ -45,9 +43,7 @@ lib/bob/test/buildable_stub.rb
45
43
  lib/bob/test/scm/abstract.rb
46
44
  lib/bob/test/scm/git.rb
47
45
  lib/bob/test/scm/svn.rb
48
- lib/core_ext/object.rb
49
46
  test/bob_test.rb
50
- test/engine/threaded_test.rb
51
47
  test/helper.rb
52
48
  test/scm/git_test.rb
53
49
  test/scm/svn_test.rb
data/lib/bob.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  require "fileutils"
2
+ require "pathname"
2
3
  require "yaml"
3
4
  require "logger"
4
5
  require "time"
6
+ require "ninja"
5
7
  require "addressable/uri"
6
8
 
7
9
  require "bob/buildable"
8
10
  require "bob/builder"
9
11
  require "bob/scm"
10
- require "bob/engine"
11
- require "core_ext/object"
12
12
 
13
13
  module Bob
14
14
  # Builds the specified <tt>buildable</tt>. This object must understand
@@ -20,14 +20,7 @@ module Bob
20
20
  # Directory where the code for the different buildables will be checked out.
21
21
  # Make sure the user running Bob is allowed to write to this directory.
22
22
  def self.directory
23
- @directory || "/tmp"
24
- end
25
-
26
- # What will you use to build in background. Must respond to <tt>call</tt> and
27
- # take a block which will be run "in background". The default is to run in
28
- # foreground.
29
- def self.engine
30
- @engine || Engine::Foreground
23
+ Pathname(@directory || "/tmp")
31
24
  end
32
25
 
33
26
  # What to log with (must implement ruby's Logger interface). Logs to STDOUT
@@ -37,6 +30,6 @@ module Bob
37
30
  end
38
31
 
39
32
  class << self
40
- attr_writer :directory, :engine, :logger
33
+ attr_writer :directory, :logger
41
34
  end
42
35
  end
data/lib/bob/buildable.rb CHANGED
@@ -7,7 +7,7 @@ module Bob
7
7
  end
8
8
 
9
9
  # What kind of repository this buildable represents. Must
10
- # return a Symbol (:git, :svn, etc.)
10
+ # return a String ("git", "svn", etc.)
11
11
  #
12
12
  # <b>You must implement this in the classes where you mixin this module</b>
13
13
  def scm
@@ -48,30 +48,26 @@ module Bob
48
48
  raise NotImplementedError
49
49
  end
50
50
 
51
- # Callback sent when a build starts. The first argument is a
52
- # string with whatever identifier is appropriate for a repository
53
- # of this kind. The second is a hash with information about the
54
- # commit.
55
- #
56
- # <tt>:author</tt>:: A string with the name/email of the committer
57
- # <tt>:message</tt>:: The commit message
58
- # <tt>:committed_at</tt>:: A Time object with the timestamp of the
59
- # commit
60
- #
61
- # <b>You must implement this in the classes where you mixin this module</b>
62
- def start_building(commit_id, commit_info)
63
- raise NotImplementedError
51
+ # Optional callback sent when the build starts. It can be used to calculate
52
+ # the build duration for example.
53
+ def start_building
64
54
  end
65
55
 
66
- # Callback sent after a build finishes. The first argument is a
67
- # string with whatever identifier is appropriate for a respository
68
- # of this kind. The second is a boolean which is true if the build
69
- # was successful or false if it failed. And the last one is a string
70
- # with the full output returned by the build process (STDOUT and
71
- # STDERR interleaved)
56
+ # Callback sent after a build finishes. The first argument is a hash with
57
+ # information about the commit.
58
+ #
59
+ # <tt>identifier</tt>:: A string with the commit identifier of the
60
+ # commit that was built
61
+ # <tt>author</tt>:: A string with the name/email of the committer
62
+ # <tt>message</tt>:: The commit message
63
+ # <tt>committed_at</tt>:: A Time object with the timestamp of the commit
64
+ #
65
+ # The second argument is a boolean indicating whether the build was
66
+ # successful. Finally, the last one is a string with the full output
67
+ # returned by the build process (STDOUT and STDERR interleaved)
72
68
  #
73
69
  # <b>You must implement this in the classes where you mixin this module</b>
74
- def finish_building(commit_id, build_status, build_output)
70
+ def finish_building(commit_info, build_status, build_output)
75
71
  raise NotImplementedError
76
72
  end
77
73
  end
data/lib/bob/builder.rb CHANGED
@@ -4,6 +4,8 @@ module Bob
4
4
  class Builder
5
5
  attr_reader :buildable
6
6
 
7
+ include Ninja
8
+
7
9
  # Instantiate the Builder, passing an object that understands
8
10
  # the <tt>Buildable</tt> interface.
9
11
  def initialize(buildable)
@@ -12,28 +14,24 @@ module Bob
12
14
 
13
15
  # This is where the magic happens:
14
16
  #
15
- # 1. Check out the repo to the appropriate commit.
16
- # 2. Notify the buildable that the build is starting.
17
- # 3. Run the build script on it in the background.
17
+ # 1. Notify the buildable that the build is starting.
18
+ # 2. Check out the repo to the appropriate commit.
19
+ # 3. Run the build script on it.
18
20
  # 4. Reports the build back to the buildable.
19
21
  def build
20
22
  Bob.logger.info "Building #{buildable.commit} of the #{buildable.scm} repo at #{buildable.uri}"
21
23
 
22
24
  in_background do
23
- scm.with_commit(commit) {
24
- buildable.start_building(commit, scm.info(commit))
25
- build_status, build_output = run_build_script
26
- buildable.finish_building(commit, build_status, build_output)
25
+ buildable.start_building if buildable.respond_to?(:start_building)
26
+
27
+ scm.with_commit(buildable.commit) { |commit_info|
28
+ buildable.finish_building(commit_info, *run_build_script)
27
29
  }
28
30
  end
29
31
  end
30
32
 
31
33
  private
32
34
 
33
- def commit
34
- @commit ||= buildable.commit == :head ? scm.head : buildable.commit
35
- end
36
-
37
35
  def run_build_script
38
36
  build_output = nil
39
37
 
@@ -45,15 +43,11 @@ module Bob
45
43
  end
46
44
 
47
45
  def build_script
48
- "(cd #{scm.directory_for(commit)} && #{buildable.build_script} 2>&1)"
46
+ "(cd #{scm.dir_for(buildable.commit)} && #{buildable.build_script} 2>&1)"
49
47
  end
50
48
 
51
49
  def scm
52
50
  @scm ||= SCM.new(buildable.scm, buildable.uri, buildable.branch)
53
51
  end
54
-
55
- def in_background(&block)
56
- Bob.engine.call(block)
57
- end
58
52
  end
59
53
  end
@@ -11,23 +11,27 @@ module Bob
11
11
  # Checkout the code at the specified <tt>commit</tt> and call the
12
12
  # passed block.
13
13
  def with_commit(commit)
14
- update_code(commit)
14
+ commit = resolve(commit)
15
15
  checkout(commit)
16
- yield
16
+ yield info(commit)
17
17
  end
18
18
 
19
19
  # Directory where the code will be checked out for the given
20
20
  # <tt>commit</tt>.
21
- def directory_for(commit)
22
- File.join(Bob.directory, "#{path}-#{commit}")
21
+ def dir_for(commit)
22
+ commit = resolve(commit)
23
+ Bob.directory.join(path, "-", commit)
23
24
  end
24
25
 
26
+ protected
27
+
25
28
  # Get some information about the specified <tt>commit</tt>.
26
29
  # Returns a hash with:
27
30
  #
28
- # [<tt>:author</tt>] Commit author's name and email
29
- # [<tt>:message</tt>] Commit message
30
- # [<tt>:committed_at</tt>] Commit date (as a <tt>Time</tt> object)
31
+ # [<tt>identifier</tt>] Commit identifier
32
+ # [<tt>author</tt>] Commit author's name and email
33
+ # [<tt>message</tt>] Commit message
34
+ # [<tt>committed_at</tt>] Commit date (as a <tt>Time</tt> object)
31
35
  def info(commit)
32
36
  raise NotImplementedError
33
37
  end
@@ -38,8 +42,6 @@ module Bob
38
42
  raise NotImplementedError
39
43
  end
40
44
 
41
- protected
42
-
43
45
  def run(command, directory=nil)
44
46
  command = "(#{directory ? "cd #{directory} && " : ""}#{command} &>/dev/null)"
45
47
  Bob.logger.debug(command)
@@ -52,6 +54,12 @@ module Bob
52
54
  gsub(/[ \-]+/i, '-'). # No more than one of the separator in a row.
53
55
  gsub(/^\-|\-$/i, '') # Remove leading/trailing separator.
54
56
  end
57
+
58
+ private
59
+
60
+ def resolve(commit)
61
+ commit == :head ? head : commit
62
+ end
55
63
  end
56
64
  end
57
65
  end
data/lib/bob/scm/git.rb CHANGED
@@ -1,19 +1,16 @@
1
1
  module Bob
2
2
  module SCM
3
3
  class Git < Abstract
4
- def initialize(uri, branch)
5
- super
6
-
7
- unless File.directory?(File.join(Bob.directory, "cache"))
8
- FileUtils.mkdir(File.join(Bob.directory, "cache"))
9
- end
10
- end
4
+ protected
11
5
 
12
6
  def info(commit)
13
- format = %Q(---%n:author: %an <%ae>%n:message: >-%n %s%n:committed_at: %ci%n)
14
- YAML.load(`cd #{directory_for(commit)} && git show -s --pretty=format:"#{format}" #{commit}`).tap { |info|
15
- info[:committed_at] = Time.parse(info[:committed_at])
16
- }
7
+ format = "---%nidentifier: %H%nauthor: %an \
8
+ <%ae>%nmessage: >-%n %s%ncommitted_at: %ci%n"
9
+
10
+ dump = YAML.load(`cd #{dir_for(commit)} && git show -s \
11
+ --pretty=format:"#{format}" #{commit}`)
12
+
13
+ dump.update("committed_at" => Time.parse(dump["committed_at"]))
17
14
  end
18
15
 
19
16
  def head
@@ -22,30 +19,15 @@ module Bob
22
19
 
23
20
  private
24
21
 
25
- def update_code(commit)
26
- unless File.directory?("#{cache_directory}/.git")
27
- run "git clone -n #{uri} #{cache_directory}"
28
- end
29
-
30
- run "git fetch origin", cache_directory
31
- run "git checkout origin/#{branch}", cache_directory
32
- end
33
-
34
22
  def checkout(commit)
35
- unless File.directory?("#{directory_for(commit)}/.git")
36
- run "git clone -ns #{cache_directory} #{directory_for(commit)}"
37
- end
38
-
39
- run "git fetch origin", directory_for(commit)
40
-
41
- # First checkout the branch just in case the commit_id
42
- # turns out to be HEAD or other non-sha identifier
43
- run "git checkout origin/#{branch}", directory_for(commit)
44
- run "git reset --hard #{commit}", directory_for(commit)
23
+ run "git clone #{uri} #{dir_for(commit)}" unless cloned?(commit)
24
+ run "git fetch origin", dir_for(commit)
25
+ run "git checkout origin/#{branch}", dir_for(commit)
26
+ run "git reset --hard #{commit}", dir_for(commit)
45
27
  end
46
28
 
47
- def cache_directory
48
- File.join(Bob.directory, "cache", path)
29
+ def cloned?(commit)
30
+ dir_for(commit).join(".git").directory?
49
31
  end
50
32
  end
51
33
  end
data/lib/bob/scm/svn.rb CHANGED
@@ -1,38 +1,36 @@
1
- require "bob/scm/abstract"
2
-
3
1
  module Bob
4
2
  module SCM
5
3
  class Svn < Abstract
4
+ protected
5
+
6
6
  def info(revision)
7
7
  dump = `svn log --non-interactive --revision #{revision} #{uri}`.split("\n")
8
8
  meta = dump[1].split(" | ")
9
9
 
10
- { :message => dump[3],
11
- :author => meta[1],
12
- :committed_at => Time.parse(meta[2]) }
10
+ { "identifier" => revision,
11
+ "message" => dump[3],
12
+ "author" => meta[1],
13
+ "committed_at" => Time.parse(meta[2]) }
13
14
  end
14
15
 
16
+
15
17
  def head
16
18
  `svn info #{uri}`.split("\n").detect { |l| l =~ /^Revision: (\d+)/ }
17
19
  $1.to_s
18
20
  end
19
21
 
20
- private
21
-
22
- def update_code(commit)
23
- initial_checkout(commit) unless checked_out?(commit)
24
- end
22
+ private
25
23
 
26
24
  def checkout(revision)
27
- run "svn up -q -r#{revision}", directory_for(revision)
28
- end
25
+ unless checked_out?(revision)
26
+ run "svn co -q #{uri} #{dir_for(revision)}"
27
+ end
29
28
 
30
- def initial_checkout(revision=nil)
31
- run "svn co -q #{uri} #{directory_for(revision)}"
29
+ run "svn up -q -r#{revision}", dir_for(revision)
32
30
  end
33
31
 
34
32
  def checked_out?(commit)
35
- File.directory?(directory_for(commit) + "/.svn")
33
+ dir_for(commit).join(".svn").directory?
36
34
  end
37
35
  end
38
36
  end
@@ -1,38 +1,40 @@
1
1
  module Bob
2
2
  module Test
3
- BuildableStub = Struct.new(:scm, :uri, :branch, :commit, :build_script) do
3
+ class BuildableStub
4
4
  include Bob::Buildable
5
5
 
6
6
  def self.for(repo, commit)
7
- scm = (Bob::Test::GitRepo === repo) ? :git : :svn
7
+ scm = (Bob::Test::GitRepo === repo) ? "git" : "svn"
8
8
  uri =
9
- if scm == :git
9
+ if scm == "git"
10
10
  repo.path
11
11
  else
12
12
  "file://#{SvnRepo.server_root}/#{repo.name}"
13
13
  end
14
- # move to repo
15
- branch = (scm == :git) ? "master" : ""
14
+ # TODO: move onto repo object?
15
+ branch = (scm == "git") ? "master" : ""
16
16
  build_script = "./test"
17
17
 
18
18
  new(scm, uri, branch, commit, build_script)
19
19
  end
20
20
 
21
- attr_reader :repo, :status, :output, :commit_info
21
+ attr_reader :scm, :uri, :branch, :commit, :build_script,
22
+ :repo, :status, :output, :commit_info
22
23
 
23
- def initialize(*args)
24
- super
24
+ def initialize(scm, uri, branch, commit, build_script)
25
+ @scm = scm.to_s
26
+ @uri = uri.to_s
27
+ @branch = branch
28
+ @commit = commit
29
+ @build_script = build_script
25
30
 
26
31
  @status = nil
27
32
  @output = ""
28
33
  @commit_info = {}
29
34
  end
30
35
 
31
- def start_building(commit_id, commit_info)
36
+ def finish_building(commit_info, status, output)
32
37
  @commit_info = commit_info
33
- end
34
-
35
- def finish_building(commit_id, status, output)
36
38
  @status = status ? :successful : :failed
37
39
  @output = output
38
40
  end
@@ -7,10 +7,6 @@ module Bob::Test
7
7
  @path = File.join(base_dir, @name.to_s)
8
8
  end
9
9
 
10
- def destroy
11
- FileUtils.rm_r path if File.directory?(path)
12
- end
13
-
14
10
  def add_commit(message, &action)
15
11
  Dir.chdir(path) do
16
12
  yield action
@@ -39,7 +35,7 @@ module Bob::Test
39
35
  end
40
36
 
41
37
  def head
42
- commits.last[:identifier]
38
+ commits.last["identifier"]
43
39
  end
44
40
 
45
41
  protected
@@ -19,8 +19,8 @@ module Bob::Test
19
19
  Dir.chdir(path) do
20
20
  commits = `git log --pretty=oneline`.collect { |l| l.split(" ").first }
21
21
  commits.inject([]) do |commits, sha1|
22
- format = "---%n:message: >-%n %s%n:timestamp: %ci%n" +
23
- ":identifier: %H%n:author: %n :name: %an%n :email: %ae%n"
22
+ format = "---%nmessage: >-%n %s%ntimestamp: %ci%n" +
23
+ "identifier: %H%nauthor: %n name: %an%n email: %ae%n"
24
24
  commits << YAML.load(`git show -s --pretty=format:"#{format}" #{sha1}`)
25
25
  end.reverse
26
26
  end
@@ -4,7 +4,7 @@ require "hpricot"
4
4
  module Bob::Test
5
5
  class SvnRepo < AbstractSCMRepo
6
6
  def self.server_root
7
- @root ||= File.join(Bob.directory, "svn")
7
+ @root ||= Bob.directory.join("svn")
8
8
  end
9
9
 
10
10
  attr_reader :remote
@@ -12,8 +12,8 @@ module Bob::Test
12
12
  def initialize(name, base_dir=Bob.directory)
13
13
  super
14
14
 
15
- @path = File.join(base_dir, "svn-#{name}")
16
- @remote = File.join(SvnRepo.server_root, name.to_s)
15
+ @path = base_dir.join("svn-#{name}")
16
+ @remote = SvnRepo.server_root.join(name.to_s)
17
17
  end
18
18
 
19
19
  def create
@@ -27,19 +27,14 @@ module Bob::Test
27
27
  end
28
28
  end
29
29
 
30
- def destroy
31
- FileUtils.rm_r(remote) if File.directory?(remote)
32
- super
33
- end
34
-
35
30
  def commits
36
31
  Dir.chdir(path) do
37
32
  doc = Hpricot::XML(`svn log --xml`)
38
33
 
39
34
  (doc/:log/:logentry).inject([]) { |commits, commit|
40
- commits << { :identifier => commit["revision"],
41
- :message => commit.at("msg").inner_html,
42
- :committed_at => Time.parse(commit.at("date").inner_html) }
35
+ commits << { "identifier" => commit["revision"],
36
+ "message" => commit.at("msg").inner_html,
37
+ "committed_at" => Time.parse(commit.at("date").inner_html) }
43
38
  }.reverse
44
39
  end
45
40
  end
@@ -58,7 +53,7 @@ module Bob::Test
58
53
 
59
54
  private
60
55
  def create_remote
61
- FileUtils.mkdir(SvnRepo.server_root)
56
+ SvnRepo.server_root.mkdir
62
57
 
63
58
  run "svnadmin create #{remote}"
64
59
 
data/test/bob_test.rb CHANGED
@@ -3,7 +3,8 @@ require File.dirname(__FILE__) + "/helper"
3
3
  class BobTest < Test::Unit::TestCase
4
4
  test "directory" do
5
5
  Bob.directory = "/foo/bar"
6
- assert_equal "/foo/bar", Bob.directory
6
+ assert_equal "/foo/bar", Bob.directory.to_s
7
+ assert_instance_of Pathname, Bob.directory
7
8
  end
8
9
 
9
10
  test "logger" do
@@ -12,11 +13,4 @@ class BobTest < Test::Unit::TestCase
12
13
 
13
14
  assert_same logger, Bob.logger
14
15
  end
15
-
16
- test "engine" do
17
- engine = Object.new
18
- Bob.engine = engine
19
-
20
- assert_same engine, Bob.engine
21
- end
22
16
  end
data/test/helper.rb CHANGED
@@ -22,10 +22,9 @@ class Test::Unit::TestCase
22
22
 
23
23
  def setup
24
24
  Bob.logger = Logger.new("/dev/null")
25
- Bob.engine = Bob::Engine::Foreground
26
- Bob.directory = File.expand_path(File.dirname(__FILE__) + "/../tmp")
25
+ Bob.directory = Pathname(__FILE__).dirname.join("..", "tmp").expand_path
27
26
 
28
- FileUtils.rm_rf(Bob.directory) if File.directory?(Bob.directory)
29
- FileUtils.mkdir_p(Bob.directory)
27
+ Bob.directory.rmtree if Bob.directory.directory?
28
+ Bob.directory.mkdir
30
29
  end
31
30
  end
data/test/scm/git_test.rb CHANGED
@@ -24,29 +24,31 @@ class BobGitTest < Test::Unit::TestCase
24
24
  test "with a successful build" do
25
25
  repo.add_successful_commit
26
26
 
27
- commit_id = repo.commits.last[:identifier]
27
+ commit_id = repo.commits.last["identifier"]
28
28
 
29
29
  buildable = BuildableStub.for(@repo, commit_id)
30
30
  buildable.build
31
31
 
32
32
  assert_equal :successful, buildable.status
33
33
  assert_equal "Running tests...\n", buildable.output
34
- assert_equal "This commit will work", buildable.commit_info[:message]
35
- assert buildable.commit_info[:committed_at].is_a?(Time)
34
+ assert_equal "This commit will work", buildable.commit_info["message"]
35
+ assert_equal commit_id, buildable.commit_info["identifier"]
36
+ assert buildable.commit_info["committed_at"].is_a?(Time)
36
37
  end
37
38
 
38
39
  test "with a failed build" do
39
40
  repo.add_failing_commit
40
41
 
41
- commit_id = repo.commits.last[:identifier]
42
+ commit_id = repo.commits.last["identifier"]
42
43
  buildable = BuildableStub.for(@repo, commit_id)
43
44
 
44
45
  buildable.build
45
46
 
46
47
  assert_equal :failed, buildable.status
47
48
  assert_equal "Running tests...\n", buildable.output
48
- assert_equal "This commit will fail", buildable.commit_info[:message]
49
- assert buildable.commit_info[:committed_at].is_a?(Time)
49
+ assert_equal "This commit will fail", buildable.commit_info["message"]
50
+ assert_equal commit_id, buildable.commit_info["identifier"]
51
+ assert buildable.commit_info["committed_at"].is_a?(Time)
50
52
  end
51
53
 
52
54
  test "can build the head of a repository" do
@@ -59,5 +61,6 @@ class BobGitTest < Test::Unit::TestCase
59
61
 
60
62
  assert_equal :successful, buildable.status
61
63
  assert_equal "Running tests...\n", buildable.output
64
+ assert_equal repo.head, buildable.commit_info["identifier"]
62
65
  end
63
66
  end
data/test/scm/svn_test.rb CHANGED
@@ -34,8 +34,9 @@ class BobSvnTest < Test::Unit::TestCase
34
34
 
35
35
  assert_equal :successful, buildable.status
36
36
  assert_equal "Running tests...\n", buildable.output
37
- assert_equal "This commit will work", buildable.commit_info[:message]
38
- assert buildable.commit_info[:committed_at].is_a?(Time)
37
+ assert_equal "This commit will work", buildable.commit_info["message"]
38
+ assert_equal "2", buildable.commit_info["identifier"]
39
+ assert buildable.commit_info["committed_at"].is_a?(Time)
39
40
  end
40
41
 
41
42
  test "with a failed build" do
@@ -46,8 +47,9 @@ class BobSvnTest < Test::Unit::TestCase
46
47
 
47
48
  assert_equal :failed, buildable.status
48
49
  assert_equal "Running tests...\n", buildable.output
49
- assert_equal "This commit will fail", buildable.commit_info[:message]
50
- assert buildable.commit_info[:committed_at].is_a?(Time)
50
+ assert_equal "This commit will fail", buildable.commit_info["message"]
51
+ assert_equal "2", buildable.commit_info["identifier"]
52
+ assert buildable.commit_info["committed_at"].is_a?(Time)
51
53
  end
52
54
 
53
55
  test "can build the head of a repository" do
@@ -59,5 +61,6 @@ class BobSvnTest < Test::Unit::TestCase
59
61
 
60
62
  assert_equal :successful, buildable.status
61
63
  assert_equal "Running tests...\n", buildable.output
64
+ assert_equal repo.head, buildable.commit_info["identifier"]
62
65
  end
63
66
  end
data/test/test_test.rb CHANGED
@@ -2,28 +2,27 @@ require File.dirname(__FILE__) + "/helper"
2
2
 
3
3
  class BobTestTest < Test::Unit::TestCase
4
4
  def assert_scm_repo(repo)
5
- repo.destroy
6
5
  repo.create
7
6
 
8
7
  assert_equal 1, repo.commits.size
9
- assert_equal "First commit", repo.commits.first[:message]
8
+ assert_equal "First commit", repo.commits.first["message"]
10
9
 
11
10
  repo.add_failing_commit
12
11
  assert_equal 2, repo.commits.size
13
- assert_equal "This commit will fail", repo.commits.last[:message]
14
- assert_equal repo.commits.last[:identifier], repo.head
12
+ assert_equal "This commit will fail", repo.commits.last["message"]
13
+ assert_equal repo.commits.last["identifier"], repo.head
15
14
  assert repo.short_head
16
15
 
17
16
  repo.add_successful_commit
18
17
  assert_equal 3, repo.commits.size
19
- assert_equal "This commit will work", repo.commits.last[:message]
20
- assert_equal repo.commits.last[:identifier], repo.head
18
+ assert_equal "This commit will work", repo.commits.last["message"]
19
+ assert_equal repo.commits.last["identifier"], repo.head
21
20
  end
22
21
 
23
22
  def test_buildable_stub
24
23
  b = BuildableStub.new(:git, "git://github.com/ry/node", "master", "HEAD", "make")
25
24
 
26
- assert_equal :git, b.scm
25
+ assert_equal "git", b.scm
27
26
  assert_equal "git://github.com/ry/node", b.uri
28
27
  assert_equal "master", b.branch
29
28
  assert_equal "HEAD", b.commit
@@ -37,12 +36,11 @@ class BobTestTest < Test::Unit::TestCase
37
36
 
38
37
  def test_buildable_git_repo
39
38
  repo = GitRepo.new(:test_repo)
40
- repo.destroy
41
39
  repo.create
42
40
 
43
41
  b = BuildableStub.for(repo, repo.head)
44
42
 
45
- assert_equal :git, b.scm
43
+ assert_equal "git", b.scm
46
44
  assert_equal "#{Bob.directory}/test_repo", b.uri
47
45
  assert_equal "master", b.branch
48
46
  assert_equal repo.head, b.commit
@@ -51,12 +49,11 @@ class BobTestTest < Test::Unit::TestCase
51
49
 
52
50
  def test_buildable_svn_repo
53
51
  repo = SvnRepo.new(:test_repo)
54
- repo.destroy
55
52
  repo.create
56
53
 
57
54
  b = BuildableStub.for(repo, repo.head)
58
55
 
59
- assert_equal :svn, b.scm
56
+ assert_equal "svn", b.scm
60
57
  assert_equal "", b.branch
61
58
  assert_equal repo.head, b.commit
62
59
  assert_equal "./test", b.build_script
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: integrity-bob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Nicol\xC3\xA1s Sanguinetti"
@@ -23,6 +23,16 @@ dependencies:
23
23
  - !ruby/object:Gem::Version
24
24
  version: "0"
25
25
  version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: ninja
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
26
36
  - !ruby/object:Gem::Dependency
27
37
  name: sr-mg
28
38
  type: :development
@@ -78,11 +88,8 @@ files:
78
88
  - Rakefile
79
89
  - bob.gemspec
80
90
  - lib/bob.rb
81
- - lib/bob/buildable.rb
82
91
  - lib/bob/builder.rb
83
- - lib/bob/engine.rb
84
- - lib/bob/engine/foreground.rb
85
- - lib/bob/engine/threaded.rb
92
+ - lib/bob/buildable.rb
86
93
  - lib/bob/scm.rb
87
94
  - lib/bob/scm/abstract.rb
88
95
  - lib/bob/scm/git.rb
@@ -92,15 +99,14 @@ files:
92
99
  - lib/bob/test/scm/abstract.rb
93
100
  - lib/bob/test/scm/git.rb
94
101
  - lib/bob/test/scm/svn.rb
95
- - lib/core_ext/object.rb
96
102
  - test/bob_test.rb
97
- - test/engine/threaded_test.rb
98
103
  - test/helper.rb
99
104
  - test/scm/git_test.rb
100
105
  - test/scm/svn_test.rb
101
106
  - test/test_test.rb
102
107
  has_rdoc: true
103
108
  homepage: http://integrityapp.com
109
+ licenses:
104
110
  post_install_message:
105
111
  rdoc_options: []
106
112
 
@@ -121,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
127
  requirements: []
122
128
 
123
129
  rubyforge_project: integrity
124
- rubygems_version: 1.2.0
130
+ rubygems_version: 1.3.5
125
131
  signing_key:
126
132
  specification_version: 2
127
133
  summary: Bob builds!
data/lib/bob/engine.rb DELETED
@@ -1,9 +0,0 @@
1
- module Bob
2
- # Different engines to run code in background. An engine is any object
3
- # that responds to #call and takes a Proc object, which should be executed
4
- # "in the background". The different engines are:
5
- module Engine
6
- autoload :Foreground, "bob/engine/foreground"
7
- autoload :Threaded, "bob/engine/threaded"
8
- end
9
- end
@@ -1,6 +0,0 @@
1
- module Bob
2
- module Engine
3
- # Dummy engine that just runs in the foreground (useful for tests).
4
- Foreground = lambda {|b| b.call }
5
- end
6
- end
@@ -1,145 +0,0 @@
1
- require "thread"
2
-
3
- module Bob
4
- module Engine
5
- # A thread pool based build engine. This engine simply adds jobs to an
6
- # in-memory queue, and processes them as soon as possible.
7
- class Threaded
8
- # The optional pool size controls how many threads will be created.
9
- def initialize(pool_size = 2, logger = Bob.logger)
10
- @pool = ThreadPool.new(pool_size)
11
- @logger = logger
12
- end
13
-
14
- # Adds a job to the queue.
15
- def call(job)
16
- @pool << job
17
- end
18
-
19
- # The number of jobs currently in the queue.
20
- def njobs
21
- @pool.njobs
22
- end
23
-
24
- # This method will not return until #njobs returns 0.
25
- def wait!
26
- Thread.pass until @pool.njobs == 0
27
- end
28
-
29
- # Manage a pool of threads, allowing for spin up / spin down of the
30
- # contained threads.
31
- # Simply processes work added to it's queue via #push.
32
- # The default size for the pool is 2 threads.
33
- class ThreadPool
34
- # A thread safe single value for use as a counter.
35
- class Incrementor
36
- # The value passed in will be the initial value.
37
- def initialize(v = 0)
38
- @m = Mutex.new
39
- @v = v
40
- end
41
-
42
- # Add the given value to self, default 1.
43
- def inc(v = 1)
44
- sync { @v += v }
45
- end
46
-
47
- # Subtract the given value to self, default 1.
48
- def dec(v = 1)
49
- sync { @v -= v }
50
- end
51
-
52
- # Simply shows the value inspect for convenience.
53
- def inspect
54
- @v.inspect
55
- end
56
-
57
- # Extract the value.
58
- def to_i
59
- @v
60
- end
61
-
62
- private
63
-
64
- # Wrap the given block in a mutex.
65
- def sync(&b)
66
- @m.synchronize &b
67
- end
68
- end
69
-
70
- # The number of threads in the pool.
71
- attr_reader :size
72
-
73
- # The job queue.
74
- attr_reader :jobs
75
-
76
- # Set the size of the thread pool. Asynchronously run down threads
77
- # that are no longer required, and synchronously spawn new required
78
- # threads.
79
- def size=(other)
80
- @size = other
81
-
82
- if @workers.size > @size
83
- (@workers.size - @size).times do
84
- @workers.shift[:run] = false
85
- end
86
- else
87
- (@size - @workers.size).times do
88
- @workers << spawn
89
- end
90
- end
91
- end
92
-
93
- # Default pool size is 2 threads.
94
- def initialize(size = nil, logger = Bob.logger)
95
- size ||= 2
96
- @jobs = Queue.new
97
- @njobs = Incrementor.new
98
- @workers = Array.new(size) { spawn }
99
- @logger = logger
100
- end
101
-
102
- # Adds a job to the queue, the job can be any number of objects
103
- # responding to call, and/or a block.
104
- def add(*jobs, &blk)
105
- jobs = jobs + Array(blk)
106
-
107
- jobs.each do |job|
108
- @jobs << job
109
- @njobs.inc
110
- end
111
- end
112
-
113
- alias_method :push, :add
114
- alias_method :<<, :add
115
-
116
- # A peak at the number of jobs in the queue. N.B. May differ, but
117
- # should be more accurate than +jobs.size+.
118
- def njobs
119
- @njobs.to_i
120
- end
121
-
122
- private
123
-
124
- # Create a new thread and return it. The thread will run until the
125
- # thread-local value +:run+ is changed to false or nil.
126
- def spawn
127
- Thread.new do
128
- c = Thread.current
129
- c[:run] = true
130
-
131
- while c[:run]
132
- job = @jobs.pop
133
- begin
134
- job.call
135
- rescue Exception => e
136
- @logger.error("Exception occured during build of #{job.uri} commit #{job.commit}: #{e.message}")
137
- end
138
- @njobs.dec
139
- end
140
- end
141
- end
142
- end
143
- end
144
- end
145
- end
@@ -1,7 +0,0 @@
1
- class Object #:nodoc:
2
- # Add Object#tap for backwards compatibility
3
- def tap
4
- yield self
5
- self
6
- end unless method_defined?(:tap)
7
- end
@@ -1,34 +0,0 @@
1
- require File.dirname(__FILE__) + "/../helper"
2
-
3
- class ThreadedBobTest < Test::Unit::TestCase
4
- def setup
5
- super
6
-
7
- @repo = GitRepo.new(:test_repo)
8
- @repo.create
9
- end
10
-
11
- test "with a successful threaded build" do
12
- old_engine = Bob.engine
13
-
14
- repo.add_successful_commit
15
- commit_id = repo.commits.last[:identifier]
16
- buildable = BuildableStub.for(@repo, commit_id)
17
-
18
- begin
19
- Thread.abort_on_exception = true
20
- Bob.engine = Bob::Engine::Threaded.new(5)
21
- buildable.build
22
- Bob.engine.wait!
23
-
24
- assert_equal :successful, buildable.status
25
- assert_equal "Running tests...\n", buildable.output
26
-
27
- commit = buildable.commit_info
28
- assert_equal "This commit will work", commit[:message]
29
- assert_equal Time.now.min, commit[:committed_at].min
30
- ensure
31
- Bob.engine = old_engine
32
- end
33
- end
34
- end