rbuilder 0.0.3 → 0.0.4

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
@@ -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