BuildMaster 1.0.9 → 1.1.9

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.
Files changed (76) hide show
  1. data/lib/buildmaster/algorithms.rb +3 -0
  2. data/lib/buildmaster/algorithms/opn_compare.rb +108 -0
  3. data/lib/buildmaster/cotta/cotta_dir.rb +7 -4
  4. data/lib/buildmaster/cotta/cotta_file.rb +5 -2
  5. data/lib/buildmaster/cotta/in_memory_system.rb +28 -4
  6. data/lib/buildmaster/project/java.rb +4 -0
  7. data/lib/buildmaster/project/java/class_path.rb +0 -0
  8. data/lib/buildmaster/project/java/javac.rb +9 -0
  9. data/lib/buildmaster/project/mysql_served_driver.rb +15 -0
  10. data/lib/buildmaster/project/pscp_driver.rb +0 -1
  11. data/lib/buildmaster/project/svn_driver.rb +4 -4
  12. data/lib/buildmaster/project/svn_server_driver.rb +18 -0
  13. data/lib/buildmaster/project/svn_status_info.rb +45 -42
  14. data/lib/buildmaster/site/content_engine_repository.rb +9 -0
  15. data/lib/buildmaster/site/file_processor.rb +5 -1
  16. data/lib/buildmaster/site/site.rb +11 -4
  17. data/lib/buildmaster/site/site_server.rb +1 -1
  18. data/lib/buildmaster/site/templatelets/href.rb +1 -1
  19. data/lib/buildmaster/version +1 -1
  20. data/test/buildmaster/algorithms/tc_opn_compare.rb +44 -0
  21. data/test/buildmaster/common/tc_properties.rb +8 -8
  22. data/test/buildmaster/common/tc_tree_to_object.rb +8 -8
  23. data/test/buildmaster/cotta/cotta_dir_behaviors.rb +167 -0
  24. data/test/buildmaster/cotta/cotta_file_behaviors.rb +127 -0
  25. data/test/buildmaster/cotta/cotta_specifications.rb +20 -0
  26. data/test/buildmaster/cotta/file_system_behaviors.rb +167 -0
  27. data/test/buildmaster/cotta/tc_command_interface.rb +6 -6
  28. data/test/buildmaster/cotta/tc_command_runner.rb +5 -5
  29. data/test/buildmaster/cotta/tc_cotta.rb +12 -12
  30. data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +17 -17
  31. data/test/buildmaster/cotta/tc_cotta_dir_physical.rb +5 -5
  32. data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +8 -9
  33. data/test/buildmaster/cotta/tc_cotta_file_physical.rb +11 -8
  34. data/test/buildmaster/cotta/tc_cotta_zip_support.rb +9 -9
  35. data/test/buildmaster/cotta/tc_in_memory_system.rb +7 -7
  36. data/test/buildmaster/cotta/tc_io_chain.rb +3 -3
  37. data/test/buildmaster/cotta/tc_pathname.rb +6 -6
  38. data/test/buildmaster/cotta/tc_physical_system.rb +7 -8
  39. data/test/buildmaster/project/tc_ant_driver.rb +8 -8
  40. data/test/buildmaster/project/tc_build_number_file.rb +5 -5
  41. data/test/buildmaster/project/tc_cvs_driver.rb +9 -9
  42. data/test/buildmaster/project/tc_java_manifest.rb +9 -11
  43. data/test/buildmaster/project/tc_release.rb +12 -12
  44. data/test/buildmaster/project/tc_server_manager.rb +8 -8
  45. data/test/buildmaster/project/tc_svn_driver.rb +18 -13
  46. data/test/buildmaster/project/tc_svn_status_info.rb +8 -8
  47. data/test/buildmaster/project/tc_version_number_file.rb +6 -6
  48. data/test/buildmaster/project/windows/tc_iis_driver.rb +4 -4
  49. data/test/buildmaster/project/windows/tc_sql_server_driver.rb +2 -2
  50. data/test/buildmaster/site/content/tc_content_engine_repository.rb +5 -5
  51. data/test/buildmaster/site/tc_element_processor_by_name.rb +4 -4
  52. data/test/buildmaster/site/tc_file_processor.rb +8 -9
  53. data/test/buildmaster/site/tc_site.rb +23 -7
  54. data/test/buildmaster/site/tc_site_server.rb +2 -2
  55. data/test/buildmaster/site/tc_site_spec.rb +5 -5
  56. data/test/buildmaster/site/tc_source_file_handler.rb +2 -2
  57. data/test/buildmaster/site/tc_template_builder.rb +22 -11
  58. data/test/buildmaster/site/tc_template_error.rb +2 -2
  59. data/test/buildmaster/site/tc_template_runner.rb +4 -4
  60. data/test/buildmaster/site/tc_templatelets.rb +4 -4
  61. data/test/buildmaster/site/tc_xtemplate.rb +5 -5
  62. data/test/buildmaster/site/templatelets/tc_attribute.rb +6 -6
  63. data/test/buildmaster/site/templatelets/tc_code.rb +10 -10
  64. data/test/buildmaster/site/templatelets/tc_each.rb +3 -3
  65. data/test/buildmaster/site/templatelets/tc_href.rb +7 -7
  66. data/test/buildmaster/site/templatelets/tc_include.rb +3 -3
  67. data/test/buildmaster/site/templatelets/tc_link.rb +6 -6
  68. data/test/buildmaster/site/templatelets/tc_text.rb +4 -4
  69. data/test/buildmaster/site/templatelets/tc_when.rb +4 -4
  70. data/test/tmp/svn_test/repository/db/revprops/0 +1 -1
  71. data/test/tmp/svn_test/repository/db/revprops/1 +1 -1
  72. data/test/tmp/svn_test/repository/db/revprops/2 +1 -1
  73. data/test/tmp/svn_test/repository/db/revprops/3 +1 -1
  74. data/test/tmp/svn_test/repository/db/revprops/4 +1 -1
  75. data/test/tmp/svn_test/repository/db/uuid +1 -1
  76. metadata +60 -46
