BuildMaster 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,14 +1,19 @@
1
- = BuildMaster - Building and releasing project and site with Ruby
1
+ = BuildMaster[http://buildmaster.rubyforge.org] - Building and releasing project and site with Ruby
2
2
 
3
3
  Homepage:: http://buildmaster.rubyforge.org
4
4
  Author:: Shane
5
5
  Copyright:: (c) 2006 BuildMaster on rubyforge
6
6
  License:: Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
7
7
 
8
- BuildMaster is a project that targets project building, releasing and site building.
8
+ BuildMaster[http://buildmaster.rubyforge.org] is a project that targets project building,
9
+ releasing and site building.
9
10
 
10
- Please post your question at http://groups.google.com/group/buildmaster/ or
11
- send email to buildmaster@googlegroups.com
11
+ This rDoc is intended for you the check out the available methods on the objects. For a full
12
+ document of what BuildMaster[http://buildmaster.rubyforge.org] can do for you, please check out
13
+ BuildMaster[http://buildmaster.rubyforge.org]'s home page:
14
+ http://buildmaster.rubyforge.org
15
+
16
+ Please post your question at mailing-list[http://groups.google.com/group/buildmaster/]
12
17
 
13
18
  == Project Building and Releasing
14
19
 
@@ -20,8 +25,8 @@ A ruby version of the project building and releasing script as described in
20
25
  A simple template engine that can build a website by producing the content pages based on the specified source
21
26
  and decrorating the content pages with a skin.
22
27
 
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>.
28
+ The supported content sources are XHTML[http://www.w3.org/TR/xhtml11/], Textile[http://hobix.com/textile/] and
29
+ Markdown[http://daringfireball.net/projects/markdown/].
25
30
 
26
31
  == Cotta
27
32
 
@@ -54,7 +54,7 @@ class AntDriver
54
54
  end
55
55
  all_arguments = Array.new()
56
56
  all_arguments.push(@ant_options)
57
- all_arguments.push('-classpath', local_path)
57
+ all_arguments.push('-classpath', "\"#{local_path}\"")
58
58
  all_arguments.push("-Dant.home=#{@ant_home.path}")
59
59
  all_arguments.push('org.apache.tools.ant.launch.Launcher', @ant_arguments);
60
60
  all_arguments.push('-f', @ant_file.path) if @ant_file
@@ -1 +1 @@
1
- 22
1
+ 41
@@ -51,6 +51,16 @@ class CottaDir
51
51
  @system.delete_dir(@path)
52
52
  end
53
53
 
54
+ def move_to(target)
55
+ target.parent.mkdirs
56
+ @system.move_dir(@path, target.path)
57
+ end
58
+
59
+ def copy_to(target)
60
+ target.parent.mkdirs
61
+ @system.copy_dir(@path, target.path)
62
+ end
63
+
54
64
  def list
55
65
  @system.list(@path).collect do |item|
56
66
  candidate = dir(item)
@@ -35,12 +35,12 @@ class CottaFile
35
35
 
36
36
  def copy_to(target_file)
37
37
  target_file.parent.mkdirs
38
- @system.copy(path, target_file.path)
38
+ @system.copy_file(path, target_file.path)
39
39
  end
40
40
 
41
41
  def move_to(target_file)
42
42
  target_file.parent.mkdirs
43
- @system.move(path, target_file.path)
43
+ @system.move_file(path, target_file.path)
44
44
  end
45
45
 
46
46
  def save(content = '')
@@ -14,11 +14,22 @@ class InMemorySystem
14
14
  @file_system = Hash.new
15
15
  @file_system[Pathname.new('/')] = DirectoryContent.new('/')
16
16
  @file_system[Pathname.new('.')] = DirectoryContent.new('.')
17
+ @output_map = Hash.new
17
18
  end
18
19
 
19
20
  def shell(command)
20
21
  @executed_commands.push(command)
21
22
  end
23
+
24
+ def shell_output(command)
25
+ result = @output_map[command]
26
+ raise "#{command} not found in expectation" unless result
27
+ return result
28
+ end
29
+
30
+ def output_for_command(command, output)
31
+ @output_map[command] = output
32
+ end
22
33
 
23
34
  def dir_exists?(pathname)
24
35
  content = path_content(pathname)
@@ -45,15 +56,35 @@ class InMemorySystem
45
56
  end
46
57
 
47
58
  def copy(source, target)
59
+ copy_file(source, target)
60
+ end
61
+
62
+ def copy_file(source, target)
48
63
  file_content = retrieve_file_content(source, 'r').content
49
64
  create_file(target).content = file_content.clone
50
65
  end
51
66
 
52
67
  def move(source, target)
68
+ move_file(source, target)
69
+ end
70
+
71
+ def move_file(source, target)
53
72
  copy(source, target)
54
73
  delete_file(source)
55
74
  end
56
75
 
76
+ def copy_dir(source, target)
77
+ mkdir(target)
78
+ path_content(source).children.each do |item|
79
+ item.copy_to_dir(self, source, target)
80
+ end
81
+ end
82
+
83
+ def move_dir(source, target)
84
+ copy_dir(source, target)
85
+ delete_dir(source)
86
+ end
87
+
57
88
  def delete_file(pathname)
58
89
  raise Errno::ENOENT.new(pathname) unless file_exists? pathname
59
90
  delete_entry(pathname)
@@ -87,6 +118,8 @@ class InMemorySystem
87
118
 
88
119
  def create_file(pathname)
89
120
  content = FileContent.new(pathname.basename.to_s)
121
+ parent_dir = pathname.parent
122
+ path_content(parent_dir).add(content)
90
123
  @file_system[pathname] = content
91
124
  return content
92
125
  end
@@ -101,9 +134,7 @@ class InMemorySystem
101
134
  if (options =~ /r/)
102
135
  raise Errno::ENOENT.new(pathname)
103
136
  end
104
- parent_dir = pathname.parent
105
137
  file_content = create_file(pathname)
106
- path_content(parent_dir).add(file_content)
107
138
  end
108
139
  return file_content
109
140
  end
@@ -138,6 +169,12 @@ class DirectoryContent
138
169
  def delete(name)
139
170
  @children.delete_if {|file_content| file_content.name == name}
140
171
  end
172
+
173
+ def copy_to_dir(system, parent_dir, target_dir)
174
+ source_path = parent_dir.join(name)
175
+ target_path = target_dir.join(name)
176
+ system.copy_dir(source_path, target_path)
177
+ end
141
178
  end
142
179
 
143
180
  class FileContent
@@ -156,5 +193,11 @@ class FileContent
156
193
  def directory?
157
194
  return false
158
195
  end
196
+
197
+ def copy_to_dir(system, parent_dir, target_dir)
198
+ target_path = target_dir.join(name)
199
+ source_path = parent_dir.join(name)
200
+ system.copy_file(source_path, target_path)
201
+ end
159
202
  end
160
203
  end
@@ -10,9 +10,15 @@ class PhysicalSystem
10
10
  end
11
11
 
12
12
  def shell(command)
13
+ puts "$> #{command}"
13
14
  raise CommandError.new, command, caller unless system(command)
14
15
  end
15
16
 
17
+ def shell_output(command)
18
+ puts "$> #{command}"
19
+ `#{command}`
20
+ end
21
+
16
22
  def environment!(variable)
17
23
  value = ENV[variable]
18
24
  raise "#{variable} environment variable not found" unless value
@@ -53,12 +59,20 @@ class PhysicalSystem
53
59
  return Dir.delete(dir_path)
54
60
  end
55
61
 
56
- def copy(source, target)
62
+ def copy_file(source, target)
57
63
  FileUtils.copy(source, target)
58
64
  end
59
65
 
60
- def move(source, target)
66
+ def move_file(source, target)
61
67
  FileUtils.move(source, target)
62
68
  end
69
+
70
+ def copy_dir(source, target)
71
+ FileUtils.copy_entry(source, target)
72
+ end
73
+
74
+ def move_dir(source, target)
75
+ FileUtils.mv(source, target)
76
+ end
63
77
  end
64
78
  end
@@ -3,39 +3,30 @@ require 'rexml/document'
3
3
 
4
4
  module BuildMaster
5
5
 
6
- class SvnInfo
7
- attr_reader :work_dir, :repository_root
8
-
9
- def initialize(work_dir)
10
- @work_dir = work_dir
11
- entries = work_dir.dir('.svn').file('entries')
12
- analyze_entry_file(entries)
13
- end
14
-
15
- def analyze_entry_file(entry_file)
16
- @repository_root = entry_file.read do |file|
17
- parse_xml_load_repository_root(file)
18
- end
19
- end
20
-
21
- private
22
- def parse_xml_load_repository_root(file)
23
- xml = REXML::Document.new(file)
24
- xml.root.each_element_with_attribute('name', '', 1) do |element|
25
- return element.attributes['repos']
26
- end
27
- end
28
-
29
- end
30
-
31
6
  class SvnDriver
32
7
  def SvnDriver::from_path(directory)
33
- return SvnDriver.new(SvnInfo.new(directory))
8
+ return SvnDriver.new(directory)
34
9
  end
35
10
 
36
- def initialize(svn_info)
37
- @svn_info = svn_info
38
- @system = svn_info.work_dir.system
11
+ attr_reader :work_dir, :repository_url
12
+
13
+ def initialize(work_dir, repository_root = nil, repository_url = nil)
14
+ @system = work_dir.system
15
+ @work_dir = work_dir
16
+ @repository_root = repository_root
17
+ @repository_url = repository_url
18
+ end
19
+
20
+ def repository_root
21
+ load_svn_info unless @repository_root
22
+ return @repository_root
23
+ end
24
+
25
+ def repository_url
26
+ if (not @repository_url)
27
+ @repository_url = "#{repository_root}/trunk"
28
+ end
29
+ return @repository_url
39
30
  end
40
31
 
41
32
  def status
@@ -51,11 +42,11 @@ class SvnDriver
51
42
  end
52
43
 
53
44
  def tag(tag_name)
54
- @system.shell("svn copy #{@svn_info.repository_root}/trunk #{@svn_info.repository_root}/tags/#{tag_name} -m \"ruby buildmaster\"")
45
+ @system.shell("svn copy #{repository_url} #{repository_root}/tags/#{tag_name} -m \"ruby buildmaster\"")
55
46
  end
56
47
 
57
48
  def checkout(output)
58
- @system.shell("svn checkout #{@svn_info.repository_root}/trunk #{output}")
49
+ @system.shell("svn checkout #{repository_root}/trunk #{output}")
59
50
  end
60
51
 
61
52
  def command(command)
@@ -63,8 +54,24 @@ class SvnDriver
63
54
  end
64
55
 
65
56
  private
57
+ def load_svn_info
58
+ info = @system.shell_output("svn info #{work_dir.path}")
59
+ StringIO.new(info).each_line do |line|
60
+ index = line.index(':')
61
+ if (index)
62
+ property = line[0, index].strip
63
+ value = line[index + 1, line.length - index - 1].strip
64
+ if (property == 'Repository Root')
65
+ @repository_root = value
66
+ elsif (property == 'URL')
67
+ @repository_url = value
68
+ end
69
+ end
70
+ end
71
+ end
72
+
66
73
  def command_for_path(svn_command, argument='')
67
- @system.shell("svn #{svn_command} #{@svn_info.work_dir.path}#{argument}")
74
+ @system.shell("svn #{svn_command} #{@work_dir.path}#{argument}")
68
75
  end
69
76
  end
70
77
 
@@ -167,6 +167,31 @@ def register_cotta_dir_specifications
167
167
  actual_dir_list[1].name.should_equal 'one.txt'
168
168
  actual_dir_list[1].save
169
169
  end
170
+
171
+ specify 'should move directory with its children' do
172
+ dir = BuildMaster::CottaDir.new(@system, Pathname.new('targetdir/child_dir'))
173
+ @dir.file('file.txt').save('file.txt')
174
+ @dir.dir('subdir').mkdirs
175
+ @dir.list.size.should_equal 2
176
+ @dir.move_to(dir)
177
+ @dir.exists?.should_equal false
178
+ dir.list.size.should_equal 2
179
+ dir.file('file.txt').load.should_equal 'file.txt'
180
+ dir.dir('subdir').exists?.should_equal true
181
+ end
182
+
183
+ specify 'should copy directory with its children' do
184
+ dir = BuildMaster::CottaDir.new(@system, Pathname.new('targetdir/child_dir'))
185
+ @dir.file('file.txt').save('file.txt')
186
+ @dir.dir('subdir').mkdirs
187
+ @dir.list.size.should_equal 2
188
+ @dir.copy_to(dir)
189
+ @dir.exists?.should_equal true
190
+ dir.list.size.should_equal 2
191
+ dir.file('file.txt').load.should_equal 'file.txt'
192
+ dir.dir('subdir').exists?.should_equal true
193
+ end
194
+
170
195
  end
171
196
 
172
197
  end
@@ -47,12 +47,24 @@ class PhysicalSystemStub
47
47
  @system.io(relative_from_tmp(pathname), arguments)
48
48
  end
49
49
 
50
- def copy(source, target)
51
- @system.copy(relative_from_tmp(source), relative_from_tmp(target))
50
+ def copy_file(source, target)
51
+ @system.copy_file(relative_from_tmp(source), relative_from_tmp(target))
52
52
  end
53
53
 
54
- def move(source, target)
55
- @system.move(relative_from_tmp(source), relative_from_tmp(target))
54
+ def move_file(source, target)
55
+ @system.move_file(relative_from_tmp(source), relative_from_tmp(target))
56
+ end
57
+
58
+ def copy_dir(source, target)
59
+ @system.copy_dir(relative_from_tmp(source), relative_from_tmp(target))
60
+ end
61
+
62
+ def move_dir(source, target)
63
+ @system.move_dir(relative_from_tmp(source), relative_from_tmp(target))
64
+ end
65
+
66
+ def copy_dir(source, target)
67
+ @system.copy_dir(relative_from_tmp(source), relative_from_tmp(target))
56
68
  end
57
69
 
58
70
  private
@@ -98,7 +98,7 @@ require 'pathname'
98
98
  write_io.puts 'line'
99
99
  write_io.close
100
100
  target = Pathname.new('target')
101
- @system.copy(pathname, target)
101
+ @system.copy_file(pathname, target)
102
102
  @system.file_exists?(target).should_equal true
103
103
  read_io = load_io(target, 'r')
104
104
  read_io.gets.should_equal "line\n"
@@ -107,11 +107,9 @@ require 'pathname'
107
107
 
108
108
  specify 'move file' do
109
109
  pathname = Pathname.new('file1')
110
- write_io = load_io(pathname, 'w')
111
- write_io.puts 'line'
112
- write_io.close
110
+ write_content(pathname, 'line')
113
111
  target = Pathname.new('target')
114
- @system.move(pathname, target)
112
+ @system.move_file(pathname, target)
115
113
  @system.file_exists?(target).should_equal true
116
114
  read_io = load_io(target, 'r')
117
115
  read_io.gets.should_equal "line\n"
@@ -119,6 +117,41 @@ require 'pathname'
119
117
  @system.file_exists?(pathname).should_equal false
120
118
  end
121
119
 
120
+ specify 'move dir' do
121
+ source = Pathname.new('source')
122
+ @system.mkdir source
123
+ source_file = Pathname.new('source/file.txt')
124
+ write_content(source_file, 'file.txt')
125
+ @system.mkdir source.join('subdir')
126
+ target = Pathname.new('target')
127
+ @system.move_dir(source, target)
128
+ @system.list(target).size.should_equal 2
129
+ @system.dir_exists?(source).should_equal false
130
+ @system.dir_exists?(target).should_equal true
131
+ @system.file_exists?(Pathname.new('target/file.txt')).should_equal true
132
+ @system.dir_exists?(Pathname.new('target/subdir')).should_equal true
133
+ end
134
+
135
+ specify 'copy dir' do
136
+ source = Pathname.new('source')
137
+ @system.mkdir source
138
+ source_file = Pathname.new('source/file.txt')
139
+ write_content(source_file, 'file.txt')
140
+ @system.mkdir source.join('subdir')
141
+ target = Pathname.new('target')
142
+ @system.copy_dir(source, target)
143
+ @system.list(target).size.should_equal 2
144
+ @system.dir_exists?(source).should_equal true
145
+ @system.dir_exists?(target).should_equal true
146
+ @system.file_exists?(Pathname.new('target/file.txt')).should_equal true
147
+ end
148
+
149
+ def write_content(pathname, content)
150
+ write_io = load_io(pathname, 'w')
151
+ write_io.puts content
152
+ write_io.close
153
+ end
154
+
122
155
  end
123
156
  def load_io(*args)
124
157
  io = @system.io(*args)
@@ -12,74 +12,68 @@ context 'SVN drivers' do
12
12
  @system = InMemorySystem.new
13
13
  cotta = Cotta.new(@system)
14
14
  @work_dir_root = cotta.dir('/workdir')
15
- @work_dir_root.dir('.svn').file('entries').save <<CONTENT
16
- <?xml version="1.0" encoding="utf-8"?>
17
- <wc-entries
18
- xmlns="svn:">
19
- <entry
20
- committed-rev="120"
21
- name=""
22
- committed-date="2006-09-05T06:50:07.932800Z"
23
- url="svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster/trunk"
24
- last-author="wolfdancer"
25
- kind="dir"
26
- uuid="ab7ff8c2-9713-0410-a269-a4b56b3120d2"
27
- repos="svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster"
28
- prop-time="2006-09-05T06:49:40.625000Z"
29
- revision="120"/>
30
- </wc-entries>
15
+ @system.output_for_command("svn info #{@work_dir_root.path}", <<CONTENT
16
+ Path: .
17
+ URL: svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster/trunk
18
+ Repository Root: svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster
19
+ Repository UUID: ab7ff8c2-9713-0410-a269-a4b56b3120d2
20
+ Revision: 153
21
+ Node Kind: directory
22
+ Schedule: normal
23
+ Last Changed Author: wolfdancer
24
+ Last Changed Rev: 153
25
+ Last Changed Date: 2006-10-15 21:27:51 -0700 (Sun, 15 Oct 2006)
31
26
  CONTENT
32
- @info = SvnInfo.new @work_dir_root
27
+ )
28
+ @svn = SvnDriver.new @work_dir_root
33
29
  end
34
30
 
35
- specify 'load svn info from the .svn directory' do
36
- info = SvnInfo.new(@work_dir_root)
37
- info.work_dir.should_equal @work_dir_root
38
- info.repository_root.should_equal 'svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster'
31
+ specify 'load svn info from the info command' do
32
+ @svn.work_dir.should_equal @work_dir_root
33
+ @svn.repository_root.should_equal 'svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster'
39
34
  end
40
35
 
41
36
  specify 'load svn driver from the root directory' do
42
- svn = SvnDriver.from_path(@work_dir_root)
43
- svn.command('info')
37
+ @svn.command('info')
44
38
  end
45
39
 
46
40
  specify 'svn status command' do
47
41
  log = ''
48
- svn = SvnDriver.new(@info)
49
- svn.status
42
+ @svn.status
50
43
  @system.executed_commands[0].should_equal "svn status #{@work_dir_root.path}"
51
44
  end
52
45
 
53
46
  specify 'svn update command' do
54
47
  log = ''
55
- svn = SvnDriver.new(@info)
56
- svn.update
48
+ @svn.update
57
49
  @system.executed_commands[0].should_equal "svn update #{@work_dir_root.path}"
58
50
  end
59
51
 
60
52
  specify 'svn commit command' do
61
- svn = SvnDriver.new(@info)
62
- svn.commit('message')
53
+ @svn.commit('message')
63
54
  @system.executed_commands[0].should_equal "svn commit #{@work_dir_root.path} -m \"message\""
64
55
  end
65
56
 
66
57
  specify 'svn check out command' do
67
- svn = SvnDriver.new(@info)
68
- svn.checkout('output')
69
- @system.executed_commands[0].should_equal "svn checkout #{@info.repository_root}/trunk output"
58
+ @svn.checkout('output')
59
+ @system.executed_commands[0].should_equal "svn checkout #{@svn.repository_root}/trunk output"
70
60
  end
71
61
 
72
62
  specify 'svn command' do
73
- svn = SvnDriver.new(@info)
74
- svn.command('info')
63
+ @svn.command('info')
75
64
  @system.executed_commands[0].should_equal "svn info #{@work_dir_root.path}"
76
65
  end
77
66
 
78
67
  specify 'svn tag' do
79
- svn = SvnDriver.new(@info)
80
68
  tag = 'build_0.0.5_b3'
81
- svn.tag(tag)
82
- @system.executed_commands[0].should_equal "svn copy #{@info.repository_root}/trunk #{@info.repository_root}/tags/#{tag} -m \"ruby buildmaster\""
69
+ @svn.tag(tag)
70
+ @system.executed_commands[0].should_equal "svn copy #{@svn.repository_root}/trunk #{@svn.repository_root}/tags/#{tag} -m \"ruby buildmaster\""
71
+ end
72
+
73
+ specify 'physical svn works' do
74
+ cotta = Cotta.new
75
+ svn = SvnDriver.new(cotta.file(__FILE__).parent)
76
+ svn.repository_root.should_equal 'svn+ssh://wolfdancer@rubyforge.org/var/svn/buildmaster'
83
77
  end
84
78
 
85
79
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: BuildMaster
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.0
7
- date: 2006-10-01 00:00:00 -06:00
6
+ version: 0.9.1
7
+ date: 2006-10-18 00:00:00 -07:00
8
8
  summary: A project that hosts a series of scripts to be used in project building, project releasing, and site building.
9
9
  require_paths:
10
10
  - lib