rbuilder 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  Gem::manage_gems
3
3
  require 'rake/gempackagetask'
4
- NEXT_VERSION = "0.0.3"
4
+ NEXT_VERSION = "0.0.4"
5
5
 
6
6
 
7
7
  desc 'Running all unit tests'
@@ -3,9 +3,8 @@ $: << File.join(File.expand_path(File.dirname(__FILE__)),'..','rbuilder')
3
3
  require 'libs'
4
4
  require 'gui'
5
5
  require 'optparse'
6
-
6
+ VERSION = 0.0.4
7
7
  USAGE_MESSAGE = %Q{
8
- usage #{$0} <working_dir> <build_command>
9
8
 
10
9
  This program is an automatic builder for any build environment
11
10
  (ant, make, rake... the lot). It accepts parameters for the
@@ -24,23 +23,28 @@ or 'make' or 'ant' but can be anything.
24
23
 
25
24
  The build command is expected to have an exit value of 0 when
26
25
  the build is successfull and anything else when the build is
27
- not successfull.
26
+ not successful.
27
+
28
+ usage #{$0} [<working_dir> <build_command>]
29
+ or #{$0} [options]
30
+ where options are:
28
31
  }
29
32
 
30
- def usage
31
- puts USAGE_MESSAGE
33
+ def usage(parser)
34
+ puts parser
32
35
  exit(1)
33
36
  end
34
37
 
35
38
  configuration_file = nil
36
39
  parser = OptionParser.new do |opts|
37
40
  opts.banner = USAGE_MESSAGE
38
- opts.on("-h", '--help', "show this message") { usage }
39
- opts.on("-c", '--configfile file', "use configuration file ") { |file| configuration_file = file }
41
+ opts.on("-h", '--help', "show this message") { usage(parser) }
42
+ opts.on("-v", '--version', "show version") { p VERSION }
43
+ opts.on("-c", '--configfile file', "use configuration file") { |file| configuration_file = file }
40
44
  end
41
45
 
42
46
  rest = parser.parse ARGV
43
- usage unless configuration_file || (rest[0] && rest[1])
47
+ usage(parser) unless configuration_file || (rest[0] && rest[1])
44
48
 
45
49
  builder = Builder.new
46
50
  build_configuration = BuildConfiguration.new(builder)
@@ -33,14 +33,18 @@ class Build
33
33
  changed!
34
34
  end
35
35
 
36
- def revision
37
- return reason.revision
36
+ def revision_number
37
+ return reason.revision_number
38
38
  end
39
39
 
40
40
  def committer
41
41
  return reason.committer
42
42
  end
43
43
 
44
+ def timestamp
45
+ return reason.timestamp
46
+ end
47
+
44
48
  def green?
45
49
  status == BuildStatus.ok
46
50
  end
@@ -17,10 +17,9 @@ class BuildCommand
17
17
 
18
18
  def run_command(build_result)
19
19
  orig_stderr = $stderr.dup
20
- run_process commandline do |stdout,stderr|
21
- while !(stdout.eof? && stderr.eof?)
20
+ run_process commandline do |stdout|
21
+ while !(stdout.eof?)
22
22
  report(build_result, stdout)
23
- report(build_result, stderr)
24
23
  end
25
24
  end
26
25
  return $? == 0
@@ -35,36 +34,9 @@ class BuildCommand
35
34
  end
36
35
  end
37
36
 
38
- def run_process(*cmd)
39
- outpipe = IO::pipe
40
- errorpipe = IO::pipe
41
-
42
- pid = fork{
43
- # child
44
- outpipe.first.close
45
- STDOUT.reopen(outpipe.last)
46
- outpipe.last.close
47
-
48
- errorpipe.first.close
49
- STDERR.reopen(errorpipe.last)
50
- errorpipe.last.close
51
-
52
- exec(*cmd)
53
- exit!($?)
54
- }
55
-
56
- outpipe.last.close
57
- errorpipe.last.close
58
- Process.waitpid(pid)
59
- pi = [outpipe.first, errorpipe.first]
60
- if defined? yield
61
- begin
62
- return yield(*pi)
63
- ensure
64
- pi.each{|p| p.close unless p.closed?}
65
- end
66
- end
67
- pi
37
+ def run_process(*cmd, &block)
38
+ IO.popen("#{cmd} 2>&1", &block)
39
+ return $? == 0
68
40
  end
