BuildMaster 1.0.9 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
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