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.
Files changed (72) hide show
  1. data/README +6 -29
  2. data/lib/buildmaster.rb +0 -2
  3. data/lib/buildmaster/ant_driver.rb +13 -12
  4. data/lib/buildmaster/build_number_file.rb +2 -12
  5. data/lib/buildmaster/buildnumber +1 -1
  6. data/lib/buildmaster/cotta.rb +4 -0
  7. data/lib/buildmaster/cotta/command_error.rb +5 -0
  8. data/lib/buildmaster/cotta/cotta.rb +35 -0
  9. data/lib/buildmaster/cotta/cotta_dir.rb +73 -0
  10. data/lib/buildmaster/cotta/cotta_file.rb +99 -0
  11. data/lib/buildmaster/cotta/file_not_found_error.rb +13 -0
  12. data/lib/buildmaster/cotta/in_memory_system.rb +160 -0
  13. data/lib/buildmaster/cotta/physical_system.rb +64 -0
  14. data/lib/buildmaster/cvs_driver.rb +5 -13
  15. data/lib/buildmaster/file_processor.rb +34 -33
  16. data/lib/buildmaster/java_manifest.rb +3 -3
  17. data/lib/buildmaster/site/site.rb +11 -22
  18. data/lib/buildmaster/site_spec.rb +15 -13
  19. data/lib/buildmaster/source_file_handler.rb +1 -1
  20. data/lib/buildmaster/svn_driver.rb +14 -20
  21. data/lib/buildmaster/{template_exception.rb → template_error.rb} +1 -1
  22. data/lib/buildmaster/template_runner.rb +2 -2
  23. data/lib/buildmaster/templatelets/attribute.rb +1 -1
  24. data/lib/buildmaster/templatelets/href.rb +1 -1
  25. data/lib/buildmaster/templatelets/text.rb +1 -1
  26. data/lib/buildmaster/templatelets/when.rb +1 -1
  27. data/lib/buildmaster/windows.rb +3 -0
  28. data/lib/buildmaster/windows/iis_driver.rb +33 -0
  29. data/lib/buildmaster/windows/sql_server_driver.rb +27 -0
  30. data/test/buildmaster/cotta/content.txt +3 -0
  31. data/test/buildmaster/cotta/cotta_specifications.rb +172 -0
  32. data/test/buildmaster/cotta/physical_system_stub.rb +85 -0
  33. data/test/buildmaster/cotta/system_file_specifications.rb +131 -0
  34. data/test/buildmaster/cotta/tc_cotta.rb +33 -0
  35. data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +23 -0
  36. data/test/buildmaster/cotta/tc_cotta_dir_physical.rb +17 -0
  37. data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +20 -0
  38. data/test/buildmaster/cotta/tc_cotta_file_physical.rb +17 -0
  39. data/test/buildmaster/cotta/tc_in_memory_system.rb +25 -0
  40. data/test/buildmaster/cotta/tc_physical_system.rb +26 -0
  41. data/test/buildmaster/manifest.mf +1 -1
  42. data/test/buildmaster/site/tc_site.rb +58 -34
  43. data/test/buildmaster/site/tc_template_builder.rb +32 -31
  44. data/test/buildmaster/tc_ant_driver.rb +11 -13
  45. data/test/buildmaster/tc_build_number_file.rb +21 -16
  46. data/test/buildmaster/tc_cvs_driver.rb +35 -37
  47. data/test/buildmaster/tc_file_processor.rb +58 -34
  48. data/test/buildmaster/tc_java_manifest.rb +37 -9
  49. data/test/buildmaster/tc_site_spec.rb +20 -15
  50. data/test/buildmaster/tc_source_file_handler.rb +4 -4
  51. data/test/buildmaster/tc_svn_driver.rb +51 -38
  52. data/test/buildmaster/tc_template_runner.rb +19 -18
  53. data/test/buildmaster/tc_tree_to_object.rb +47 -46
  54. data/test/buildmaster/tc_xtemplate.rb +52 -38
  55. data/test/buildmaster/templatelets/common_templatelet_test.rb +9 -8
  56. data/test/buildmaster/templatelets/tc_attribute.rb +26 -23
  57. data/test/buildmaster/templatelets/tc_each.rb +27 -26
  58. data/test/buildmaster/templatelets/tc_href.rb +14 -13
  59. data/test/buildmaster/templatelets/tc_include.rb +11 -4
  60. data/test/buildmaster/templatelets/tc_link.rb +18 -12
  61. data/test/buildmaster/templatelets/tc_text.rb +12 -7
  62. data/test/buildmaster/templatelets/tc_when.rb +11 -5
  63. data/test/buildmaster/windows/tc_iis_driver.rb +29 -0
  64. data/test/buildmaster/windows/tc_sql_server_driver.rb +24 -0
  65. data/test/spec_runner.rb +27 -0
  66. data/test/ts_buildmaster.rb +2 -19
  67. metadata +34 -10
  68. data/lib/buildmaster/release_control.rb +0 -22
  69. data/lib/buildmaster/shell_command.rb +0 -39
  70. data/test/buildmaster/tc_release_control.rb +0 -27
  71. data/test/buildmaster/ts_site.rb +0 -4
  72. data/test/buildmaster/ts_templatelets.rb +0 -10