69
41
 
70
42
  attr_reader :commandline
@@ -19,10 +19,11 @@ module Gui
19
19
  def update
20
20
  iterator[0] = self
21
21
  iterator[1] = build.archive
22
- iterator[2] = build.revision.to_s
23
- iterator[3] = build.committer.to_s
24
- iterator[4] = build.status.to_s
25
- iterator[5] = build.summary.to_s
22
+ iterator[2] = build.revision_number.to_s
23
+ iterator[3] = build.timestamp.to_s
24
+ iterator[4] = build.committer.to_s
25
+ iterator[5] = build.status.to_s
26
+ iterator[6] = build.summary.to_s
26
27
  end
27
28
  Colors = {BuildStatus.ok => 'green', BuildStatus.failed => 'red', BuildStatus.building => 'yellow'}
28
29
  def update_renderer_style(renderer)
@@ -9,17 +9,17 @@ module Gui
9
9
  end
10
10
 
11
11
  def initialize_ui_elements
12
- @tree_store = Gtk::TreeStore.new(BuildListViewEntry,String,String,String,String,String)
12
+ @tree_store = Gtk::TreeStore.new(BuildListViewEntry,String,String,String,String,String,String)
13
13
  @tree_view = Gtk::TreeView.new(tree_store)
14
14
  @gtk_container = Gtk::ScrolledWindow.new
15
15
  gtk_container << tree_view
16
16
 
17
17
  renderer = Gtk::CellRendererText.new
18
- %w{Archive Revision Committer Status Summary}.each_with_index do |column, index|
18
+ %w{Archive Revision Time Committer Status Summary}.each_with_index do |column, index|
19
19
  col = Gtk::TreeViewColumn.new(column, renderer, :text => index+1)
20
20
  col.resizable=true
21
21
  col.set_cell_data_func(renderer) do |col, renderer, model, iter|
22
- iter[0].update_renderer_style(renderer)
22
+ iter[0].update_renderer_style(renderer) if iter[0]
23
23
  end
24
24
 
25
25
  tree_view.append_column(col)
@@ -1,21 +1,36 @@
1
1
 
2
2
  class RevisionCommitted
3
- attr_reader :committer, :revision
4
- def initialize(revision, committer)
3
+ def initialize(revision)
5
4
  @revision = revision
6
- @committer = committer
7
5
  end
8
6
 
9
7
  def self.from_source_control_status(status)
10
- self.new(status.revision, status.committer)
8
+ self.new(status)
9
+ end
10
+
11
+ def committer
12
+ return @revision.committer
13
+ end
14
+
15
+ def revision_number
16
+ return @revision.revision
17
+ end
18
+
19
+ def timestamp
20
+ return @revision.timestamp
11
21
  end
12
22
 
13
23
  def ==(other)
14
24
  return false unless other.class == self.class
15
- self.revision == other.revision && self.committer == other.committer
25
+ self.revision == other.revision
16
26
  end
17
27
 
18
28
  def to_s
19
- "Revision #{revision} committed by #{committer}"
29
+ "Revision #{revision_number} committed by #{committer}"
20
30
  end
31
+
32
+ protected
33
+ attr_reader :revision
34
+
35
+
21
36
  end
@@ -1,9 +1,11 @@
1
1
  module SourceControl
2
2
  class Status
3
- attr_reader :revision, :committer
4
- def initialize(revision, committer)
3
+ attr_reader :revision, :committer, :timestamp, :comment
4
+ def initialize(revision, committer, timestamp = "", comment = "")
5
5
  @revision = revision
