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