integrity-bob 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -0
- data/bob.gemspec +7 -2
- data/lib/bob/buildable.rb +14 -6
- data/lib/bob/builder.rb +12 -17
- data/lib/bob/engine/threaded.rb +11 -4
- data/lib/bob/scm/abstract.rb +14 -16
- data/lib/bob/scm/git.rb +26 -19
- data/lib/bob/scm/svn.rb +6 -12
- data/lib/bob/test/buildable_stub.rb +41 -0
- data/lib/bob/test/scm/abstract.rb +66 -0
- data/lib/bob/test/scm/git.rb +48 -0
- data/lib/bob/test/scm/svn.rb +72 -0
- data/lib/bob/test.rb +4 -0
- data/lib/bob.rb +2 -17
- data/test/engine/threaded_test.rb +5 -7
- data/test/helper.rb +2 -1
- data/test/scm/git_test.rb +16 -38
- data/test/scm/svn_test.rb +16 -40
- data/test/test_test.rb +65 -0
- metadata +7 -11
data/Rakefile
CHANGED
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
|
+
s.version = "0.3.0"
|
4
4
|
s.date = "2009-07-02"
|
5
5
|
|
6
6
|
s.description = "Bob the Builder will build your code. Simple."
|
@@ -19,7 +19,6 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
if s.respond_to?(:add_development_dependency)
|
21
21
|
s.add_development_dependency "sr-mg"
|
22
|
-
s.add_development_dependency "sr-bob-test"
|
23
22
|
s.add_development_dependency "contest"
|
24
23
|
s.add_development_dependency "redgreen"
|
25
24
|
s.add_development_dependency "ruby-debug"
|
@@ -41,11 +40,17 @@ lib/bob/scm.rb
|
|
41
40
|
lib/bob/scm/abstract.rb
|
42
41
|
lib/bob/scm/git.rb
|
43
42
|
lib/bob/scm/svn.rb
|
43
|
+
lib/bob/test.rb
|
44
|
+
lib/bob/test/buildable_stub.rb
|
45
|
+
lib/bob/test/scm/abstract.rb
|
46
|
+
lib/bob/test/scm/git.rb
|
47
|
+
lib/bob/test/scm/svn.rb
|
44
48
|
lib/core_ext/object.rb
|
45
49
|
test/bob_test.rb
|
46
50
|
test/engine/threaded_test.rb
|
47
51
|
test/helper.rb
|
48
52
|
test/scm/git_test.rb
|
49
53
|
test/scm/svn_test.rb
|
54
|
+
test/test_test.rb
|
50
55
|
]
|
51
56
|
end
|
data/lib/bob/buildable.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
module Bob
|
2
2
|
# Mixin to add to your classes.
|
3
3
|
module Buildable
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
# etc), or a single string with a commit id.
|
8
|
-
def build(commits)
|
9
|
-
Bob.build(self, commits)
|
4
|
+
# Build itself.
|
5
|
+
def build
|
6
|
+
Bob.build(self)
|
10
7
|
end
|
11
8
|
|
12
9
|
# What kind of repository this buildable represents. Must
|
@@ -31,6 +28,17 @@ module Bob
|
|
31
28
|
raise NotImplementedError
|
32
29
|
end
|
33
30
|
|
31
|
+
# Indentifier of the commit to build.
|
32
|
+
#
|
33
|
+
# The special identifier <tt>:head</tt> will be resolved to the head
|
34
|
+
# commit of the current branch (for example, "HEAD" under git or the
|
35
|
+
# latest revision under svn)
|
36
|
+
#
|
37
|
+
# <b>You must implement this in the classes where you mixin this module</b>
|
38
|
+
def commit
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
|
34
42
|
# Script that will be run in the buildable's checked out code,
|
35
43
|
# if it returns a status code of 0 it will be considered a
|
36
44
|
# successfull build. Else it will be considered a failed build.
|
data/lib/bob/builder.rb
CHANGED
@@ -1,18 +1,13 @@
|
|
1
1
|
module Bob
|
2
|
-
# A Builder will take care of building a buildable (wow, you didn't see
|
3
|
-
# right?).
|
2
|
+
# A Builder will take care of building a buildable (wow, you didn't see
|
3
|
+
# that coming, right?).
|
4
4
|
class Builder
|
5
5
|
attr_reader :buildable
|
6
6
|
|
7
|
-
# Instantiate the Builder, passing an object that understands
|
8
|
-
#
|
9
|
-
|
10
|
-
# You can pass <tt>:head</tt> as the commit id, in which case it will resolve to the
|
11
|
-
# head commit of the current branch (for example, "HEAD" under git, or the latest
|
12
|
-
# revision under svn)
|
13
|
-
def initialize(buildable, commit_id)
|
7
|
+
# Instantiate the Builder, passing an object that understands
|
8
|
+
# the <tt>Buildable</tt> interface.
|
9
|
+
def initialize(buildable)
|
14
10
|
@buildable = buildable
|
15
|
-
@commit_id = commit_id
|
16
11
|
end
|
17
12
|
|
18
13
|
# This is where the magic happens:
|
@@ -22,21 +17,21 @@ module Bob
|
|
22
17
|
# 3. Run the build script on it in the background.
|
23
18
|
# 4. Reports the build back to the buildable.
|
24
19
|
def build
|
25
|
-
Bob.logger.info "Building #{
|
20
|
+
Bob.logger.info "Building #{buildable.commit} of the #{buildable.scm} repo at #{buildable.uri}"
|
26
21
|
|
27
22
|
in_background do
|
28
|
-
scm.with_commit(
|
29
|
-
buildable.start_building(
|
23
|
+
scm.with_commit(commit) {
|
24
|
+
buildable.start_building(commit, scm.info(commit))
|
30
25
|
build_status, build_output = run_build_script
|
31
|
-
buildable.finish_building(
|
26
|
+
buildable.finish_building(commit, build_status, build_output)
|
32
27
|
}
|
33
28
|
end
|
34
29
|
end
|
35
30
|
|
36
31
|
private
|
37
32
|
|
38
|
-
def
|
39
|
-
@
|
33
|
+
def commit
|
34
|
+
@commit ||= buildable.commit == :head ? scm.head : buildable.commit
|
40
35
|
end
|
41
36
|
|
42
37
|
def run_build_script
|
@@ -50,7 +45,7 @@ module Bob
|
|
50
45
|
end
|
51
46
|
|
52
47
|
def build_script
|
53
|
-
"(cd #{scm.
|
48
|
+
"(cd #{scm.directory_for(commit)} && #{buildable.build_script} 2>&1)"
|
54
49
|
end
|
55
50
|
|
56
51
|
def scm
|
data/lib/bob/engine/threaded.rb
CHANGED
@@ -6,8 +6,9 @@ module Bob
|
|
6
6
|
# in-memory queue, and processes them as soon as possible.
|
7
7
|
class Threaded
|
8
8
|
# The optional pool size controls how many threads will be created.
|
9
|
-
def initialize(pool_size = 2)
|
10
|
-
@pool
|
9
|
+
def initialize(pool_size = 2, logger = Bob.logger)
|
10
|
+
@pool = ThreadPool.new(pool_size)
|
11
|
+
@logger = logger
|
11
12
|
end
|
12
13
|
|
13
14
|
# Adds a job to the queue.
|
@@ -90,11 +91,12 @@ module Bob
|
|
90
91
|
end
|
91
92
|
|
92
93
|
# Default pool size is 2 threads.
|
93
|
-
def initialize(size = nil)
|
94
|
+
def initialize(size = nil, logger = Bob.logger)
|
94
95
|
size ||= 2
|
95
96
|
@jobs = Queue.new
|
96
97
|
@njobs = Incrementor.new
|
97
98
|
@workers = Array.new(size) { spawn }
|
99
|
+
@logger = logger
|
98
100
|
end
|
99
101
|
|
100
102
|
# Adds a job to the queue, the job can be any number of objects
|
@@ -127,7 +129,12 @@ module Bob
|
|
127
129
|
c[:run] = true
|
128
130
|
|
129
131
|
while c[:run]
|
130
|
-
@jobs.pop
|
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
|
131
138
|
@njobs.dec
|
132
139
|
end
|
133
140
|
end
|
data/lib/bob/scm/abstract.rb
CHANGED
@@ -8,29 +8,27 @@ module Bob
|
|
8
8
|
@branch = branch
|
9
9
|
end
|
10
10
|
|
11
|
-
# Checkout the code
|
12
|
-
#
|
13
|
-
def with_commit(
|
14
|
-
update_code
|
15
|
-
checkout(
|
11
|
+
# Checkout the code at the specified <tt>commit</tt> and call the
|
12
|
+
# passed block.
|
13
|
+
def with_commit(commit)
|
14
|
+
update_code(commit)
|
15
|
+
checkout(commit)
|
16
16
|
yield
|
17
17
|
end
|
18
18
|
|
19
|
-
# Directory where the code will be checked out
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
@working_dir ||= "#{Bob.directory}/#{path}".tap { |dir|
|
24
|
-
FileUtils.mkdir_p(dir)
|
25
|
-
}
|
19
|
+
# Directory where the code will be checked out for the given
|
20
|
+
# <tt>commit</tt>.
|
21
|
+
def directory_for(commit)
|
22
|
+
File.join(Bob.directory, "#{path}-#{commit}")
|
26
23
|
end
|
27
24
|
|
28
|
-
# Get some information about the specified commit
|
25
|
+
# Get some information about the specified <tt>commit</tt>.
|
26
|
+
# Returns a hash with:
|
29
27
|
#
|
30
28
|
# [<tt>:author</tt>] Commit author's name and email
|
31
29
|
# [<tt>:message</tt>] Commit message
|
32
30
|
# [<tt>:committed_at</tt>] Commit date (as a <tt>Time</tt> object)
|
33
|
-
def info(
|
31
|
+
def info(commit)
|
34
32
|
raise NotImplementedError
|
35
33
|
end
|
36
34
|
|
@@ -42,8 +40,8 @@ module Bob
|
|
42
40
|
|
43
41
|
protected
|
44
42
|
|
45
|
-
def run(command,
|
46
|
-
command = "(#{
|
43
|
+
def run(command, directory=nil)
|
44
|
+
command = "(#{directory ? "cd #{directory} && " : ""}#{command} &>/dev/null)"
|
47
45
|
Bob.logger.debug(command)
|
48
46
|
system(command) || raise(Error, "Couldn't run SCM command `#{command}`")
|
49
47
|
end
|
data/lib/bob/scm/git.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
module Bob
|
2
2
|
module SCM
|
3
3
|
class Git < Abstract
|
4
|
-
def
|
5
|
-
|
6
|
-
|
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
|
11
|
+
|
12
|
+
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|
|
7
15
|
info[:committed_at] = Time.parse(info[:committed_at])
|
8
16
|
}
|
9
17
|
end
|
@@ -14,31 +22,30 @@ module Bob
|
|
14
22
|
|
15
23
|
private
|
16
24
|
|
17
|
-
def update_code
|
18
|
-
|
19
|
-
|
25
|
+
def update_code(commit)
|
26
|
+
unless File.directory?("#{cache_directory}/.git")
|
27
|
+
run "git clone -n #{uri} #{cache_directory}"
|
28
|
+
end
|
20
29
|
|
21
|
-
|
22
|
-
|
30
|
+
run "git fetch origin", cache_directory
|
31
|
+
run "git checkout origin/#{branch}", cache_directory
|
23
32
|
end
|
24
33
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
34
|
+
def checkout(commit)
|
35
|
+
unless File.directory?("#{directory_for(commit)}/.git")
|
36
|
+
run "git clone -ns #{cache_directory} #{directory_for(commit)}"
|
37
|
+
end
|
28
38
|
|
29
|
-
|
30
|
-
git "fetch origin"
|
31
|
-
end
|
39
|
+
run "git fetch origin", directory_for(commit)
|
32
40
|
|
33
|
-
def checkout(commit_id)
|
34
41
|
# First checkout the branch just in case the commit_id
|
35
42
|
# turns out to be HEAD or other non-sha identifier
|
36
|
-
git
|
37
|
-
git
|
43
|
+
run "git checkout origin/#{branch}", directory_for(commit)
|
44
|
+
run "git reset --hard #{commit}", directory_for(commit)
|
38
45
|
end
|
39
46
|
|
40
|
-
def
|
41
|
-
|
47
|
+
def cache_directory
|
48
|
+
File.join(Bob.directory, "cache", path)
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
data/lib/bob/scm/svn.rb
CHANGED
@@ -17,28 +17,22 @@ module Bob
|
|
17
17
|
$1.to_s
|
18
18
|
end
|
19
19
|
|
20
|
-
def with_commit(commit_id)
|
21
|
-
update_code
|
22
|
-
checkout(commit_id)
|
23
|
-
yield
|
24
|
-
end
|
25
|
-
|
26
20
|
private
|
27
21
|
|
28
|
-
def update_code
|
29
|
-
initial_checkout unless checked_out?
|
22
|
+
def update_code(commit)
|
23
|
+
initial_checkout(commit) unless checked_out?(commit)
|
30
24
|
end
|
31
25
|
|
32
26
|
def checkout(revision)
|
33
|
-
run
|
27
|
+
run "svn up -q -r#{revision}", directory_for(revision)
|
34
28
|
end
|
35
29
|
|
36
30
|
def initial_checkout(revision=nil)
|
37
|
-
run
|
31
|
+
run "svn co -q #{uri} #{directory_for(revision)}"
|
38
32
|
end
|
39
33
|
|
40
|
-
def checked_out?
|
41
|
-
File.directory?(
|
34
|
+
def checked_out?(commit)
|
35
|
+
File.directory?(directory_for(commit) + "/.svn")
|
42
36
|
end
|
43
37
|
end
|
44
38
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Bob
|
2
|
+
module Test
|
3
|
+
BuildableStub = Struct.new(:scm, :uri, :branch, :commit, :build_script) do
|
4
|
+
include Bob::Buildable
|
5
|
+
|
6
|
+
def self.for(repo, commit)
|
7
|
+
scm = (Bob::Test::GitRepo === repo) ? :git : :svn
|
8
|
+
uri =
|
9
|
+
if scm == :git
|
10
|
+
repo.path
|
11
|
+
else
|
12
|
+
"file://#{SvnRepo.server_root}/#{repo.name}"
|
13
|
+
end
|
14
|
+
# move to repo
|
15
|
+
branch = (scm == :git) ? "master" : ""
|
16
|
+
build_script = "./test"
|
17
|
+
|
18
|
+
new(scm, uri, branch, commit, build_script)
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :repo, :status, :output, :commit_info
|
22
|
+
|
23
|
+
def initialize(*args)
|
24
|
+
super
|
25
|
+
|
26
|
+
@status = nil
|
27
|
+
@output = ""
|
28
|
+
@commit_info = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_building(commit_id, commit_info)
|
32
|
+
@commit_info = commit_info
|
33
|
+
end
|
34
|
+
|
35
|
+
def finish_building(commit_id, status, output)
|
36
|
+
@status = status ? :successful : :failed
|
37
|
+
@output = output
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Bob::Test
|
2
|
+
class AbstractSCMRepo
|
3
|
+
attr_reader :path, :name
|
4
|
+
|
5
|
+
def initialize(name, base_dir=Bob.directory)
|
6
|
+
@name = name
|
7
|
+
@path = File.join(base_dir, @name.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy
|
11
|
+
FileUtils.rm_r path if File.directory?(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_commit(message, &action)
|
15
|
+
Dir.chdir(path) do
|
16
|
+
yield action
|
17
|
+
commit(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_failing_commit
|
22
|
+
add_commit "This commit will fail" do
|
23
|
+
system "echo '#{build_script(false)}' > test"
|
24
|
+
system "chmod +x test"
|
25
|
+
add "test"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_successful_commit
|
30
|
+
add_commit "This commit will work" do
|
31
|
+
system "echo '#{build_script(true)}' > test"
|
32
|
+
system "chmod +x test"
|
33
|
+
add "test"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def commits
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
|
41
|
+
def head
|
42
|
+
commits.last[:identifier]
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
def add(file)
|
47
|
+
raise NotImplementedError
|
48
|
+
end
|
49
|
+
|
50
|
+
def commit(message)
|
51
|
+
raise NotImplementedError
|
52
|
+
end
|
53
|
+
|
54
|
+
def run(command)
|
55
|
+
system "#{command} &>/dev/null"
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_script(successful=true)
|
59
|
+
<<-script
|
60
|
+
#!/bin/sh
|
61
|
+
echo "Running tests..."
|
62
|
+
exit #{successful ? 0 : 1}
|
63
|
+
script
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/abstract"
|
2
|
+
|
3
|
+
module Bob::Test
|
4
|
+
class GitRepo < AbstractSCMRepo
|
5
|
+
def create
|
6
|
+
FileUtils.mkdir(path)
|
7
|
+
|
8
|
+
Dir.chdir(path) do
|
9
|
+
run "git init"
|
10
|
+
run "git config user.name 'John Doe'"
|
11
|
+
run "git config user.email 'johndoe@example.org'"
|
12
|
+
run "echo 'just a test repo' >> README"
|
13
|
+
add "README"
|
14
|
+
commit "First commit"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def commits
|
19
|
+
Dir.chdir(path) do
|
20
|
+
commits = `git log --pretty=oneline`.collect { |l| l.split(" ").first }
|
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"
|
24
|
+
commits << YAML.load(`git show -s --pretty=format:"#{format}" #{sha1}`)
|
25
|
+
end.reverse
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def head
|
30
|
+
Dir.chdir(path) do
|
31
|
+
`git log --pretty=format:%H | head -1`.chomp
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def short_head
|
36
|
+
head[0..6]
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def add(file)
|
41
|
+
run "git add #{file}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def commit(message)
|
45
|
+
run %Q{git commit -m "#{message}"}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/abstract"
|
2
|
+
require "hpricot"
|
3
|
+
|
4
|
+
module Bob::Test
|
5
|
+
class SvnRepo < AbstractSCMRepo
|
6
|
+
def self.server_root
|
7
|
+
@root ||= File.join(Bob.directory, "svn")
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :remote
|
11
|
+
|
12
|
+
def initialize(name, base_dir=Bob.directory)
|
13
|
+
super
|
14
|
+
|
15
|
+
@path = File.join(base_dir, "svn-#{name}")
|
16
|
+
@remote = File.join(SvnRepo.server_root, name.to_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
create_remote
|
21
|
+
|
22
|
+
run "svn checkout file://#{remote} #{path}"
|
23
|
+
|
24
|
+
add_commit("First commit") do
|
25
|
+
run "echo 'just a test repo' >> README"
|
26
|
+
add "README"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
FileUtils.rm_r(remote) if File.directory?(remote)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def commits
|
36
|
+
Dir.chdir(path) do
|
37
|
+
doc = Hpricot::XML(`svn log --xml`)
|
38
|
+
|
39
|
+
(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) }
|
43
|
+
}.reverse
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :short_head, :head
|
48
|
+
|
49
|
+
protected
|
50
|
+
def add(file)
|
51
|
+
run "svn add #{file}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def commit(message)
|
55
|
+
run %Q{svn commit -m "#{message}"}
|
56
|
+
run "svn up"
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def create_remote
|
61
|
+
FileUtils.mkdir(SvnRepo.server_root)
|
62
|
+
|
63
|
+
run "svnadmin create #{remote}"
|
64
|
+
|
65
|
+
File.open(File.join(remote, "conf", "svnserve.conf"), "w") { |f|
|
66
|
+
f.puts "[general]"
|
67
|
+
f.puts "anon-access = write"
|
68
|
+
f.puts "auth-access = write"
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/bob/test.rb
ADDED
data/lib/bob.rb
CHANGED
@@ -13,23 +13,8 @@ require "core_ext/object"
|
|
13
13
|
module Bob
|
14
14
|
# Builds the specified <tt>buildable</tt>. This object must understand
|
15
15
|
# the API described in the README.
|
16
|
-
|
17
|
-
|
18
|
-
# strings with the relevant identifier (a SHA1 hash for git repositories,
|
19
|
-
# a numerical revision for svn repositories, etc).
|
20
|
-
#
|
21
|
-
# You can pass :head as a commit identifier to build the latest commit
|
22
|
-
# in the repo. Examples:
|
23
|
-
#
|
24
|
-
# Bob.build(buildable, :head) # just build the head
|
25
|
-
# Bob.build(buildable, ["4", "3", "2"]) # build revision 4, 3, and 2
|
26
|
-
# # (in that order)
|
27
|
-
# Bob.build(buildable, [:head, "a30fb12"]) # build the HEAD and a30fb12
|
28
|
-
# # commits in this repo.
|
29
|
-
def self.build(buildable, commit_ids)
|
30
|
-
Array(commit_ids).each do |commit_id|
|
31
|
-
Builder.new(buildable, commit_id).build
|
32
|
-
end
|
16
|
+
def self.build(buildable)
|
17
|
+
Builder.new(buildable).build
|
33
18
|
end
|
34
19
|
|
35
20
|
# Directory where the code for the different buildables will be checked out.
|
@@ -6,8 +6,6 @@ class ThreadedBobTest < Test::Unit::TestCase
|
|
6
6
|
|
7
7
|
@repo = GitRepo.new(:test_repo)
|
8
8
|
@repo.create
|
9
|
-
|
10
|
-
@buildable = BuildableStub.call(@repo)
|
11
9
|
end
|
12
10
|
|
13
11
|
test "with a successful threaded build" do
|
@@ -15,18 +13,18 @@ class ThreadedBobTest < Test::Unit::TestCase
|
|
15
13
|
|
16
14
|
repo.add_successful_commit
|
17
15
|
commit_id = repo.commits.last[:identifier]
|
16
|
+
buildable = BuildableStub.for(@repo, commit_id)
|
18
17
|
|
19
18
|
begin
|
20
19
|
Thread.abort_on_exception = true
|
21
20
|
Bob.engine = Bob::Engine::Threaded.new(5)
|
22
|
-
|
21
|
+
buildable.build
|
23
22
|
Bob.engine.wait!
|
24
23
|
|
25
|
-
|
26
|
-
assert_equal
|
27
|
-
assert_equal "Running tests...\n", output
|
24
|
+
assert_equal :successful, buildable.status
|
25
|
+
assert_equal "Running tests...\n", buildable.output
|
28
26
|
|
29
|
-
commit = buildable.
|
27
|
+
commit = buildable.commit_info
|
30
28
|
assert_equal "This commit will work", commit[:message]
|
31
29
|
assert_equal Time.now.min, commit[:committed_at].min
|
32
30
|
ensure
|
data/test/helper.rb
CHANGED
@@ -18,7 +18,7 @@ class Test::Unit::TestCase
|
|
18
18
|
include Bob
|
19
19
|
include Bob::Test
|
20
20
|
|
21
|
-
attr_reader :repo
|
21
|
+
attr_reader :repo
|
22
22
|
|
23
23
|
def setup
|
24
24
|
Bob.logger = Logger.new("/dev/null")
|
@@ -26,5 +26,6 @@ class Test::Unit::TestCase
|
|
26
26
|
Bob.directory = File.expand_path(File.dirname(__FILE__) + "/../tmp")
|
27
27
|
|
28
28
|
FileUtils.rm_rf(Bob.directory) if File.directory?(Bob.directory)
|
29
|
+
FileUtils.mkdir_p(Bob.directory)
|
29
30
|
end
|
30
31
|
end
|
data/test/scm/git_test.rb
CHANGED
@@ -6,8 +6,6 @@ class BobGitTest < Test::Unit::TestCase
|
|
6
6
|
|
7
7
|
@repo = GitRepo.new(:test_repo)
|
8
8
|
@repo.create
|
9
|
-
|
10
|
-
@buildable = BuildableStub.call(@repo)
|
11
9
|
end
|
12
10
|
|
13
11
|
def path(uri, branch="master")
|
@@ -28,58 +26,38 @@ class BobGitTest < Test::Unit::TestCase
|
|
28
26
|
|
29
27
|
commit_id = repo.commits.last[:identifier]
|
30
28
|
|
31
|
-
buildable.
|
32
|
-
|
33
|
-
status, output = buildable.builds[commit_id]
|
34
|
-
assert_equal :successful, status
|
35
|
-
assert_equal "Running tests...\n", output
|
36
|
-
|
37
|
-
assert_equal 1, buildable.metadata.length
|
29
|
+
buildable = BuildableStub.for(@repo, commit_id)
|
30
|
+
buildable.build
|
38
31
|
|
39
|
-
|
40
|
-
assert_equal "
|
41
|
-
|
32
|
+
assert_equal :successful, buildable.status
|
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)
|
42
36
|
end
|
43
37
|
|
44
38
|
test "with a failed build" do
|
45
39
|
repo.add_failing_commit
|
46
40
|
|
47
41
|
commit_id = repo.commits.last[:identifier]
|
42
|
+
buildable = BuildableStub.for(@repo, commit_id)
|
48
43
|
|
49
|
-
buildable.build
|
50
|
-
|
51
|
-
status, output = buildable.builds[commit_id]
|
52
|
-
assert_equal :failed, status
|
53
|
-
assert_equal "Running tests...\n", output
|
54
|
-
|
55
|
-
assert_equal 1, buildable.metadata.length
|
56
|
-
|
57
|
-
commit = buildable.metadata[commit_id]
|
58
|
-
assert_equal "This commit will fail", commit[:message]
|
59
|
-
assert commit[:committed_at].is_a?(Time)
|
60
|
-
end
|
61
|
-
|
62
|
-
test "with multiple commits" do
|
63
|
-
2.times { repo.add_failing_commit }
|
64
|
-
commits = repo.commits.collect { |c| c[:identifier] }
|
65
|
-
|
66
|
-
buildable.build(commits)
|
44
|
+
buildable.build
|
67
45
|
|
68
|
-
assert_equal
|
69
|
-
assert_equal
|
70
|
-
assert_equal
|
46
|
+
assert_equal :failed, buildable.status
|
47
|
+
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)
|
71
50
|
end
|
72
51
|
|
73
52
|
test "can build the head of a repository" do
|
74
53
|
repo.add_failing_commit
|
75
54
|
repo.add_successful_commit
|
76
55
|
|
77
|
-
buildable.
|
56
|
+
buildable = BuildableStub.for(@repo, :head)
|
78
57
|
|
79
|
-
|
58
|
+
buildable.build
|
80
59
|
|
81
|
-
|
82
|
-
assert_equal
|
83
|
-
assert_equal "Running tests...\n", output
|
60
|
+
assert_equal :successful, buildable.status
|
61
|
+
assert_equal "Running tests...\n", buildable.output
|
84
62
|
end
|
85
63
|
end
|
data/test/scm/svn_test.rb
CHANGED
@@ -6,8 +6,6 @@ class BobSvnTest < Test::Unit::TestCase
|
|
6
6
|
|
7
7
|
@repo = SvnRepo.new(:test_repo)
|
8
8
|
@repo.create
|
9
|
-
|
10
|
-
@buildable = BuildableStub.call(@repo)
|
11
9
|
end
|
12
10
|
|
13
11
|
def path(uri)
|
@@ -31,57 +29,35 @@ class BobSvnTest < Test::Unit::TestCase
|
|
31
29
|
test "with a successful build" do
|
32
30
|
repo.add_successful_commit
|
33
31
|
|
34
|
-
buildable.
|
35
|
-
|
36
|
-
assert_equal 1, buildable.metadata.length
|
37
|
-
|
38
|
-
status, output = buildable.builds["2"]
|
39
|
-
assert_equal :successful, status
|
40
|
-
assert_equal "Running tests...\n", output
|
32
|
+
buildable = BuildableStub.for(@repo, "2")
|
33
|
+
buildable.build
|
41
34
|
|
42
|
-
assert_equal
|
43
|
-
|
44
|
-
commit
|
45
|
-
assert
|
46
|
-
assert_equal "This commit will work", commit[:message]
|
35
|
+
assert_equal :successful, buildable.status
|
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)
|
47
39
|
end
|
48
40
|
|
49
41
|
test "with a failed build" do
|
50
42
|
repo.add_failing_commit
|
51
43
|
|
52
|
-
buildable.
|
53
|
-
|
54
|
-
status, output = buildable.builds["2"]
|
55
|
-
assert_equal :failed, status
|
56
|
-
assert_equal "Running tests...\n", output
|
57
|
-
|
58
|
-
assert_equal 1, buildable.metadata.length
|
44
|
+
buildable = BuildableStub.for(@repo, "2")
|
45
|
+
buildable.build
|
59
46
|
|
60
|
-
|
61
|
-
|
62
|
-
assert_equal "This commit will fail",
|
63
|
-
|
64
|
-
|
65
|
-
test "with multiple commits" do
|
66
|
-
repo.add_successful_commit
|
67
|
-
2.times { repo.add_failing_commit }
|
68
|
-
|
69
|
-
buildable.build(repo.commits.collect { |c| c[:identifier] })
|
70
|
-
|
71
|
-
assert_equal 3, buildable.metadata.length
|
72
|
-
assert_equal 3, buildable.builds.length
|
47
|
+
assert_equal :failed, buildable.status
|
48
|
+
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)
|
73
51
|
end
|
74
52
|
|
75
53
|
test "can build the head of a repository" do
|
76
54
|
repo.add_failing_commit
|
77
55
|
repo.add_successful_commit
|
78
56
|
|
79
|
-
buildable.
|
80
|
-
|
81
|
-
assert_equal 1, buildable.builds.length
|
57
|
+
buildable = BuildableStub.for(@repo, :head)
|
58
|
+
buildable.build
|
82
59
|
|
83
|
-
|
84
|
-
assert_equal
|
85
|
-
assert_equal "Running tests...\n", output
|
60
|
+
assert_equal :successful, buildable.status
|
61
|
+
assert_equal "Running tests...\n", buildable.output
|
86
62
|
end
|
87
63
|
end
|
data/test/test_test.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/helper"
|
2
|
+
|
3
|
+
class BobTestTest < Test::Unit::TestCase
|
4
|
+
def assert_scm_repo(repo)
|
5
|
+
repo.destroy
|
6
|
+
repo.create
|
7
|
+
|
8
|
+
assert_equal 1, repo.commits.size
|
9
|
+
assert_equal "First commit", repo.commits.first[:message]
|
10
|
+
|
11
|
+
repo.add_failing_commit
|
12
|
+
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
|
15
|
+
assert repo.short_head
|
16
|
+
|
17
|
+
repo.add_successful_commit
|
18
|
+
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
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_buildable_stub
|
24
|
+
b = BuildableStub.new(:git, "git://github.com/ry/node", "master", "HEAD", "make")
|
25
|
+
|
26
|
+
assert_equal :git, b.scm
|
27
|
+
assert_equal "git://github.com/ry/node", b.uri
|
28
|
+
assert_equal "master", b.branch
|
29
|
+
assert_equal "HEAD", b.commit
|
30
|
+
assert_equal "make", b.build_script
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_scm_repo
|
34
|
+
assert_scm_repo(GitRepo.new(:my_test_project))
|
35
|
+
assert_scm_repo(SvnRepo.new(:my_test_project))
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_buildable_git_repo
|
39
|
+
repo = GitRepo.new(:test_repo)
|
40
|
+
repo.destroy
|
41
|
+
repo.create
|
42
|
+
|
43
|
+
b = BuildableStub.for(repo, repo.head)
|
44
|
+
|
45
|
+
assert_equal :git, b.scm
|
46
|
+
assert_equal "#{Bob.directory}/test_repo", b.uri
|
47
|
+
assert_equal "master", b.branch
|
48
|
+
assert_equal repo.head, b.commit
|
49
|
+
assert_equal "./test", b.build_script
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_buildable_svn_repo
|
53
|
+
repo = SvnRepo.new(:test_repo)
|
54
|
+
repo.destroy
|
55
|
+
repo.create
|
56
|
+
|
57
|
+
b = BuildableStub.for(repo, repo.head)
|
58
|
+
|
59
|
+
assert_equal :svn, b.scm
|
60
|
+
assert_equal "", b.branch
|
61
|
+
assert_equal repo.head, b.commit
|
62
|
+
assert_equal "./test", b.build_script
|
63
|
+
assert_equal "file://#{Bob.directory}/svn/test_repo", b.uri
|
64
|
+
end
|
65
|
+
end
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Nicol\xC3\xA1s Sanguinetti"
|
@@ -33,16 +33,6 @@ dependencies:
|
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: "0"
|
35
35
|
version:
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: sr-bob-test
|
38
|
-
type: :development
|
39
|
-
version_requirement:
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
requirements:
|
42
|
-
- - ">="
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
version: "0"
|
45
|
-
version:
|
46
36
|
- !ruby/object:Gem::Dependency
|
47
37
|
name: contest
|
48
38
|
type: :development
|
@@ -97,12 +87,18 @@ files:
|
|
97
87
|
- lib/bob/scm/abstract.rb
|
98
88
|
- lib/bob/scm/git.rb
|
99
89
|
- lib/bob/scm/svn.rb
|
90
|
+
- lib/bob/test.rb
|
91
|
+
- lib/bob/test/buildable_stub.rb
|
92
|
+
- lib/bob/test/scm/abstract.rb
|
93
|
+
- lib/bob/test/scm/git.rb
|
94
|
+
- lib/bob/test/scm/svn.rb
|
100
95
|
- lib/core_ext/object.rb
|
101
96
|
- test/bob_test.rb
|
102
97
|
- test/engine/threaded_test.rb
|
103
98
|
- test/helper.rb
|
104
99
|
- test/scm/git_test.rb
|
105
100
|
- test/scm/svn_test.rb
|
101
|
+
- test/test_test.rb
|
106
102
|
has_rdoc: true
|
107
103
|
homepage: http://integrityapp.com
|
108
104
|
post_install_message:
|