6
6
  @committer = committer
7
+ @timestamp = timestamp
8
+ @comment = comment
7
9
  end
8
10
 
9
11
 
@@ -14,7 +16,7 @@ module SourceControl
14
16
  end
15
17
 
16
18
  def to_s
17
- "(#{revision},#{committer})"
19
+ "(#{revision},#{committer}, #{timestamp}, #{comment})"
18
20
  end
19
21
  def inspect
20
22
  "Status#{to_s}"
@@ -28,7 +28,7 @@ module SourceControl
28
28
  end
29
29
 
30
30
  def parse_archive(repo_info)
31
- repo_info =~ /^(Repository Root: )(.*)$/
31
+ return 'unknown archive' unless repo_info =~ /^(Repository Root: )(.*)$/
32
32
  line = $2
33
33
  line = strip_server(line)
34
34
  return strip_trunk(line)
@@ -36,8 +36,10 @@ module SourceControl
36
36
 
37
37
  def get_info
38
38
  info_output = run_info
39
- revision = info_output[/^Revision:(.*)$/].split(':')[1]
40
- committer = info_output[/^Last Changed Author:(.*)$/].split(':')[1].strip
39
+ revision_line = info_output[/^Revision:(.*)$/]
40
+ revision = revision_line && revision_line.split(':')[1] || 0
41
+ author_line = info_output[/^Last Changed Author:(.*)$/]
42
+ committer = author_line && author_line.split(':')[1].strip || 'unknown'
41
43
  Status.new(revision.to_i, committer)
42
44
  end
43
45
 
@@ -25,21 +25,21 @@ module Gui
25
25
  class TestBuilderListViewEntry < Test::Unit::TestCase
26
26
  attr_reader :build, :entry, :tree_view_iterator
27
27
  def setup
28
- @build = stub(:add_observer => nil, :archive => 'the_archive', :revision => 123, :status => BuildStatus.building, :summary => nil, :committer => 'westgeer')
28
+ @build = stub(:add_observer => nil, :archive => 'the_archive', :revision_number => 123, :timestamp => '10 o clock', :status => BuildStatus.building, :summary => nil, :committer => 'westgeer')
29
29
  @entry = BuildListViewEntry.new(build)
30
30
  @tree_view_iterator = []
31
31
  end
32
32
 
33
33
  def test_attach_to_tree_view_iterator_sets_revision_and_status_values
34
34
  entry.attach_to(tree_view_iterator)
35
- assert_equal [entry, 'the_archive', '123', 'westgeer', 'building', ''], tree_view_iterator
35
+ assert_equal [entry, 'the_archive', '123', '10 o clock', 'westgeer', 'building', ''], tree_view_iterator
36
36
  end
37
37
 
38
38
  def test_update_updates_tree_view_iterator
39
39
  entry.attach_to(tree_view_iterator)
40
- build.stubs(:archive => 'some_archive', :revision => 300, :status => BuildStatus.ok,:summary => 'done', :committer => 'westgeer')
40
+ build.stubs(:archive => 'some_archive', :revision_number => 300, :timestamp => '11 o clock', :status => BuildStatus.ok,:summary => 'done', :committer => 'westgeer')
41
41
  entry.update
42
- assert_equal [entry, 'some_archive', '300', 'westgeer', 'ok', 'done'], tree_view_iterator
42
+ assert_equal [entry, 'some_archive', '300', '11 o clock', 'westgeer', 'ok', 'done'], tree_view_iterator
43
43
  end
44
44
  end
45
45
 
@@ -6,23 +6,22 @@ require 'rbuilder/source_control'
6
6
 
7
7
 
8
8
  class TestSourceControlCheck < Test::Unit::TestCase
9
- attr_reader :svn, :source_control, :builder
9
+ attr_reader :svn, :source_control, :build_description
10
10
 
11
11
  def setup
12
12
  @svn = stub(:working_dir => 'the_working_dir', :archive => 'the_archive_name')