@@ -0,0 +1,3 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'algorithms')
2
+
3
+ require 'opn_compare'
@@ -0,0 +1,108 @@
1
+ module BuildMaster
2
+ module Algorithms
3
+ class OpnCompare
4
+ def initialize(a, b)
5
+ @a = a
6
+ @b = b
7
+ @m = a.size
8
+ @n = b.size
9
+ end
10
+
11
+ def compare
12
+ delta = @n - @m
13
+ diff = SequenceDiff.new
14
+ fp = NegativeIndexArray.new(@m + 1, @n + 1) {|index| EditAction.new(nil, nil, -1 - index, -1) }
15
+ p = -1
16
+ begin
17
+ p = p + 1
18
+ (-p..(delta - 1)).each do |k|
19
+ fp[k] = snake(k, max(fp[k-1], fp[k+1]))
20
+ end
21
+ ((delta + p)..(delta - 1)).each do |k|
22
+ fp[k] = snake(k, max(fp[k-1], fp[k+1]))
23
+ end
24
+ fp[delta] = snake(delta, max(fp[delta-1], fp[delta+1]))
25
+ end until fp[delta].y == @n
26
+ return diff
27
+ end
28
+
29
+ private
30
+ def snake(k, edit)
31
+ y = edit.y
32
+ x = y - k
33
+ snake = edit
34
+ while (x < @m and y < @n and @a[x] == @b[y]) do
35
+ x = x + 1
36
+ y = y + 1
37
+ snake = EditType::COPY.apply_to(snake)
38
+ end
39
+ snake
40
+ end
41
+
42
+ def max(fp1, fp2)
43
+ if (fp1.y < fp2.y)
44
+ EditType::DELETE.apply_to(fp2)
45
+ else
46
+ EditType::ADD.apply_to(fp1)
47
+ end
48
+ end
49
+ end
50
+
51
+ class NegativeIndexArray
52
+ attr_reader :max_negative, :max_positive
53
+ def initialize(max_negative, max_positive, &block)
54
+ @max_negative = max_negative
55
+ @max_positive = max_positive
56
+ @array = Array.new(max_negative + max_positive + 1) {|index| block.call(index - max_negative)}
57
+ end
58
+
59
+ def [](index)
60
+ @array[index + max_negative]
61
+ end
62
+
63
+ def []=(index, value)
64
+ @array[index + max_negative] = value
65
+ end
66
+ end
67
+
68
+ class SequenceDiff
69
+ def edits
70
+ []
71
+ end
72
+ end
73
+
74
+ class EditAction
75
+ attr_reader :type, :x, :y
76
+ def initialize(last, type, x, y)
77
+ @last = last
78
+ @type = type
79
+ @x = x
80
+ @y = y
81
+ end
82
+
83
+ def inspect
84
+ if @type
85
+ "#{@type.name}(#@x, #@y) - )-" + @last.inspect
86
+ else
87
+ 'nil'
88
+ end
89
+ end
90
+ end
91
+
92
+ class EditType
93
+ attr_reader :name
94
+ def initialize(name, deltx, delty)
95
+ @name = name
96
+ @deltx = deltx
97
+ @delty = delty
98
+ end
99
+
100
+ def apply_to(edit_action)
101
+ EditAction.new(edit_action, self, edit_action.x + @deltx, edit_action.y + @delty)
102
+ end
103
+ ADD = EditType.new('add', 0, 1)
104
+ DELETE = EditType.new('delete', 1, 0)
105
+ COPY = EditType.new('copy', 1, 1)
106
+ end
107
+ end
108
+ end
@@ -88,20 +88,23 @@ class CottaDir
88
88
  @system.copy_dir(@path, target.path)