data/README CHANGED
@@ -20,32 +20,9 @@ A ruby version of the project building and releasing script as described in
20
20
  A simple template engine that can build a website by producing the content pages based on the specified source
21
21
  and decrorating the content pages with a skin.
22
22
 
23
- The supported content sources are <a href="http://www.w3.org/TR/xhtml11/">XHTML</a> and <a href="http://hobix.com/textile/">Textile</a>.
24
-
25
-
26
- == Task List
27
-
28
- * Use RDoc engine (rdoc/template, TemplatePage) to generate template (page
29
- 255)
30
- * Use RDoc format for content
31
-
32
- require 'rdoc/template'
33
- HTML = %{Hello, %name%.
34
- <p>
35
- The reasons you gave were:
36
- <ul>
37
- START:reasons
38
- <li>%reason_name% (%rank%)
39
- END:reasons
40
- </ul>
41
- }
42
- data = {
43
- 'name' => 'Dave Thomas',
44
- 'reasons' => [
45
- { 'reason_name' => 'flexible', 'rank' => '87' },
46
- { 'reason_name' => 'transparent', 'rank' => '76' },
47
- { 'reason_name' => 'fun', 'rank' => '94' },
48
- ]
49
- }
50
- t = TemplatePage.new(HTML)
51
- t.write_html_on(STDOUT, data)
23
+ The supported content sources are <a href="http://www.w3.org/TR/xhtml11/">XHTML</a>
24
+ , <a href="http://hobix.com/textile/">Textile</a> and <a href="http://daringfireball.net/projects/markdown/">Markdown</a>.
25
+
26
+ == Cotta
27
+
28
+ A wrapper of Ruby file operations in an object-oriented way.
@@ -2,8 +2,6 @@ $:.unshift(File.dirname(__FILE__))
2
2
 
3
3
  require 'buildmaster/build_number_file'
4
4
  require 'buildmaster/java_manifest'
5
- require 'buildmaster/shell_command'
6
- require 'buildmaster/release_control'
7
5
  require 'buildmaster/ant_driver'
8
6
  require 'buildmaster/cvs_driver'
9
7
  require 'buildmaster/svn_driver'
@@ -1,14 +1,16 @@
1
1
  module BuildMaster
2
2
 
3
3
  class AntDriver
4
- include Shell
5
4
  def AntDriver.from_file(ant_file)
6
5
  return AntDriver.new(ant_file)
7
6
  end
8
7
 
9
- def initialize(ant_file = nil, &command_runner)
8
+ def initialize(ant_file = nil)
9
+ @cotta = Cotta.new(ant_file.system)
10
10
  @ant_file = ant_file
11
- @ant_home = check_directory(get_environment('ANT_HOME'))
11
+ ant_path = @cotta.environment!('ANT_HOME')
12
+ @ant_home = @cotta.dir(ant_path)
13
+ raise 'ANT_HOME need to point to ANT home directory' unless @ant_home.exists?
12
14
  #ISSUE: what java wants to split up classpath varies from platform to platform
13
15
  #and ruby, following perl, is not too hot at hinting which box it is on.
14
16
  #here I assume ":" except on win32, dos, and netware. Add extra tests here as needed.
@@ -21,19 +23,18 @@ class AntDriver
21
23
  @path_seperator='/'
22
24
  end
23
25
  @java_command = get_java_command()