13
13
  @source_control = SourceControl.new(svn)
14
- @builder = mock
14
+ @build_description = mock
15
15
  end
16
16
 
17
-
18
- def expect_new_revision_committed_on_builder(last_commit)
17
+ def expect_new_revision_committed_on_build_description(last_commit)
19
18
  svn.stubs(:get_info).returns(last_commit)
20
- builder.expects(:new_revision_committed).with(last_commit)
19
+ build_description.expects(:new_revision_committed).with(last_commit)
21
20
  end
22
21
 
23
- def expect_no_new_revision_committed_on_builder(last_commit)
22
+ def expect_no_new_revision_committed_on_build_description(last_commit)
24
23
  svn.stubs(:get_info).returns(last_commit)
25
- builder.expects(:new_revision_committed).with(last_commit).never
24
+ build_description.expects(:new_revision_committed).with(last_commit).never
26
25
  end
27
26
 
28
27
  def test_working_dir
@@ -35,18 +34,18 @@ class TestSourceControlCheck < Test::Unit::TestCase
35
34
  end
36
35
 
37
36
  def test_generates_new_revision_committed_when_source_control_status_has_changed
38
- expect_new_revision_committed_on_builder(SourceControl::Status.new(35, 'westgeest'))
39
- source_control.report_change_to(builder)
37
+ expect_new_revision_committed_on_build_description(SourceControl::Status.new(35, 'westgeest'))
38
+ source_control.report_change_to(build_description)
40
39
 
41
- expect_new_revision_committed_on_builder(SourceControl::Status.new(36, 'harry'))
42
- source_control.report_change_to(builder)
40
+ expect_new_revision_committed_on_build_description(SourceControl::Status.new(36, 'harry'))
41
+ source_control.report_change_to(build_description)
43
42
  end
44
43
 
45
44
  def test_generates_nothing_when_source_control_revision_was_not_changed
46
- expect_new_revision_committed_on_builder(SourceControl::Status.new(35, 'westgeest'))
47
- source_control.report_change_to(builder)
45
+ expect_new_revision_committed_on_build_description(SourceControl::Status.new(35, 'westgeest'))
46
+ source_control.report_change_to(build_description)
48
47
 
49
- expect_no_new_revision_committed_on_builder(SourceControl::Status.new(35, 'westgeest'))
50
- source_control.report_change_to(builder)
48
+ expect_no_new_revision_committed_on_build_description(SourceControl::Status.new(35, 'westgeest'))
49
+ source_control.report_change_to(build_description)
51
50
  end
52
51
  end
@@ -42,15 +42,31 @@ module SourceControl
42
42
  svn.stubs(:run_info).returns svn_output_for(:repo_root => 'file:///home/svn/rbuilder/trunk')
43
43
  assert_equal 'home/svn/rbuilder', svn.archive
44
44
  end
45
+
46
+ def test_archive_is_unknown_if_archive_line_not_in_svn_output
47
+ svn.stubs(:run_info).returns svn_output_without_author_for(:repo_root => 'file:///home/svn/rbuilder/trunk')
48
+ assert_equal 'unknown archive', svn.archive
49
+ end
45
50
 
46
51
  def test_info_returns_info_struct_with_revision_and_committer
47
- svn.stubs(:run_info).returns svn_output_for(:author => 'westgeest', :revision => '1')
52
+ svn.stubs(:run_log).with('repos').returns svn_log_output_for(:revision => '10', :comment => 'fix')
53
+ svn.stubs(:run_info).returns svn_output_for(:author => 'westgeest', :revision => '1', :repo_root => 'repos')
48
54
  assert_equal Status.new(1, 'westgeest'), svn.get_info
49
- svn.stubs(:run_info).returns svn_output_for(:author => 'harry', :revision => '2')
55
+ svn.stubs(:run_log).with('repos').returns svn_log_output_for(:revision => '10', :comment => 'fix')
56
+ svn.stubs(:run_info).returns svn_output_for(:author => 'harry', :revision => '2', :repo_root => 'repos')
50
57
  assert_equal Status.new(2, 'harry'), svn.get_info
