BuildMaster 0.9.1 → 1.0.6
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/bin/svnfix.rb +3 -0
- data/lib/buildmaster/ci/server.rb +55 -0
- data/lib/buildmaster/common.rb +3 -0
- data/lib/buildmaster/common/properties.rb +28 -0
- data/lib/buildmaster/{tree_to_object.rb → common/tree_to_object.rb} +0 -0
- data/lib/buildmaster/cotta.rb +1 -1
- data/lib/buildmaster/cotta/command_error.rb +6 -1
- data/lib/buildmaster/cotta/command_interface.rb +44 -0
- data/lib/buildmaster/cotta/command_runner.rb +39 -0
- data/lib/buildmaster/cotta/cotta.rb +40 -3
- data/lib/buildmaster/cotta/cotta_dir.rb +28 -7
- data/lib/buildmaster/cotta/cotta_file.rb +14 -2
- data/lib/buildmaster/cotta/cotta_pathname.rb +9 -0
- data/lib/buildmaster/cotta/in_memory_system.rb +20 -9
- data/lib/buildmaster/cotta/physical_system.rb +4 -8
- data/lib/buildmaster/project.rb +10 -0
- data/lib/buildmaster/{ant_driver.rb → project/ant_driver.rb} +0 -0
- data/lib/buildmaster/project/build.rb +3 -0
- data/lib/buildmaster/{build_number_file.rb → project/build_number_file.rb} +4 -0
- data/lib/buildmaster/project/ci.rb +3 -0
- data/lib/buildmaster/{cvs_driver.rb → project/cvs_driver.rb} +0 -0
- data/lib/buildmaster/project/ftp_driver.rb +64 -0
- data/lib/buildmaster/{java_manifest.rb → project/java_manifest.rb} +0 -0
- data/lib/buildmaster/project/pscp_driver.rb +17 -0
- data/lib/buildmaster/project/release.rb +67 -0
- data/lib/buildmaster/project/ruby_forge_project.rb +26 -0
- data/lib/buildmaster/{run_ant.rb → project/run_ant.rb} +0 -0
- data/lib/buildmaster/project/server_manager.rb +64 -0
- data/lib/buildmaster/project/svn_admin_driver.rb +20 -0
- data/lib/buildmaster/project/svn_driver.rb +94 -0
- data/lib/buildmaster/project/svn_helper.rb +113 -0
- data/lib/buildmaster/project/svn_status_info.rb +54 -0
- data/lib/buildmaster/{try.rb → project/try.rb} +0 -0
- data/lib/buildmaster/project/version_number_file.rb +45 -0
- data/lib/buildmaster/{windows → project/windows}/iis_driver.rb +4 -4
- data/lib/buildmaster/{windows → project/windows}/sql_server_driver.rb +0 -0
- data/lib/buildmaster/site.rb +5 -0
- data/lib/buildmaster/site/about_handler.rb +43 -0
- data/lib/buildmaster/site/content_engine_repository.rb +83 -0
- data/lib/buildmaster/site/element_processor_by_name.rb +18 -0
- data/lib/buildmaster/site/file_processor.rb +59 -0
- data/lib/buildmaster/site/site.rb +29 -6
- data/lib/buildmaster/site/site_server.rb +56 -0
- data/lib/buildmaster/{site_spec.rb → site/site_spec.rb} +63 -38
- data/lib/buildmaster/{site_tester.rb → site/site_tester.rb} +0 -0
- data/lib/buildmaster/site/source_content.rb +12 -0
- data/lib/buildmaster/{source_file_handler.rb → site/source_file_handler.rb} +13 -27
- data/lib/buildmaster/site/template_builder.rb +4 -0
- data/lib/buildmaster/site/template_error.rb +18 -0
- data/lib/buildmaster/{template_runner.rb → site/template_runner.rb} +6 -16
- data/lib/buildmaster/{templatelets.rb → site/templatelets.rb} +3 -1
- data/lib/buildmaster/site/templatelets/attribute.rb +21 -0
- data/lib/buildmaster/site/templatelets/code.rb +82 -0
- data/lib/buildmaster/{templatelets → site/templatelets}/each.rb +7 -5
- data/lib/buildmaster/{templatelets → site/templatelets}/href.rb +1 -1
- data/lib/buildmaster/{templatelets → site/templatelets}/include.rb +0 -0
- data/lib/buildmaster/{templatelets → site/templatelets}/link.rb +2 -3
- data/lib/buildmaster/{templatelets → site/templatelets}/text.rb +1 -1
- data/lib/buildmaster/{templatelets → site/templatelets}/when.rb +4 -7
- data/lib/buildmaster/site/templates/buildmaster/content/border_bottom.gif +0 -0
- data/lib/buildmaster/site/templates/buildmaster/content/buildmaster.css +370 -0
- data/lib/buildmaster/site/templates/buildmaster/content/logo.gif +0 -0
- data/lib/buildmaster/site/templates/buildmaster/content/news-rss2.xml +4 -0
- data/lib/buildmaster/site/templates/buildmaster/content/print.css +65 -0
- data/lib/buildmaster/site/templates/buildmaster/content/ruby.css +14 -0
- data/lib/buildmaster/site/templates/buildmaster/template.html +121 -0
- data/lib/buildmaster/site/templates/cotta/content/border_bottom.gif +0 -0
- data/lib/buildmaster/site/templates/cotta/content/cotta.css +363 -0
- data/lib/buildmaster/site/templates/cotta/content/cotta.gif +0 -0
- data/lib/buildmaster/site/templates/cotta/content/news-rss2.xml +2 -0
- data/lib/buildmaster/site/templates/cotta/template.html +106 -0
- data/lib/buildmaster/site/xtemplate.rb +26 -0
- data/lib/buildmaster/version +1 -0
- data/test/buildmaster/common/tc_properties.rb +24 -0
- data/test/buildmaster/{tc_tree_to_object.rb → common/tc_tree_to_object.rb} +18 -18
- data/test/buildmaster/cotta/cotta_specifications.rb +88 -64
- data/test/buildmaster/cotta/physical_system_stub.rb +3 -3
- data/test/buildmaster/cotta/system_file_specifications.rb +38 -47
- data/test/buildmaster/cotta/tc_command_interface.rb +46 -0
- data/test/buildmaster/cotta/tc_command_runner.rb +28 -0
- data/test/buildmaster/cotta/tc_cotta.rb +35 -9
- data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +10 -5
- data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +3 -3
- data/test/buildmaster/cotta/tc_in_memory_system.rb +7 -2
- data/test/buildmaster/cotta/tc_pathname.rb +22 -0
- data/test/buildmaster/cotta/tc_physical_system.rb +12 -2
- data/test/buildmaster/{build.xml → project/build.xml} +0 -0
- data/test/buildmaster/{manifest.mf → project/manifest.mf} +0 -0
- data/test/buildmaster/{tc_ant_driver.rb → project/tc_ant_driver.rb} +3 -3
- data/test/buildmaster/{tc_build_number_file.rb → project/tc_build_number_file.rb} +7 -7
- data/test/buildmaster/{tc_cvs_driver.rb → project/tc_cvs_driver.rb} +14 -14
- data/test/buildmaster/{tc_java_manifest.rb → project/tc_java_manifest.rb} +7 -7
- data/test/buildmaster/project/tc_release.rb +61 -0
- data/test/buildmaster/project/tc_server_manager.rb +70 -0
- data/test/buildmaster/project/tc_svn_driver.rb +104 -0
- data/test/buildmaster/project/tc_svn_status_info.rb +37 -0
- data/test/buildmaster/project/tc_version_number_file.rb +46 -0
- data/test/buildmaster/{windows → project/windows}/tc_iis_driver.rb +5 -4
- data/test/buildmaster/{windows → project/windows}/tc_sql_server_driver.rb +4 -4
- data/test/buildmaster/site/content/tc_content_engine_repository.rb +63 -0
- data/test/buildmaster/site/tc_element_processor_by_name.rb +29 -0
- data/test/buildmaster/site/tc_file_processor.rb +141 -0
- data/test/buildmaster/site/tc_site.rb +42 -11
- data/test/buildmaster/site/tc_site_server.rb +43 -0
- data/test/buildmaster/{tc_site_spec.rb → site/tc_site_spec.rb} +9 -9
- data/test/buildmaster/{tc_source_file_handler.rb → site/tc_source_file_handler.rb} +10 -9
- data/test/buildmaster/site/tc_template_builder.rb +23 -23
- data/test/buildmaster/site/tc_template_error.rb +15 -0
- data/test/buildmaster/{tc_template_runner.rb → site/tc_template_runner.rb} +22 -17
- data/test/buildmaster/site/tc_templatelets.rb +37 -0
- data/test/buildmaster/{tc_xtemplate.rb → site/tc_xtemplate.rb} +14 -15
- data/test/buildmaster/{template.xhtml → site/template.xhtml} +0 -0
- data/test/buildmaster/{templatelets → site/templatelets}/common_templatelet_test.rb +11 -7
- data/test/buildmaster/{templatelets → site/templatelets}/tc_attribute.rb +14 -10
- data/test/buildmaster/site/templatelets/tc_code.rb +132 -0
- data/test/buildmaster/{templatelets → site/templatelets}/tc_each.rb +25 -12
- data/test/buildmaster/{templatelets → site/templatelets}/tc_href.rb +6 -8
- data/test/buildmaster/{templatelets → site/templatelets}/tc_include.rb +3 -12
- data/test/buildmaster/{templatelets → site/templatelets}/tc_link.rb +11 -18
- data/test/buildmaster/{templatelets → site/templatelets}/tc_text.rb +2 -9
- data/test/buildmaster/{templatelets → site/templatelets}/tc_when.rb +8 -15
- data/test/manual/bms.rb +10 -0
- data/test/tmp/svn_test/repository/README.txt +5 -0
- data/test/tmp/svn_test/repository/conf/authz +21 -0
- data/test/tmp/svn_test/repository/conf/passwd +8 -0
- data/test/tmp/svn_test/repository/conf/svnserve.conf +30 -0
- data/test/tmp/svn_test/repository/db/current +1 -0
- data/test/tmp/svn_test/repository/db/format +1 -0
- data/test/tmp/svn_test/repository/db/fs-type +1 -0
- data/test/tmp/svn_test/repository/db/revprops/0 +5 -0
- data/test/tmp/svn_test/repository/db/revprops/1 +13 -0
- data/test/tmp/svn_test/repository/db/revprops/2 +13 -0
- data/test/tmp/svn_test/repository/db/revprops/3 +13 -0
- data/test/tmp/svn_test/repository/db/revprops/4 +13 -0
- data/test/tmp/svn_test/repository/db/revs/0 +11 -0
- data/test/tmp/svn_test/repository/db/revs/1 +25 -0
- data/test/tmp/svn_test/repository/db/revs/2 +29 -0
- data/test/tmp/svn_test/repository/db/revs/3 +33 -0
- data/test/tmp/svn_test/repository/db/revs/4 +0 -0
- data/test/tmp/svn_test/repository/db/uuid +1 -0
- data/test/tmp/svn_test/repository/db/write-lock +0 -0
- data/test/tmp/svn_test/repository/format +1 -0
- data/test/tmp/svn_test/repository/hooks/post-commit.tmpl +51 -0
- data/test/tmp/svn_test/repository/hooks/post-lock.tmpl +44 -0
- data/test/tmp/svn_test/repository/hooks/post-revprop-change.tmpl +56 -0
- data/test/tmp/svn_test/repository/hooks/post-unlock.tmpl +42 -0
- data/test/tmp/svn_test/repository/hooks/pre-commit.tmpl +70 -0
- data/test/tmp/svn_test/repository/hooks/pre-lock.tmpl +64 -0
- data/test/tmp/svn_test/repository/hooks/pre-revprop-change.tmpl +66 -0
- data/test/tmp/svn_test/repository/hooks/pre-unlock.tmpl +60 -0
- data/test/tmp/svn_test/repository/hooks/start-commit.tmpl +54 -0
- data/test/tmp/svn_test/repository/locks/db-logs.lock +3 -0
- data/test/tmp/svn_test/repository/locks/db.lock +3 -0
- data/test/tmp/svn_test/second/test.txt +1 -0
- data/test/tmp/svn_test/workdir/test.txt +1 -0
- data/test/ts_buildmaster.rb +0 -1
- metadata +168 -69
- data/lib/buildmaster.rb +0 -10
- data/lib/buildmaster/build_file.rb +0 -11
- data/lib/buildmaster/buildnumber +0 -1
- data/lib/buildmaster/file_processor.rb +0 -138
- data/lib/buildmaster/site_server.rb +0 -33
- data/lib/buildmaster/source_content.rb +0 -11
- data/lib/buildmaster/svn_driver.rb +0 -78
- data/lib/buildmaster/template_error.rb +0 -8
- data/lib/buildmaster/templatelets/attribute.rb +0 -16
- data/lib/buildmaster/xtemplate.rb +0 -27
- data/lib/mock.rb +0 -3
- data/lib/mock/mock_base.rb +0 -24
- data/test/buildmaster/tc_file_processor.rb +0 -125
- data/test/buildmaster/tc_svn_driver.rb +0 -81
- data/test/tmp/output/index.html +0 -8
- data/test/tmp/output/markdown.html +0 -8
- data/test/tmp/output/textile.html +0 -8
data/bin/svnfix.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module BuildMaster
|
|
2
|
+
module CI
|
|
3
|
+
|
|
4
|
+
=begin rdoc
|
|
5
|
+
A CI (Continuous Integration) server that does the following loop
|
|
6
|
+
* check for modifications
|
|
7
|
+
* if modification set found,
|
|
8
|
+
** update
|
|
9
|
+
** make
|
|
10
|
+
** publish (update site, email notification)
|
|
11
|
+
=end
|
|
12
|
+
class Server
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
@modification_checker = Array.new
|
|
16
|
+
@updator = Array.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def serve
|
|
20
|
+
pid = fork {start}
|
|
21
|
+
if (pid)
|
|
22
|
+
['INT', 'TERM'].each { |signal|
|
|
23
|
+
trap(signal){Process.kill('break', pid)}
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def start
|
|
29
|
+
puts "server started"
|
|
30
|
+
until @stopped
|
|
31
|
+
if check_modifications
|
|
32
|
+
build_loop
|
|
33
|
+
end
|
|
34
|
+
sleep 30
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def stop
|
|
39
|
+
@stopped = true
|
|
40
|
+
Thread.current.raise 'shutting down'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
def check_modifications
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def build_loop
|
|
48
|
+
update
|
|
49
|
+
result = build
|
|
50
|
+
publish(result)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module BuildMaster
|
|
2
|
+
module Common
|
|
3
|
+
|
|
4
|
+
class Properties
|
|
5
|
+
def Properties::parse_io(io)
|
|
6
|
+
hash = Hash.new
|
|
7
|
+
io.each_line do |line|
|
|
8
|
+
line.strip!
|
|
9
|
+
if (line[0..0] != '#')
|
|
10
|
+
parse_into_hash(hash, line)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
return hash
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def Properties::parse_into_hash(hash, line)
|
|
18
|
+
index = line.index(':')
|
|
19
|
+
if (index)
|
|
20
|
+
property = line[0, index].strip
|
|
21
|
+
value = line[index + 1, line.length - index - 1].strip
|
|
22
|
+
hash[property] = value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
File without changes
|
data/lib/buildmaster/cotta.rb
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module BuildMaster
|
|
2
|
+
class CommandInterface
|
|
3
|
+
def initialize(io = SystemIo.new)
|
|
4
|
+
@io = io
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def puts(content)
|
|
8
|
+
@io.puts(content)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def prompt(question)
|
|
12
|
+
puts(question)
|
|
13
|
+
gets
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def prompt_for_choice(question, candidates)
|
|
17
|
+
puts(question)
|
|
18
|
+
0.upto(candidates.size - 1) do |index|
|
|
19
|
+
puts "[#{index + 1}] #{candidates[index]}"
|
|
20
|
+
end
|
|
21
|
+
answer = gets.to_i
|
|
22
|
+
seletion = nil
|
|
23
|
+
if answer > 0 && answer <= candidates.size
|
|
24
|
+
selection = candidates[answer - 1]
|
|
25
|
+
end
|
|
26
|
+
return selection
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def gets
|
|
30
|
+
@io.gets
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class SystemIo
|
|
36
|
+
def puts(content)
|
|
37
|
+
$stdout.puts(content)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def gets
|
|
41
|
+
$stdin.gets
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
require 'command_error'
|
|
4
|
+
|
|
5
|
+
module BuildMaster
|
|
6
|
+
class CommandRunner
|
|
7
|
+
attr_reader :outputs
|
|
8
|
+
|
|
9
|
+
def initialize(command)
|
|
10
|
+
@command = command
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute
|
|
14
|
+
id = rand(10000)
|
|
15
|
+
puts "[#{id}]$> #{@command}"
|
|
16
|
+
output = nil
|
|
17
|
+
IO.popen(@command) do |io|
|
|
18
|
+
if (block_given?)
|
|
19
|
+
output = yield io
|
|
20
|
+
else
|
|
21
|
+
output = load_output(id, io)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
last_process = $?
|
|
25
|
+
raise CommandError.new(last_process, output), @command unless last_process.exitstatus == 0
|
|
26
|
+
return output
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
def load_output(id, io)
|
|
31
|
+
output = ''
|
|
32
|
+
while (line = io.gets) do
|
|
33
|
+
puts "[#{id}] #{line}"
|
|
34
|
+
output << line
|
|
35
|
+
end
|
|
36
|
+
return output
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -4,26 +4,63 @@ require 'physical_system'
|
|
|
4
4
|
require 'cotta_dir'
|
|
5
5
|
require 'cotta_file'
|
|
6
6
|
require 'pathname'
|
|
7
|
+
require 'cotta_pathname'
|
|
8
|
+
require 'command_interface'
|
|
7
9
|
|
|
8
10
|
module BuildMaster
|
|
9
11
|
class Cotta
|
|
12
|
+
attr_accessor :command_interface
|
|
13
|
+
|
|
10
14
|
def initialize(system=PhysicalSystem.new)
|
|
11
15
|
@system = system
|
|
16
|
+
@command_interface = CommandInterface.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def shell(command_line, &block)
|
|
20
|
+
@system.shell(command_line, &block)
|
|
12
21
|
end
|
|
13
22
|
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
def command_interface=(value)
|
|
24
|
+
if (value)
|
|
25
|
+
@command_interface = value
|
|
26
|
+
else
|
|
27
|
+
@command_interface = CommandInterface.new
|
|
28
|
+
end
|
|
17
29
|
end
|
|
18
30
|
|
|
19
31
|
def dir(path)
|
|
32
|
+
return nil unless path
|
|
20
33
|
return CottaDir.new(@system, Pathname.new(path))
|
|
21
34
|
end
|
|
22
35
|
|
|
36
|
+
def Cotta::dir(path)
|
|
37
|
+
return nil unless path
|
|
38
|
+
return Cotta.new.dir(File.expand_path(path))
|
|
39
|
+
end
|
|
40
|
+
|
|
23
41
|
def file(path)
|
|
42
|
+
return nil unless path
|
|
24
43
|
return CottaFile.new(@system, Pathname.new(path))
|
|
25
44
|
end
|
|
26
45
|
|
|
46
|
+
def Cotta::file(path)
|
|
47
|
+
return nil unless path
|
|
48
|
+
return Cotta.new.file(File.expand_path(path))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def Cotta::parent_of(path)
|
|
52
|
+
return Cotta.file(path).parent
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def entry(path)
|
|
56
|
+
entry = file(path)
|
|
57
|
+
unless (entry.exists?)
|
|
58
|
+
entry = dir(path)
|
|
59
|
+
raise "#{path} exists as niether file nor directory" unless entry.exists?
|
|
60
|
+
end
|
|
61
|
+
return entry
|
|
62
|
+
end
|
|
63
|
+
|
|
27
64
|
def environment!(variable)
|
|
28
65
|
@system.environment!(variable)
|
|
29
66
|
end
|
|
@@ -7,8 +7,8 @@ class CottaDir
|
|
|
7
7
|
attr_reader :path, :system
|
|
8
8
|
|
|
9
9
|
def initialize(system, path)
|
|
10
|
-
@system = system
|
|
11
10
|
@path = path
|
|
11
|
+
@system = system
|
|
12
12
|
@name = @path.basename.to_s
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -17,7 +17,17 @@ class CottaDir
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def name
|
|
20
|
-
|
|
20
|
+
name = nil
|
|
21
|
+
if root?
|
|
22
|
+
name = path.to_s
|
|
23
|
+
else
|
|
24
|
+
name = @path.basename.to_s
|
|
25
|
+
end
|
|
26
|
+
return name
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def root?
|
|
30
|
+
parent.nil?
|
|
21
31
|
end
|
|
22
32
|
|
|
23
33
|
def exists?
|
|
@@ -25,10 +35,9 @@ class CottaDir
|
|
|
25
35
|
end
|
|
26
36
|
|
|
27
37
|
def parent
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return CottaDir.new(@system, @path.parent)
|
|
38
|
+
parent_path = @path.cotta_parent
|
|
39
|
+
return nil unless parent_path
|
|
40
|
+
return CottaDir.new(@system, parent_path)
|
|
32
41
|
end
|
|
33
42
|
|
|
34
43
|
def dir(name)
|
|
@@ -56,11 +65,19 @@ class CottaDir
|
|
|
56
65
|
@system.move_dir(@path, target.path)
|
|
57
66
|
end
|
|
58
67
|
|
|
68
|
+
def move_to_path(target_path)
|
|
69
|
+
move_to(cotta.dir(target_path))
|
|
70
|
+
end
|
|
71
|
+
|
|
59
72
|
def copy_to(target)
|
|
60
73
|
target.parent.mkdirs
|
|
61
74
|
@system.copy_dir(@path, target.path)
|
|
62
75
|
end
|
|
63
76
|
|
|
77
|
+
def copy_to_path(target_path)
|
|
78
|
+
copy_to(cotta.dir(target_path))
|
|
79
|
+
end
|
|
80
|
+
|
|
64
81
|
def list
|
|
65
82
|
@system.list(@path).collect do |item|
|
|
66
83
|
candidate = dir(item)
|
|
@@ -75,8 +92,12 @@ class CottaDir
|
|
|
75
92
|
return @path == other.path && @system == other.system
|
|
76
93
|
end
|
|
77
94
|
|
|
95
|
+
def inspect
|
|
96
|
+
return "#{self.class}:#{self.object_id}-#{@system.inspect}-#@path"
|
|
97
|
+
end
|
|
98
|
+
|
|
78
99
|
def to_s
|
|
79
|
-
|
|
100
|
+
@path
|
|
80
101
|
end
|
|
81
102
|
|
|
82
103
|
end
|
|
@@ -5,8 +5,8 @@ class CottaFile
|
|
|
5
5
|
attr_reader :system, :path
|
|
6
6
|
|
|
7
7
|
def initialize(system, path)
|
|
8
|
-
@system = system
|
|
9
8
|
@path = path
|
|
9
|
+
@system = system
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def cotta
|
|
@@ -38,11 +38,19 @@ class CottaFile
|
|
|
38
38
|
@system.copy_file(path, target_file.path)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
def copy_to_path(target_path)
|
|
42
|
+
copy_to(cotta.file(target_path))
|
|
43
|
+
end
|
|
44
|
+
|
|
41
45
|
def move_to(target_file)
|
|
42
46
|
target_file.parent.mkdirs
|
|
43
47
|
@system.move_file(path, target_file.path)
|
|
44
48
|
end
|
|
45
49
|
|
|
50
|
+
def move_to_path(target_path)
|
|
51
|
+
move_to(cotta.file(target_path))
|
|
52
|
+
end
|
|
53
|
+
|
|
46
54
|
def save(content = '')
|
|
47
55
|
write {|file| file.printf content.to_s}
|
|
48
56
|
end
|
|
@@ -78,7 +86,11 @@ class CottaFile
|
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
def to_s
|
|
81
|
-
|
|
89
|
+
@path
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def inspect
|
|
93
|
+
return "#{self.class}:#{self.object_id}-#{@system.inspect}-#@path"
|
|
82
94
|
end
|
|
83
95
|
|
|
84
96
|
private
|
|
@@ -12,6 +12,7 @@ class InMemorySystem
|
|
|
12
12
|
@executed_commands = []
|
|
13
13
|
@content = ""
|
|
14
14
|
@file_system = Hash.new
|
|
15
|
+
@file_system[nil] = DirectoryContent.new('')
|
|
15
16
|
@file_system[Pathname.new('/')] = DirectoryContent.new('/')
|
|
16
17
|
@file_system[Pathname.new('.')] = DirectoryContent.new('.')
|
|
17
18
|
@output_map = Hash.new
|
|
@@ -19,9 +20,6 @@ class InMemorySystem
|
|
|
19
20
|
|
|
20
21
|
def shell(command)
|
|
21
22
|
@executed_commands.push(command)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def shell_output(command)
|
|
25
23
|
result = @output_map[command]
|
|
26
24
|
raise "#{command} not found in expectation" unless result
|
|
27
25
|
return result
|
|
@@ -30,9 +28,13 @@ class InMemorySystem
|
|
|
30
28
|
def output_for_command(command, output)
|
|
31
29
|
@output_map[command] = output
|
|
32
30
|
end
|
|
31
|
+
|
|
32
|
+
def expect_command(command)
|
|
33
|
+
Entry.new(command)
|
|
34
|
+
end
|
|
33
35
|
|
|
34
36
|
def dir_exists?(pathname)
|
|
35
|
-
|
|
37
|
+
content = path_content(pathname)
|
|
36
38
|
return !content.nil? && content.directory?
|
|
37
39
|
end
|
|
38
40
|
|
|
@@ -47,7 +49,7 @@ class InMemorySystem
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def mkdir(pathname)
|
|
50
|
-
path_content(pathname.
|
|
52
|
+
path_content!(pathname.cotta_parent).add(create_dir(pathname))
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
def io(*args)
|
|
@@ -105,7 +107,7 @@ class InMemorySystem
|
|
|
105
107
|
path_to_create = pathname
|
|
106
108
|
while (! dir_exists?(path_to_create))
|
|
107
109
|
paths.push(path_to_create)
|
|
108
|
-
path_to_create = path_to_create.
|
|
110
|
+
path_to_create = path_to_create.cotta_parent
|
|
109
111
|
end
|
|
110
112
|
return paths
|
|
111
113
|
end
|
|
@@ -118,14 +120,23 @@ class InMemorySystem
|
|
|
118
120
|
|
|
119
121
|
def create_file(pathname)
|
|
120
122
|
content = FileContent.new(pathname.basename.to_s)
|
|
121
|
-
parent_dir = pathname.
|
|
123
|
+
parent_dir = pathname.cotta_parent
|
|
122
124
|
path_content(parent_dir).add(content)
|
|
123
125
|
@file_system[pathname] = content
|
|
124
126
|
return content
|
|
125
127
|
end
|
|
126
128
|
|
|
127
129
|
def path_content(pathname)
|
|
128
|
-
|
|
130
|
+
content = path_content!(pathname)
|
|
131
|
+
if (content.nil? && pathname.cotta_parent.nil?)
|
|
132
|
+
mkdir(pathname)
|
|
133
|
+
content = @file_system[pathname]
|
|
134
|
+
end
|
|
135
|
+
return content
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def path_content!(pathname)
|
|
139
|
+
@file_system[pathname]
|
|
129
140
|
end
|
|
130
141
|
|
|
131
142
|
def retrieve_file_content(pathname, options)
|
|
@@ -141,7 +152,7 @@ class InMemorySystem
|
|
|
141
152
|
|
|
142
153
|
def delete_entry(pathname)
|
|
143
154
|
@file_system.delete pathname
|
|
144
|
-
@file_system[pathname.
|
|
155
|
+
@file_system[pathname.cotta_parent].delete(pathname.basename.to_s)
|
|
145
156
|
end
|
|
146
157
|
|
|
147
158
|
end
|