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.
- data/lib/buildmaster/algorithms.rb +3 -0
- data/lib/buildmaster/algorithms/opn_compare.rb +108 -0
- data/lib/buildmaster/cotta/cotta_dir.rb +7 -4
- data/lib/buildmaster/cotta/cotta_file.rb +5 -2
- data/lib/buildmaster/cotta/in_memory_system.rb +28 -4
- data/lib/buildmaster/project/java.rb +4 -0
- data/lib/buildmaster/project/java/class_path.rb +0 -0
- data/lib/buildmaster/project/java/javac.rb +9 -0
- data/lib/buildmaster/project/mysql_served_driver.rb +15 -0
- data/lib/buildmaster/project/pscp_driver.rb +0 -1
- data/lib/buildmaster/project/svn_driver.rb +4 -4
- data/lib/buildmaster/project/svn_server_driver.rb +18 -0
- data/lib/buildmaster/project/svn_status_info.rb +45 -42
- data/lib/buildmaster/site/content_engine_repository.rb +9 -0
- data/lib/buildmaster/site/file_processor.rb +5 -1
- data/lib/buildmaster/site/site.rb +11 -4
- data/lib/buildmaster/site/site_server.rb +1 -1
- data/lib/buildmaster/site/templatelets/href.rb +1 -1
- data/lib/buildmaster/version +1 -1
- data/test/buildmaster/algorithms/tc_opn_compare.rb +44 -0
- data/test/buildmaster/common/tc_properties.rb +8 -8
- data/test/buildmaster/common/tc_tree_to_object.rb +8 -8
- data/test/buildmaster/cotta/cotta_dir_behaviors.rb +167 -0
- data/test/buildmaster/cotta/cotta_file_behaviors.rb +127 -0
- data/test/buildmaster/cotta/cotta_specifications.rb +20 -0
- data/test/buildmaster/cotta/file_system_behaviors.rb +167 -0
- data/test/buildmaster/cotta/tc_command_interface.rb +6 -6
- data/test/buildmaster/cotta/tc_command_runner.rb +5 -5
- data/test/buildmaster/cotta/tc_cotta.rb +12 -12
- data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +17 -17
- data/test/buildmaster/cotta/tc_cotta_dir_physical.rb +5 -5
- data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +8 -9
- data/test/buildmaster/cotta/tc_cotta_file_physical.rb +11 -8
- data/test/buildmaster/cotta/tc_cotta_zip_support.rb +9 -9
- data/test/buildmaster/cotta/tc_in_memory_system.rb +7 -7
- data/test/buildmaster/cotta/tc_io_chain.rb +3 -3
- data/test/buildmaster/cotta/tc_pathname.rb +6 -6
- data/test/buildmaster/cotta/tc_physical_system.rb +7 -8
- data/test/buildmaster/project/tc_ant_driver.rb +8 -8
- data/test/buildmaster/project/tc_build_number_file.rb +5 -5
- data/test/buildmaster/project/tc_cvs_driver.rb +9 -9
- data/test/buildmaster/project/tc_java_manifest.rb +9 -11
- data/test/buildmaster/project/tc_release.rb +12 -12
- data/test/buildmaster/project/tc_server_manager.rb +8 -8
- data/test/buildmaster/project/tc_svn_driver.rb +18 -13
- data/test/buildmaster/project/tc_svn_status_info.rb +8 -8
- data/test/buildmaster/project/tc_version_number_file.rb +6 -6
- data/test/buildmaster/project/windows/tc_iis_driver.rb +4 -4
- data/test/buildmaster/project/windows/tc_sql_server_driver.rb +2 -2
- data/test/buildmaster/site/content/tc_content_engine_repository.rb +5 -5
- data/test/buildmaster/site/tc_element_processor_by_name.rb +4 -4
- data/test/buildmaster/site/tc_file_processor.rb +8 -9
- data/test/buildmaster/site/tc_site.rb +23 -7
- data/test/buildmaster/site/tc_site_server.rb +2 -2
- data/test/buildmaster/site/tc_site_spec.rb +5 -5
- data/test/buildmaster/site/tc_source_file_handler.rb +2 -2
- data/test/buildmaster/site/tc_template_builder.rb +22 -11
- data/test/buildmaster/site/tc_template_error.rb +2 -2
- data/test/buildmaster/site/tc_template_runner.rb +4 -4
- data/test/buildmaster/site/tc_templatelets.rb +4 -4
- data/test/buildmaster/site/tc_xtemplate.rb +5 -5
- data/test/buildmaster/site/templatelets/tc_attribute.rb +6 -6
- data/test/buildmaster/site/templatelets/tc_code.rb +10 -10
- data/test/buildmaster/site/templatelets/tc_each.rb +3 -3
- data/test/buildmaster/site/templatelets/tc_href.rb +7 -7
- data/test/buildmaster/site/templatelets/tc_include.rb +3 -3
- data/test/buildmaster/site/templatelets/tc_link.rb +6 -6
- data/test/buildmaster/site/templatelets/tc_text.rb +4 -4
- data/test/buildmaster/site/templatelets/tc_when.rb +4 -4
- data/test/tmp/svn_test/repository/db/revprops/0 +1 -1
- data/test/tmp/svn_test/repository/db/revprops/1 +1 -1
- data/test/tmp/svn_test/repository/db/revprops/2 +1 -1
- data/test/tmp/svn_test/repository/db/revprops/3 +1 -1
- data/test/tmp/svn_test/repository/db/revprops/4 +1 -1
- data/test/tmp/svn_test/repository/db/uuid +1 -1
- metadata +60 -46
@@ -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
|
-
|
48
|
+
path_content(pathname).stat
|
49
49
|
end
|
50
50
|
|
51
51
|
def file_stat(pathname)
|
52
52
|
check_file_exists(pathname)
|
53
|
-
|
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
|
File without changes
|
@@ -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
|
@@ -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
|
-
|
85
|
-
@repository_root =
|
86
|
-
@
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
45
|
-
@
|
30
|
+
|
31
|
+
def entries(status)
|
32
|
+
@changes.select {|entry|
|
33
|
+
entry.status == status
|
34
|
+
}
|
46
35
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|