51
58
  end
52
59
 
60
+ def test_author_returns_unknown_when_author_not_in_svn_output
61
+ svn.stubs(:run_info).returns svn_output_without_author_for()
62
+ assert_equal Status.new(0, 'unknown'), svn.get_info
63
+ end
64
+
53
65
  private
66
+ def svn_log_output_for(args = {})
67
+ args = {:revision => '1', :comment => 'some comment'}.merge args
68
+
69
+ end
54
70
  def svn_output_for(args = {})
55
71
  args = {:repo_root => 'svn+ssh://yosemite/home/svn/rbuilder', :author => 'harry', :revision => '2'}.merge args
56
72
  %Q{
@@ -66,5 +82,16 @@ module SourceControl
66
82
  Last Changed Date: 2007-12-21 23:31:23 +0100 (Fri, 21 Dec 2007)
67
83
  }.gsub(/^ +/,'')
68
84
  end
85
+ def svn_output_without_author_for(args = {})
86
+ args = {:repo_root => 'svn+ssh://yosemite/home/svn/rbuilder', :author => 'harry', :revision => '2'}.merge args
87
+ %Q{
88
+ Path: .
89
+ URL: svn+ssh://yosemite/home/svn/rbuilder/trunk
90
+ Repository UUID: f125cab9-89fe-4a65-988d-b833e1c403a1
91
+ Node Kind: directory
92
+ Schedule: normal
93
+ Last Changed Date: 2007-12-21 23:31:23 +0100 (Fri, 21 Dec 2007)
94
+ }.gsub(/^ +/,'')
95
+ end
69
96
  end
70
97
  end
@@ -49,11 +49,25 @@ class TestBuildRevision < Test::Unit::TestCase
49
49
  @build = Build.new(nil,nil,stub_reason)
50
50
  end
51
51
 
52
- def test_is_retreived_from_reason
53
- stub_reason.stubs(:revision).returns 233
54
- assert_equal 233, build.revision
55
- stub_reason.stubs(:revision).returns 455
56
- assert_equal 455, build.revision
52
+ def test_is_number_is_retreived_from_reason
53
+ stub_reason.stubs(:revision_number).returns 233
54
+ assert_equal 233, build.revision_number
55
+ stub_reason.stubs(:revision_number).returns 455
56
+ assert_equal 455, build.revision_number
57
+ end
58
+
59
+ def test_is_committer_is_retreived_from_reason
60
+ stub_reason.stubs(:committer).returns 'rob'
61
+ assert_equal 'rob', build.committer
62
+ stub_reason.stubs(:committer).returns 'henk'
63
+ assert_equal 'henk', build.committer
64
+ end
65
+
66
+ def test_is_timestamp_is_retreived_from_reason
67
+ stub_reason.stubs(:timestamp).returns '10 o clock'
68
+ assert_equal '10 o clock', build.timestamp
69
+ stub_reason.stubs(:timestamp).returns '11:30'
70
+ assert_equal '11:30', build.timestamp
57
71
  end
58
72
 
59
73
  end
@@ -39,7 +39,7 @@ class TestBuildCommandWithRealCommandPrintingOnStdout < Test::Unit::TestCase
39
39
  attr_reader :expected_output_lines, :build_command, :build_report
40
40
  def setup
41
41
  @expected_output_lines = ["line_1\n","line_2\n"]
42
- @build_command = BuildCommand.new("echo line_1;echo line_2")
42
+ @build_command = BuildCommand.new(%Q{ruby -e 'puts "line_1";puts "line_2"; exit(0)'})
43
43
  @build_report = stub_everything
44
44
  end
45
45
 
@@ -51,13 +51,16 @@ class TestBuildDescription_RunABuild < Test::Unit::TestCase
51
51
  assert_equal [build,build2], build_description.builds
52
52
  end