89
89
  end
90
90
 
91
- def archive(target = nil)
91
+ def archive(target = nil, &block)
92
92
  unless target
93
93
  target = parent.file("#{name}.tar")
94
94
  end
95
95
  target.write_binary do |io|
96
96
  writer = Gem::Package::TarWriter.new(io) do |tar_io|
97
- archive_dir(tar_io, self)
97
+ archive_dir(tar_io, self, &block)
98
98
  end
99
99
  end
100
100
  target
101
101
  end
102
102
 
103
- def archive_dir(tar_io, dir)
103
+ def archive_dir(tar_io, dir, &block)
104
104
  dir.list.each do |child|
105
+ if (block_given? and not yield child)
106
+ next
107
+ end
105
108
  stat = child.stat
106
109
  entry_name = child.relative_path_from(self).to_s
107
110
  mode = stat.mode
@@ -113,7 +116,7 @@ class CottaDir
113
116
  end
114
117
  elsif (stat.directory?)
115
118
  tar_io.mkdir(entry_name, mode)
116
- archive_dir(tar_io, child)
119
+ archive_dir(tar_io, child, &block)
117
120
  end
118
121
  end
119
122
  end
@@ -7,7 +7,7 @@ require 'io_chain'
7
7
  module BuildMaster
8
8
  class CottaFile
9
9
  include IoChain
10
- attr_reader :system, :path
10
+ attr_reader :system, :path, :stat
11
11
 
12
12
  def initialize(system, path)
13
13
  @path = path
@@ -33,6 +33,10 @@ class CottaFile
33
33
  def stat
34
34
  @system.file_stat(@path)
35
35
  end
36
+
37
+ def older_than?(file)
38
+ (stat <=> file.stat) == -1
39
+ end
36
40
 
37
41
  def exists?
38
42
  return @system.file_exists?(@path)
@@ -132,7 +136,6 @@ windows system because it does no put the system on binary mode
132
136
  end
133
137
  end
134
138
 
135
-
136
139
  def foreach()
137
140
  open('r') do |file|
138
141
  file.each {|line| yield line}