24
- @ant_options = get_environment_or_default('ANT_OPTS').split(' ')
25
- @ant_arguments = get_environment_or_default('ANT_ARGS').split(' ')
26
+ @ant_options = @cotta.environment('ANT_OPTS').split(' ')
27
+ @ant_arguments = @cotta.environment('ANT_ARGS').split(' ')
26
28
  @ant_options.putsh(ENV['JIKESPATH']) if ENV['JIKESPATH']
27
29
  @classpath=ENV['CLASSPATH']
28
- @command_runner = command_runner
29
30
  end
30
31
 
31
32
  def get_java_command
32
- java_home = get_environment_or_default('JAVA_HOME')
33
+ java_home = @cotta.environment('JAVA_HOME')
33
34
  if java_home
34
35
  command = [java_home, 'bin', 'java'].join(@path_seperator)
35
36
  else
36
- command = get_environment_or_default('JAVA_CMD', 'java')
37
+ command = @cotta.environment('JAVA_CMD', 'java')
37
38
  end
38
39
  return command
39
40
  end
@@ -47,19 +48,19 @@ class AntDriver
47
48
  end
48
49
 
49
50
  def launch(arguments)
50
- local_path = "#{@ant_home}/lib/ant-launcher.jar"
51
+ local_path = "#{@ant_home.path}/lib/ant-launcher.jar"
51
52
  if (@classpath and @classpath.length() > 0)
52
53
  local_path = "#{local_path}#{@class_path_delimiter}#{@classpath}"
53
54
  end
54
55
  all_arguments = Array.new()
55
56
  all_arguments.push(@ant_options)
56
57
  all_arguments.push('-classpath', local_path)
57
- all_arguments.push("-Dant.home=#{@ant_home}")
58
+ all_arguments.push("-Dant.home=#{@ant_home.path}")
58
59
  all_arguments.push('org.apache.tools.ant.launch.Launcher', @ant_arguments);
59
- all_arguments.push('-f', @ant_file) if @ant_file
60
+ all_arguments.push('-f', @ant_file.path) if @ant_file
60
61
  all_arguments.push(arguments)
61
62
  command_line = "#{@java_command} #{all_arguments.join(' ')}"
62
- run_command(command_line)
63
+ @cotta.shell(command_line)
63
64
  end
64
65
 
65
66
  def method_missing(method, *args)
@@ -5,23 +5,13 @@ class BuildNumberFile
5
5
 
6
6
  def initialize(path)
7
7
  @path = path
8
- @number = load_content().chomp!.to_i
8
+ @number = @path.load().strip.to_i
9
9
  end
10
10
 
11
11
  def increase_build
12
12
  @number = @number + 1
13
- save_content
13
+ @path.save(@number)
14
14
  end
15
15
 
16
- private
17
- def load_content()
18
- content = nil
19
- File.open(@path, 'r') {|file| content = file.gets}
20
- return content
21
- end
22
-
23
- def save_content
24
- File.open(@path, 'w') {|file| file.puts @number}
25
- end
26
16
  end
27
17
  end