53
53
 
54
- def test_receiving_a_commit_runs_a_build_with_reason_receiving_a_commit
54
+ def test_receiving_a_new_revision_comitted_runs_a_build_with_reason_receiving_a_commit
55
55
  revision = 234
56
56
  committer = 'westgeer'
57
- expected_reason = RevisionCommitted.new(revision,committer)
57
+ timestamp = "timestamp"
58
+ comments = "comments"
59
+ status = SourceControl::Status.new(revision,committer, timestamp, comments)
60
+ expected_reason = RevisionCommitted.from_source_control_status(status)
58
61
  build.expects :run
59
62
  build_description.expects(:create_build).with(expected_reason).returns build
60
- build_description.new_revision_committed(SourceControl::Status.new(revision,committer))
63
+ build_description.new_revision_committed(status)
61
64
  end
62
65
 
63
66
  end
@@ -41,6 +41,7 @@ class TestBuilder < Test::Unit::TestCase
41
41
  end
42
42
 
43
43
  end
44
+
44
45
  class TestBuildViewUpdates < Test::Unit::TestCase
45
46
 
46
47
  def test_updates_views_afer_each_iteration
@@ -3,28 +3,30 @@ require 'rubygems'
3
3
  require 'mocha'
4
4
  require File.join(File.dirname(__FILE__), 'builder_test_env')
5
5
  require 'revision_committed'
6
+ require 'source_control'
6
7
 
7
8
  class TestRevisionCommitted < Test::Unit::TestCase
9
+ attr_reader :status, :event, :revision, :committer, :timestamp
10
+ def setup
11
+ @revision = 123
12
+ @committer = 'westgeer'
13
+ @timestamp = "ten o clock"
14
+ @status = SourceControl::Status.new(revision, committer, timestamp)
15
+ @event = RevisionCommitted.new(status)
16
+ end
17
+
8
18
  def test_has_revision_and_committer
9
- revision = 123
10
- committer = 'westgeer'
11
- event = RevisionCommitted.new(revision, committer)
12
- assert_equal revision, event.revision
19
+ assert_equal revision, event.revision_number
13
20
  assert_equal committer, event.committer
21
+ assert_equal timestamp, event.timestamp
14
22
  end
15
23
 
16
24
  def test_equals
17
- assert_equal RevisionCommitted.new(1,'westgeest'), RevisionCommitted.new(1,'westgeest')
18
- assert_equal RevisionCommitted.new(2,'westgeest'), RevisionCommitted.new(2,'westgeest')
19
- assert_equal RevisionCommitted.new(1,'blah'), RevisionCommitted.new(1,'blah')
20
-
21
- assert_not_equal RevisionCommitted.new(1,'blah'), RevisionCommitted.new(1,'westgeest')
22
- assert_not_equal RevisionCommitted.new(1,'westgeest'), RevisionCommitted.new(1,'blah')
23
- assert_not_equal RevisionCommitted.new(2,'westgeest'), RevisionCommitted.new(1,'westgeest')
24
- assert_not_equal RevisionCommitted.new(1,'westgeest'), RevisionCommitted.new(2,'westgeest')
25
+ assert_equal RevisionCommitted.new(status), RevisionCommitted.new(status)
26
+ assert_not_equal RevisionCommitted.new(status), RevisionCommitted.new(SourceControl::Status.new('',''))
25
27
  end
26
28
 
27
29
  def test_equals_with_other_type_of_object_returns_false
28
- assert_not_equal RevisionCommitted.new(1,'westgeest'), Object.new
30
+ assert_not_equal RevisionCommitted.new(status), Object.new
29
31
  end
30
32
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: rbuilder
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.3
7
- date: 2008-02-15 00:00:00 +01:00
6
+ version: 0.0.4
7
+ date: 2008-04-03 00:00:00 +02:00
8
8
  summary: A Ruby auto build tool like build-o-matic for running on a desktop pc
9
9
  require_paths:
10
10
  - rbuilder