BuildMaster 0.8.1 → 0.9.0
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/README +6 -29
- data/lib/buildmaster.rb +0 -2
- data/lib/buildmaster/ant_driver.rb +13 -12
- data/lib/buildmaster/build_number_file.rb +2 -12
- data/lib/buildmaster/buildnumber +1 -1
- data/lib/buildmaster/cotta.rb +4 -0
- data/lib/buildmaster/cotta/command_error.rb +5 -0
- data/lib/buildmaster/cotta/cotta.rb +35 -0
- data/lib/buildmaster/cotta/cotta_dir.rb +73 -0
- data/lib/buildmaster/cotta/cotta_file.rb +99 -0
- data/lib/buildmaster/cotta/file_not_found_error.rb +13 -0
- data/lib/buildmaster/cotta/in_memory_system.rb +160 -0
- data/lib/buildmaster/cotta/physical_system.rb +64 -0
- data/lib/buildmaster/cvs_driver.rb +5 -13
- data/lib/buildmaster/file_processor.rb +34 -33
- data/lib/buildmaster/java_manifest.rb +3 -3
- data/lib/buildmaster/site/site.rb +11 -22
- data/lib/buildmaster/site_spec.rb +15 -13
- data/lib/buildmaster/source_file_handler.rb +1 -1
- data/lib/buildmaster/svn_driver.rb +14 -20
- data/lib/buildmaster/{template_exception.rb → template_error.rb} +1 -1
- data/lib/buildmaster/template_runner.rb +2 -2
- data/lib/buildmaster/templatelets/attribute.rb +1 -1
- data/lib/buildmaster/templatelets/href.rb +1 -1
- data/lib/buildmaster/templatelets/text.rb +1 -1
- data/lib/buildmaster/templatelets/when.rb +1 -1
- data/lib/buildmaster/windows.rb +3 -0
- data/lib/buildmaster/windows/iis_driver.rb +33 -0
- data/lib/buildmaster/windows/sql_server_driver.rb +27 -0
- data/test/buildmaster/cotta/content.txt +3 -0
- data/test/buildmaster/cotta/cotta_specifications.rb +172 -0
- data/test/buildmaster/cotta/physical_system_stub.rb +85 -0
- data/test/buildmaster/cotta/system_file_specifications.rb +131 -0
- data/test/buildmaster/cotta/tc_cotta.rb +33 -0
- data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +23 -0
- data/test/buildmaster/cotta/tc_cotta_dir_physical.rb +17 -0
- data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +20 -0
- data/test/buildmaster/cotta/tc_cotta_file_physical.rb +17 -0
- data/test/buildmaster/cotta/tc_in_memory_system.rb +25 -0
- data/test/buildmaster/cotta/tc_physical_system.rb +26 -0
- data/test/buildmaster/manifest.mf +1 -1
- data/test/buildmaster/site/tc_site.rb +58 -34
- data/test/buildmaster/site/tc_template_builder.rb +32 -31
- data/test/buildmaster/tc_ant_driver.rb +11 -13
- data/test/buildmaster/tc_build_number_file.rb +21 -16
- data/test/buildmaster/tc_cvs_driver.rb +35 -37
- data/test/buildmaster/tc_file_processor.rb +58 -34
- data/test/buildmaster/tc_java_manifest.rb +37 -9
- data/test/buildmaster/tc_site_spec.rb +20 -15
- data/test/buildmaster/tc_source_file_handler.rb +4 -4
- data/test/buildmaster/tc_svn_driver.rb +51 -38
- data/test/buildmaster/tc_template_runner.rb +19 -18
- data/test/buildmaster/tc_tree_to_object.rb +47 -46
- data/test/buildmaster/tc_xtemplate.rb +52 -38
- data/test/buildmaster/templatelets/common_templatelet_test.rb +9 -8
- data/test/buildmaster/templatelets/tc_attribute.rb +26 -23
- data/test/buildmaster/templatelets/tc_each.rb +27 -26
- data/test/buildmaster/templatelets/tc_href.rb +14 -13
- data/test/buildmaster/templatelets/tc_include.rb +11 -4
- data/test/buildmaster/templatelets/tc_link.rb +18 -12
- data/test/buildmaster/templatelets/tc_text.rb +12 -7
- data/test/buildmaster/templatelets/tc_when.rb +11 -5
- data/test/buildmaster/windows/tc_iis_driver.rb +29 -0
- data/test/buildmaster/windows/tc_sql_server_driver.rb +24 -0
- data/test/spec_runner.rb +27 -0
- data/test/ts_buildmaster.rb +2 -19
- metadata +34 -10
- data/lib/buildmaster/release_control.rb +0 -22
- data/lib/buildmaster/shell_command.rb +0 -39
- data/test/buildmaster/tc_release_control.rb +0 -27
- data/test/buildmaster/ts_site.rb +0 -4
- data/test/buildmaster/ts_templatelets.rb +0 -10
@@ -0,0 +1,64 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'file_not_found_error'
|
4
|
+
require 'command_error'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module BuildMaster
|
8
|
+
class PhysicalSystem
|
9
|
+
def initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
def shell(command)
|
13
|
+
raise CommandError.new, command, caller unless system(command)
|
14
|
+
end
|
15
|
+
|
16
|
+
def environment!(variable)
|
17
|
+
value = ENV[variable]
|
18
|
+
raise "#{variable} environment variable not found" unless value
|
19
|
+
return value
|
20
|
+
end
|
21
|
+
|
22
|
+
def environment(variable, default)
|
23
|
+
value = ENV[variable]
|
24
|
+
value = default unless value
|
25
|
+
return value
|
26
|
+
end
|
27
|
+
|
28
|
+
def dir_exists?(dir_path)
|
29
|
+
return FileTest.directory?(dir_path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def file_exists?(file_path)
|
33
|
+
return FileTest.file?(file_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def list(dir_path)
|
37
|
+
Dir.entries(dir_path).find_all {|item| item != '.' && item != '..'}
|
38
|
+
end
|
39
|
+
|
40
|
+
def mkdir(dir_path)
|
41
|
+
Dir.mkdir(dir_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def io(file_path, argument)
|
45
|
+
return File.open(file_path, argument)
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete_file(file_path)
|
49
|
+
return File.delete(file_path)
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete_dir(dir_path)
|
53
|
+
return Dir.delete(dir_path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def copy(source, target)
|
57
|
+
FileUtils.copy(source, target)
|
58
|
+
end
|
59
|
+
|
60
|
+
def move(source, target)
|
61
|
+
FileUtils.move(source, target)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -10,36 +10,28 @@ class CvsInfo
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def CvsInfo.load(folder)
|
13
|
-
return CvsInfo.new(
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
def CvsInfo.read(file)
|
18
|
-
File.open(file) do |file|
|
19
|
-
return file.gets
|
20
|
-
end
|
13
|
+
return CvsInfo.new(folder.file('ROOT').load.strip, folder.file('Repository').load.strip)
|
21
14
|
end
|
22
15
|
|
23
16
|
end
|
24
17
|
|
25
18
|
class CvsDriver
|
26
|
-
include Shell
|
27
19
|
def CvsDriver.from_path(working_directory)
|
28
20
|
return CvsDriver.new(CvsInfo.load("#{working_directory}/CVS"), working_directory)
|
29
21
|
end
|
30
22
|
|
31
|
-
def initialize(cvs_info, working_directory
|
23
|
+
def initialize(cvs_info, working_directory)
|
32
24
|
@cvs_info = cvs_info
|
33
25
|
@working_directory = working_directory
|
34
|
-
@
|
26
|
+
@cotta = @working_directory.cotta
|
35
27
|
end
|
36
28
|
|
37
29
|
def command(command)
|
38
|
-
|
30
|
+
@cotta.shell "cvs -d #{@cvs_info.root} #{command} #{@working_directory.path}"
|
39
31
|
end
|
40
32
|
|
41
33
|
def checkout()
|
42
|
-
|
34
|
+
@cotta.shell("cvs -d #{@cvs_info.root} co -d #{@working_directory.path} #{@cvs_info.repository}")
|
43
35
|
end
|
44
36
|
|
45
37
|
def update(option='')
|
@@ -18,13 +18,13 @@ class FileProcessor
|
|
18
18
|
return result
|
19
19
|
end
|
20
20
|
|
21
|
-
attr_reader :
|
21
|
+
attr_reader :content_file, :target_file
|
22
22
|
|
23
|
-
def initialize(template,
|
23
|
+
def initialize(template, content_file, sitespec)
|
24
24
|
@template = template
|
25
|
-
@
|
25
|
+
@content_file = content_file
|
26
26
|
@sitespec = sitespec
|
27
|
-
extension =
|
27
|
+
extension = content_file.extname
|
28
28
|
if (extension == '.html')
|
29
29
|
@convert_method = 'process_html'
|
30
30
|
elsif (extension == '.textile')
|
@@ -33,53 +33,54 @@ class FileProcessor
|
|
33
33
|
@convert_method = 'process_markdown'
|
34
34
|
end
|
35
35
|
if @convert_method
|
36
|
-
basename =
|
37
|
-
@path = sitespec.relative_to_root(
|
38
|
-
@
|
36
|
+
basename = content_file.basename
|
37
|
+
@path = sitespec.relative_to_root(content_file).parent.join("#{basename}.html")
|
38
|
+
@target_file = sitespec.output_dir.file(@path)
|
39
39
|
else
|
40
|
-
@
|
40
|
+
@target_file = sitespec.output_dir.file(sitespec.relative_to_root(content_file))
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
def FileProcessor::for_request_path(request_path, site_spec)
|
45
45
|
template = site_spec.load_template
|
46
|
-
|
47
|
-
|
48
|
-
extension = relative_to_root.extname.to_s
|
49
|
-
result = nil
|
50
|
-
path_to_content = nil
|
51
|
-
if (extension == '.html')
|
52
|
-
basename = relative_to_root.basename(extension).to_s
|
53
|
-
source_directory = join(site_spec.content_dir, dir)
|
54
|
-
['textile', 'markdown', 'html'].find do |extension_candidate|
|
55
|
-
filename = "#{basename}.#{extension_candidate}"
|
56
|
-
candidate = File.join(source_directory, filename)
|
57
|
-
if (FileTest.file? candidate)
|
58
|
-
path_to_content = candidate
|
59
|
-
true
|
60
|
-
else
|
61
|
-
false
|
62
|
-
end
|
63
|
-
end
|
46
|
+
if (request_path[0,1] == '/')
|
47
|
+
request_path = request_path[1, request_path.length - 1]
|
64
48
|
end
|
65
|
-
|
66
|
-
|
49
|
+
file = site_spec.content_dir.file(request_path)
|
50
|
+
if (file.extname == '.html')
|
51
|
+
file = check_source(file)
|
67
52
|
end
|
68
|
-
return FileProcessor.new(template,
|
53
|
+
return FileProcessor.new(template, file, site_spec)
|
54
|
+
end
|
55
|
+
|
56
|
+
def FileProcessor::check_source(file)
|
57
|
+
result = file
|
58
|
+
basename = file.basename
|
59
|
+
dir = file.parent
|
60
|
+
['textile', 'markdown', 'html'].find do |extension|
|
61
|
+
candidate = dir.file("#{basename}.#{extension}")
|
62
|
+
if (candidate.exists?)
|
63
|
+
result = candidate
|
64
|
+
true
|
65
|
+
else
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return result
|
69
70
|
end
|
70
71
|
|
71
72
|
def is_html?
|
72
|
-
return
|
73
|
+
return target_file.extname == '.html'
|
73
74
|
end
|
74
75
|
|
75
76
|
def write_to_target
|
76
77
|
document = generate_document
|
77
78
|
if (document)
|
78
|
-
|
79
|
+
target_file.write do |file|
|
79
80
|
document.write(file, 0, false, true)
|
80
81
|
end
|
81
82
|
else
|
82
|
-
|
83
|
+
content_file.copy_to(target_file)
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
@@ -89,7 +90,7 @@ class FileProcessor
|
|
89
90
|
|
90
91
|
|
91
92
|
def load_content
|
92
|
-
return
|
93
|
+
return content_file.load
|
93
94
|
end
|
94
95
|
|
95
96
|
def process_textile(textile_content)
|
@@ -11,7 +11,7 @@ class JavaManifest
|
|
11
11
|
def version
|
12
12
|
number = nil
|
13
13
|
build = nil
|
14
|
-
|
14
|
+
@manifest_file.foreach do |line|
|
15
15
|
name_value = NameValue.parse(line)
|
16
16
|
if (name_value.name== "Implementation-Version")
|
17
17
|
number = name_value.value
|
@@ -26,7 +26,7 @@ class JavaManifest
|
|
26
26
|
content = ""
|
27
27
|
number = nil
|
28
28
|
build = nil
|
29
|
-
|
29
|
+
@manifest_file.foreach do |line|
|
30
30
|
name_value = NameValue.parse(line)
|
31
31
|
if (name_value.name== "Implementation-Version")
|
32
32
|
number = name_value.value
|
@@ -38,7 +38,7 @@ class JavaManifest
|
|
38
38
|
content = content + line
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
@manifest_file.write do |file|
|
42
42
|
file.printf(content)
|
43
43
|
end
|
44
44
|
return Version.new(number, build)
|
@@ -60,34 +60,23 @@ require 'buildmaster/site_tester'
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def ensure_directory_exists(dir_name)
|
64
|
-
if (not File.exist?(dir_name))
|
65
|
-
ensure_directory_exists(File.join(dir_name, '..'))
|
66
|
-
Dir.mkdir dir_name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
63
|
def build_directory(out_dir, content_dir, template)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
process_file(content_path, out_dir, content_dir, item)
|
64
|
+
out_dir.mkdirs
|
65
|
+
content_dir.list.each do |item|
|
66
|
+
if (item.name == '.svn' || item.name == 'CVS' || item.name == '_svn')
|
67
|
+
elsif (item.respond_to? 'list')
|
68
|
+
build_directory(out_dir.dir(item.name), item, template)
|
69
|
+
elsif (item.respond_to? 'read')
|
70
|
+
@current_file_name = item
|
71
|
+
process_file(item, out_dir, content_dir, item)
|
80
72
|
@count = @count + 1
|
81
73
|
end
|
82
74
|
end
|
83
75
|
end
|
84
76
|
|
85
|
-
def process_file(
|
86
|
-
print ">> #{
|
87
|
-
|
88
|
-
isIndex = @current_file_name =~ /^index/
|
89
|
-
file_processor = FileProcessor.new(@template, path_to_content, @spec)
|
90
|
-
file_processor.write_to_target
|
77
|
+
def process_file(content_file, out_dir, content_dir, item)
|
78
|
+
print ">> #{content_file.path.to_s}\n"
|
79
|
+
FileProcessor.new(@template, content_file, @spec).write_to_target
|
91
80
|
end
|
92
81
|
|
93
82
|
end
|
@@ -4,6 +4,7 @@ require 'pathname'
|
|
4
4
|
require 'templatelets'
|
5
5
|
require 'tree_to_object'
|
6
6
|
require 'site/template_builder'
|
7
|
+
require 'cotta'
|
7
8
|
|
8
9
|
module BuildMaster
|
9
10
|
|
@@ -11,8 +12,9 @@ module BuildMaster
|
|
11
12
|
attr_reader :output_dir
|
12
13
|
attr_accessor :content_dir, :template, :template_file
|
13
14
|
|
14
|
-
def initialize(file = nil)
|
15
|
-
@root =
|
15
|
+
def initialize(file = nil, cotta = Cotta.new())
|
16
|
+
@root = cotta.file(file).parent if file
|
17
|
+
@cotta = cotta
|
16
18
|
if (block_given?)
|
17
19
|
yield self
|
18
20
|
end
|
@@ -20,17 +22,17 @@ module BuildMaster
|
|
20
22
|
|
21
23
|
def output_dir=(path)
|
22
24
|
if (@root)
|
23
|
-
@output_dir =
|
25
|
+
@output_dir = @root.dir(path)
|
24
26
|
else
|
25
|
-
@output_dir = path
|
27
|
+
@output_dir = @cotta.dir(path)
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
def content_dir=(path)
|
30
32
|
if (@root)
|
31
|
-
@content_dir =
|
33
|
+
@content_dir = @root.dir(path)
|
32
34
|
else
|
33
|
-
@content_dir = path
|
35
|
+
@content_dir = @cotta.dir(path)
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
@@ -44,7 +46,7 @@ module BuildMaster
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def validate_inputs
|
47
|
-
validate_dir(
|
49
|
+
validate_dir(content_dir, :content_dir)
|
48
50
|
end
|
49
51
|
|
50
52
|
def load_template
|
@@ -69,17 +71,17 @@ module BuildMaster
|
|
69
71
|
if (@template)
|
70
72
|
return @template
|
71
73
|
else
|
72
|
-
return
|
74
|
+
return @template_file.load
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
76
78
|
def load_document(path)
|
77
|
-
|
79
|
+
content_dir.file(path).read {|file| REXML::Document.new(file)}
|
78
80
|
end
|
79
81
|
|
80
82
|
def relative_to_root(path)
|
81
|
-
to = path_name(path)
|
82
|
-
from = path_name(@content_dir)
|
83
|
+
to = path_name(path.path.to_s)
|
84
|
+
from = path_name(@content_dir.path.to_s)
|
83
85
|
return to.relative_path_from(from)
|
84
86
|
end
|
85
87
|
|
@@ -109,10 +111,10 @@ module BuildMaster
|
|
109
111
|
if not directory
|
110
112
|
raise "Directory for #{symbol.id2name} not specified"
|
111
113
|
end
|
112
|
-
if not
|
114
|
+
if not directory.exists?
|
113
115
|
raise "Directory for #{symbol.id2name} -- <#{directory}> does not exist"
|
114
116
|
end
|
115
|
-
if not
|
117
|
+
if not directory.exists?
|
116
118
|
raise "<#{directory}> should be a directory for #{symbol.id2name}"
|
117
119
|
end
|
118
120
|
end
|
@@ -17,7 +17,7 @@ class SourceFileHandler < WEBrick::HTTPServlet::AbstractServlet
|
|
17
17
|
@config = server.config
|
18
18
|
@logger = @config[:Logger]
|
19
19
|
@spec = spec
|
20
|
-
@delegate = WEBrick::HTTPServlet::FileHandler.new(server, spec.content_dir, true)
|
20
|
+
@delegate = WEBrick::HTTPServlet::FileHandler.new(server, spec.content_dir.path, true)
|
21
21
|
end
|
22
22
|
|
23
23
|
def service(req, res)
|
@@ -4,15 +4,16 @@ require 'rexml/document'
|
|
4
4
|
module BuildMaster
|
5
5
|
|
6
6
|
class SvnInfo
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :work_dir, :repository_root
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
|
9
|
+
def initialize(work_dir)
|
10
|
+
@work_dir = work_dir
|
11
|
+
entries = work_dir.dir('.svn').file('entries')
|
12
|
+
analyze_entry_file(entries)
|
12
13
|
end
|
13
14
|
|
14
|
-
def analyze_entry_file(
|
15
|
-
|
15
|
+
def analyze_entry_file(entry_file)
|
16
|
+
@repository_root = entry_file.read do |file|
|
16
17
|
parse_xml_load_repository_root(file)
|
17
18
|
end
|
18
19
|
end
|
@@ -21,26 +22,20 @@ class SvnInfo
|
|
21
22
|
def parse_xml_load_repository_root(file)
|
22
23
|
xml = REXML::Document.new(file)
|
23
24
|
xml.root.each_element_with_attribute('name', '', 1) do |element|
|
24
|
-
|
25
|
+
return element.attributes['repos']
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
29
30
|
|
30
|
-
class SvnDriver
|
31
|
-
include Shell
|
32
|
-
|
31
|
+
class SvnDriver
|
33
32
|
def SvnDriver::from_path(directory)
|
34
33
|
return SvnDriver.new(SvnInfo.new(directory))
|
35
34
|
end
|
36
35
|
|
37
|
-
def initialize(svn_info
|
36
|
+
def initialize(svn_info)
|
38
37
|
@svn_info = svn_info
|
39
|
-
|
40
|
-
@command_runner = command_runner
|
41
|
-
else
|
42
|
-
@command_runner = Proc.new {|command| run(command)}
|
43
|
-
end
|
38
|
+
@system = svn_info.work_dir.system
|
44
39
|
end
|
45
40
|
|
46
41
|
def status
|
@@ -56,11 +51,11 @@ class SvnDriver
|
|
56
51
|
end
|
57
52
|
|
58
53
|
def tag(tag_name)
|
59
|
-
|
54
|
+
@system.shell("svn copy #{@svn_info.repository_root}/trunk #{@svn_info.repository_root}/tags/#{tag_name} -m \"ruby buildmaster\"")
|
60
55
|
end
|
61
56
|
|
62
57
|
def checkout(output)
|
63
|
-
|
58
|
+
@system.shell("svn checkout #{@svn_info.repository_root}/trunk #{output}")
|
64
59
|
end
|
65
60
|
|
66
61
|
def command(command)
|
@@ -68,9 +63,8 @@ class SvnDriver
|
|
68
63
|
end
|
69
64
|
|
70
65
|
private
|
71
|
-
|
72
66
|
def command_for_path(svn_command, argument='')
|
73
|
-
|
67
|
+
@system.shell("svn #{svn_command} #{@svn_info.work_dir.path}#{argument}")
|
74
68
|
end
|
75
69
|
end
|
76
70
|
|