@@ -1 +1 @@
1
- 15
1
+ 22
@@ -0,0 +1,4 @@
1
+ $:.unshift File.join(File.dirname(__FILE__))
2
+
3
+ require 'cotta/cotta'
4
+ require 'cotta/file_not_found_error'
@@ -0,0 +1,5 @@
1
+ module BuildMaster
2
+ class CommandError < StandardError
3
+
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'physical_system'
4
+ require 'cotta_dir'
5
+ require 'cotta_file'
6
+ require 'pathname'
7
+
8
+ module BuildMaster
9
+ class Cotta
10
+ def initialize(system=PhysicalSystem.new)
11
+ @system = system
12
+ end
13
+
14
+ def shell(command_line)
15
+ puts "$> #{command_line}"
16
+ @system.shell(command_line)
17
+ end
18
+
19
+ def dir(path)
20
+ return CottaDir.new(@system, Pathname.new(path))
21
+ end
22
+
23
+ def file(path)
24
+ return CottaFile.new(@system, Pathname.new(path))
25
+ end
26
+
27
+ def environment!(variable)
28
+ @system.environment!(variable)
29
+ end
30
+
31
+ def environment(variable, default = '')
32
+ @system.environment(variable, default)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,73 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'cotta_file'
4
+
5
+ module BuildMaster
6
+ class CottaDir
7
+ attr_reader :path, :system
8
+
9
+ def initialize(system, path)
10
+ @system = system
11
+ @path = path
12
+ @name = @path.basename.to_s
13
+ end
14
+
15
+ def cotta
16
+ return Cotta.new(@system)
17
+ end
18
+
19
+ def name
20
+ return @path.basename.to_s
21
+ end
22
+
23
+ def exists?
24
+ return @system.dir_exists?(@path)
25
+ end
26
+
27
+ def parent
28
+ if (@name == '.')
29
+ return nil
30
+ end
31
+ return CottaDir.new(@system, @path.parent)
32
+ end
33
+
34
+ def dir(name)
35
+ return CottaDir.new(@system, @path.join(name))
36
+ end
37
+
38
+ def file(name)
39
+ return CottaFile.new(@system, @path.join(name))
40
+ end
41
+
42
+ def mkdirs
43
+ if (not exists?)
44
+ parent.mkdirs
45
+ @system.mkdir @path
46
+ end
47
+ end
48
+
49
+ def delete
50
+ list.each {|children| children.delete}
51
+ @system.delete_dir(@path)
52
+ end
53
+
54
+ def list
55
+ @system.list(@path).collect do |item|
56
+ candidate = dir(item)
57
+ if (not candidate.exists?)
58
+ candidate = file(item)
59
+ end
60
+ candidate
61
+ end
62
+ end
63
+
64
+ def ==(other)
65
+ return @path == other.path && @system == other.system
66
+ end
67
+
68
+ def to_s
69
+ return "#{super}-#@system-#@path"
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,99 @@
1
+ require 'fileutils'
2
+
3
+ module BuildMaster
4
+ class CottaFile
5
+ attr_reader :system, :path
6
+
7
+ def initialize(system, path)
8
+ @system = system
9
+ @path = path
10
+ end
11
+
12
+ def cotta
13
+ return Cotta.new(system)
14
+ end
15
+
16
+ def name
17
+ return @path.basename.to_s
18
+ end
19
+
20
+ def parent
21
+ return CottaDir.new(@system, @path.parent)
22
+ end
23
+
24
+ def extname
25
+ return @path.extname
26
+ end
27
+
28
+ def basename
29
+ return @path.basename(extname).to_s
30
+ end
31
+
32
+ def exists?
33
+ return @system.file_exists?(@path)
34
+ end
35
+
36
+ def copy_to(target_file)
37
+ target_file.parent.mkdirs
38
+ @system.copy(path, target_file.path)
39
+ end
40
+
41
+ def move_to(target_file)
42
+ target_file.parent.mkdirs
43
+ @system.move(path, target_file.path)
44
+ end
45
+
46
+ def save(content = '')
47
+ write {|file| file.printf content.to_s}
48
+ end
49
+
50
+ def write(&block)
51
+ parent.mkdirs
52
+ open('w', &block)
53
+ end
54
+
55
+ def load
56
+ content = nil
57
+ read {|file| content = file.read}
58
+ return content
59
+ end
60
+
61
+ def read(&block)
62
+ open('r', &block)
63
+ end
64
+
65
+ def foreach()
66
+ open('r') do |file|
67
+ file.each {|line| yield line}
68
+ end
69
+ end
70
+
71
+ def delete
72
+ @system.delete_file(@path)
73
+ end
74
+
75
+ def ==(other)
76
+ return false unless other.kind_of? CottaFile
77
+ return @system == other.system && @path == other.path
78
+ end
79
+
80
+ def to_s
81
+ return "#{super}-#@system-#@path"
82
+ end
83
+
84
+ private
85
+
86
+ def open(*args)
87
+ result = f = @system.io(@path, *args)
88
+ if block_given?
89
+ begin
90
+ result = yield f
91
+ ensure
92
+ f.close
93
+ end
94
+ end
95
+ return result
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ module BuildMaster
2
+ class FileNotFoundError < StandardError
3
+ attr_reader :pathname
4
+
5
+ def initialize(pathname)
6
+ @pathname = pathname
7
+ end
8
+
9
+ def message
10
+ "file not found: #{pathname}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,160 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'stringio'
4
+ require 'file_not_found_error'
5
+
6
+ module BuildMaster
7
+ class InMemorySystem
8
+
9
+ attr_reader :executed_commands
10
+
11
+ def initialize
12
+ @executed_commands = []
13
+ @content = ""
14
+ @file_system = Hash.new
15
+ @file_system[Pathname.new('/')] = DirectoryContent.new('/')
16
+ @file_system[Pathname.new('.')] = DirectoryContent.new('.')
17
+ end
18
+
19
+ def shell(command)
20
+ @executed_commands.push(command)
21
+ end
22
+
23
+ def dir_exists?(pathname)
24
+ content = path_content(pathname)
25
+ return !content.nil? && content.directory?
26
+ end
27
+
28
+ def file_exists?(pathname)
29
+ content = path_content(pathname)
30
+ return !content.nil? && content.file?
31
+ end
32
+
33
+ def list(pathname)
34
+ content = path_content(pathname)
35
+ return content.children.collect {|item| item.name}
36
+ end
37
+
38
+ def mkdir(pathname)
39
+ path_content(pathname.parent).add(create_dir(pathname))
40
+ end
41
+
42
+ def io(*args)
43
+ file_content = retrieve_file_content(args[0], args[1])
44
+ return StringIO.new(file_content.content, *args[1, args.size - 1])
45
+ end
46
+
47
+ def copy(source, target)
48
+ file_content = retrieve_file_content(source, 'r').content
49
+ create_file(target).content = file_content.clone
50
+ end
51
+
52
+ def move(source, target)
53
+ copy(source, target)
54
+ delete_file(source)
55
+ end
56
+
57
+ def delete_file(pathname)
58
+ raise Errno::ENOENT.new(pathname) unless file_exists? pathname
59
+ delete_entry(pathname)
60
+ end
61
+
62
+ def delete_dir(pathname)
63
+ raise Errno::ENOENT.new(pathname) unless dir_exists? pathname
64
+ delete_entry(pathname)
65
+ end
66
+
67
+ def to_s
68
+ return 'InMemorySystem'
69
+ end
70
+
71
+ private
72
+ def gather_paths_to_create(pathname)
73
+ paths = Array.new
74
+ path_to_create = pathname
75
+ while (! dir_exists?(path_to_create))
76
+ paths.push(path_to_create)
77
+ path_to_create = path_to_create.parent
78
+ end
79
+ return paths
80
+ end
81
+
82
+ def create_dir(pathname)
83
+ content = DirectoryContent.new(pathname.basename.to_s)
84
+ @file_system[pathname] = content
85
+ return content
86
+ end
87
+
88
+ def create_file(pathname)
89
+ content = FileContent.new(pathname.basename.to_s)
90
+ @file_system[pathname] = content
91
+ return content
92
+ end
93
+
94
+ def path_content(pathname)
95
+ return @file_system[pathname]
96
+ end
97
+
98
+ def retrieve_file_content(pathname, options)
99
+ file_content = path_content(pathname)
100
+ if (file_content.nil?)
101
+ if (options =~ /r/)
102
+ raise Errno::ENOENT.new(pathname)
103
+ end
104
+ parent_dir = pathname.parent
105
+ file_content = create_file(pathname)
106
+ path_content(parent_dir).add(file_content)
107
+ end
108
+ return file_content
109
+ end
110
+
111
+ def delete_entry(pathname)
112
+ @file_system.delete pathname
113
+ @file_system[pathname.parent].delete(pathname.basename.to_s)
114
+ end
115
+
116
+ end
117
+
118
+ class DirectoryContent
119
+ attr_reader :name, :children
120
+
121
+ def initialize(name)
122
+ @name = name
123
+ @children = Array.new
124
+ end
125
+
126
+ def file?
127
+ return false
128
+ end
129
+
130
+ def directory?
131
+ return true
132
+ end
133
+
134
+ def add(content)
135
+ @children.push(content)
136
+ end
137
+
138
+ def delete(name)
139
+ @children.delete_if {|file_content| file_content.name == name}
140
+ end
141
+ end
142
+
143
+ class FileContent
144
+ attr_reader :name, :content
145
+ attr_writer :content
146
+
147
+ def initialize(name)
148
+ @name = name
149
+ @content = ''
150
+ end
151
+
152
+ def file?
153
+ return true
154
+ end
155
+
156
+ def directory?
157
+ return false
158
+ end
159
+ end
160
+ end