@@ -45,12 +45,12 @@ class InMemorySystem
45
45
 
46
46
  def dir_stat(pathname)
47
47
  check_dir_exists(pathname)
48
- ContentStat.new(path_content(pathname))
48
+ path_content(pathname).stat
49
49
  end
50
50
 
51
51
  def file_stat(pathname)
52
52
  check_file_exists(pathname)
53
- ContentStat.new(path_content(pathname))
53
+ path_content(pathname).stat
54
54
  end
55
55
 
56
56
  def list(pathname)
@@ -167,6 +167,9 @@ class InMemorySystem
167
167
  end
168
168
  file_content = create_file(pathname)
169
169
  end
170
+ if (options =~ /w/)
171
+ file_content.touch
172
+ end
170
173
  return file_content
171
174
  end
172
175
 
@@ -178,11 +181,12 @@ class InMemorySystem
178
181
  end
179
182
 
180
183
  class DirectoryContent
181
- attr_reader :name, :children
184
+ attr_reader :name, :children, :stat
182
185
 
183
186
  def initialize(name)
184
187
  @name = name
185
188
  @children = Array.new
189
+ @stat = ContentStat.new(self)
186
190
  end
187
191
 
188
192
  def file?
@@ -209,12 +213,13 @@ class DirectoryContent
209
213
  end
210
214
 
211
215
  class FileContent
212
- attr_reader :name, :content
216
+ attr_reader :name, :content, :stat
213
217
  attr_writer :content
214
218
 
215
219
  def initialize(name)
216
220
  @name = name
217
221
  @content = ''
222
+ @stat = ContentStat.new(self)
218
223
  end
219
224
 
220
225
  def file?
@@ -234,11 +239,18 @@ class FileContent
234
239
  source_path = parent_dir.join(name)
235
240
  system.copy_file(source_path, target_path)
236
241
  end
242
+
243
+ def touch
244
+ @stat.touch
245
+ end
237
246
  end
238
247
 
239
248
  class ContentStat
249
+ attr_reader :mtime
250
+
240
251
  def initialize(content)
241
252
  @content = content
253
+ @mtime = Time.new
242
254
  end
243
255
 
244
256
  def mode
@@ -256,5 +268,17 @@ class ContentStat
256
268
  def directory?
257
269
  @content.directory?
258
270
  end
271
+
272
+ def touch
273
+ @mtime = Time.new
274
+ end
275
+
276
+ def writable?
277
+ true
278
+ end
279
+
280
+ def <=> stat
281
+ mtime <=> stat.mtime
282
+ end
259
283
  end
260
284
  end
@@ -0,0 +1,4 @@
1
+ $:.unshift(__FILE__, 'java')
2
+
3
+ require 'javac'
4
+ require 'class_path'
@@ -0,0 +1,9 @@
1
+ $:.unshift (File.join(File.dirname(__FILE__), '..', '..'))
2
+
3
+ require 'cotta'
4
+
5
+ module BuildMaster
6
+ class Javac
7
+
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ require '../cotta'
2
+ require '../cotta/in_memory_system'
3
+
4
+ module BuildMaster
5
+ class MySqlServerDriver
6
+ def initialize(mysqld)
7
+ @mysqld = mysqld
8
+ @cotta = mysqld.cotta
9
+ end
10
+
11
+ def start
12
+ @cotta.shell("#{@mysqld.path} --console")
13
+ end
14
+ end
15
+ end
@@ -1,7 +1,6 @@
1
1
  $:.unshift File.join(File.dirname(__FILE__), '..')
2
2
 
3
3
  require 'cotta'
4
- require 'cotta/in_memory_system'
5
4
 
6
5
  module BuildMaster
7
6
  class PscpDriver
@@ -3,7 +3,6 @@ $:.unshift File.dirname(__FILE__)
3
3
  require 'stringio'
4
4
  require 'rexml/document'
5
5
  require 'svn_status_info'
6
- require 'common/properties'
7
6
 
8
7
  module BuildMaster
9
8
 
@@ -81,9 +80,10 @@ class SvnDriver
81
80
 
82
81
  private
83
82
  def load_svn_info
84
- properties = @cotta.shell("svn info #{work_dir.path}") {|io| BuildMaster::Common::Properties.parse_io(io)}
85
- @repository_root = properties['Repository Root']
86
- @user = properties['Last Changed Author']
83
+ xml = REXML::Document.new(@cotta.shell("svn info #{work_dir.path} --xml"))
84
+ @repository_root = REXML::XPath.first(xml, '/info/entry/repository/root').text
85
+ @repository_url = REXML::XPath.first(xml, '/info/entry/url').text
86
+ @user = REXML::XPath.first(xml, '/info/entry/commit/author').text
87
87
  end
88
88
 
89
89
  def command_for_path(svn_command, argument='', &callback)
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..')
2
+
3
+ require '../cotta'
4
+ require '../cotta/in_memory_system'
5
+
6
+ module BuildMaster
7
+ class SvnServerDriver
8
+ def initialize(server, repository)
9
+ @server = server
10
+ @repository = repository
11
+ @cotta = @server.cotta
12
+ end
13
+
14
+ def start
15
+ @cotta.shell("#{@server.path} -d -r #{@repository.path}")
16
+ end
17
+ end
18
+ end
@@ -2,53 +2,56 @@ require 'rexml/document'
2
2
  require 'pathname'
3
3
 
4
4
  module BuildMaster
5
+ class SvnStatusInfo
6
+ def initialize
7
+ @changes = Array.new
8
+ end
5
9
 
6
- class SvnStatusInfo
7
- def initialize
8
- @changes = Array.new
9
- end
10
-
11
- def add(entry)
12
- @changes.push entry
13
- end
10
+ def add(entry)
11
+ @changes.push entry
12
+ end
14
13
 
15
- def SvnStatusInfo::parse_xml(content)
16
- info = SvnStatusInfo.new
17
- xml = REXML::Document.new(content)
18
- REXML::XPath.each(xml, '/status/target/entry') do |entry|
19
- info.add Entry.new(entry)
14
+ def SvnStatusInfo::parse_xml(content)
15
+ info = SvnStatusInfo.new
16
+ xml = REXML::Document.new(content)
17
+ REXML::XPath.each(xml, '/status/target/entry') do |entry|
18
+ info.add Entry.new(entry)
19
+ end
20
+ return info
20
21
  end
21
- return info
22
- end
23
-
24
- def unversioned
25
- entries('unversioned')
26
- end
27
-
28
- def missing
29
- entries('missing')
30
- end
31
-
32
- def entries(status)
33
- @changes.select {|entry| entry.status == status}
34
- end
35
-
36
- class Entry
37
- attr_reader :path
38
-
39
- def initialize(element)
40
- @element = element
41
- @path = Pathname.new @element.attributes['path']
22
+
23
+ def unversioned
24
+ entries('unversioned')
25
+ end
26
+
27
+ def missing
28
+ entries('missing')
42
29
  end
43
-
44
- def basename
45
- @path.basename
30
+
31
+ def entries(status)
32
+ @changes.select {|entry|
33
+ entry.status == status
34
+ }
46
35
  end
47
-
48
- def status
49
- status_element = @element.elements.find {|element| element.name == 'wc-status'}
50
- status_element.attributes['item']
36
+
37
+ class Entry
38
+ attr_reader :path
39
+
40
+ def initialize(element)
41
+ @element = element
42
+ @path = Pathname.new @element.attributes['path']
43
+ end
44
+
45
+ def basename
46
+ @path.basename
47
+ end
48
+
49
+ def status
50
+ status_element = @element.elements.find {|element|
51
+ element.name == 'wc-status'
52
+ }
53
+ status_element.attributes['item']
54
+ end
51
55
  end
52
56
  end
53
- end
54
57
  end