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.
Files changed (174) hide show
  1. data/bin/svnfix.rb +3 -0
  2. data/lib/buildmaster/ci/server.rb +55 -0
  3. data/lib/buildmaster/common.rb +3 -0
  4. data/lib/buildmaster/common/properties.rb +28 -0
  5. data/lib/buildmaster/{tree_to_object.rb → common/tree_to_object.rb} +0 -0
  6. data/lib/buildmaster/cotta.rb +1 -1
  7. data/lib/buildmaster/cotta/command_error.rb +6 -1
  8. data/lib/buildmaster/cotta/command_interface.rb +44 -0
  9. data/lib/buildmaster/cotta/command_runner.rb +39 -0
  10. data/lib/buildmaster/cotta/cotta.rb +40 -3
  11. data/lib/buildmaster/cotta/cotta_dir.rb +28 -7
  12. data/lib/buildmaster/cotta/cotta_file.rb +14 -2
  13. data/lib/buildmaster/cotta/cotta_pathname.rb +9 -0
  14. data/lib/buildmaster/cotta/in_memory_system.rb +20 -9
  15. data/lib/buildmaster/cotta/physical_system.rb +4 -8
  16. data/lib/buildmaster/project.rb +10 -0
  17. data/lib/buildmaster/{ant_driver.rb → project/ant_driver.rb} +0 -0
  18. data/lib/buildmaster/project/build.rb +3 -0
  19. data/lib/buildmaster/{build_number_file.rb → project/build_number_file.rb} +4 -0
  20. data/lib/buildmaster/project/ci.rb +3 -0
  21. data/lib/buildmaster/{cvs_driver.rb → project/cvs_driver.rb} +0 -0
  22. data/lib/buildmaster/project/ftp_driver.rb +64 -0
  23. data/lib/buildmaster/{java_manifest.rb → project/java_manifest.rb} +0 -0
  24. data/lib/buildmaster/project/pscp_driver.rb +17 -0
  25. data/lib/buildmaster/project/release.rb +67 -0
  26. data/lib/buildmaster/project/ruby_forge_project.rb +26 -0
  27. data/lib/buildmaster/{run_ant.rb → project/run_ant.rb} +0 -0
  28. data/lib/buildmaster/project/server_manager.rb +64 -0
  29. data/lib/buildmaster/project/svn_admin_driver.rb +20 -0
  30. data/lib/buildmaster/project/svn_driver.rb +94 -0
  31. data/lib/buildmaster/project/svn_helper.rb +113 -0
  32. data/lib/buildmaster/project/svn_status_info.rb +54 -0
  33. data/lib/buildmaster/{try.rb → project/try.rb} +0 -0
  34. data/lib/buildmaster/project/version_number_file.rb +45 -0
  35. data/lib/buildmaster/{windows → project/windows}/iis_driver.rb +4 -4
  36. data/lib/buildmaster/{windows → project/windows}/sql_server_driver.rb +0 -0
  37. data/lib/buildmaster/site.rb +5 -0
  38. data/lib/buildmaster/site/about_handler.rb +43 -0
  39. data/lib/buildmaster/site/content_engine_repository.rb +83 -0
  40. data/lib/buildmaster/site/element_processor_by_name.rb +18 -0
  41. data/lib/buildmaster/site/file_processor.rb +59 -0
  42. data/lib/buildmaster/site/site.rb +29 -6
  43. data/lib/buildmaster/site/site_server.rb +56 -0
  44. data/lib/buildmaster/{site_spec.rb → site/site_spec.rb} +63 -38
  45. data/lib/buildmaster/{site_tester.rb → site/site_tester.rb} +0 -0
  46. data/lib/buildmaster/site/source_content.rb +12 -0
  47. data/lib/buildmaster/{source_file_handler.rb → site/source_file_handler.rb} +13 -27
  48. data/lib/buildmaster/site/template_builder.rb +4 -0
  49. data/lib/buildmaster/site/template_error.rb +18 -0
  50. data/lib/buildmaster/{template_runner.rb → site/template_runner.rb} +6 -16
  51. data/lib/buildmaster/{templatelets.rb → site/templatelets.rb} +3 -1
  52. data/lib/buildmaster/site/templatelets/attribute.rb +21 -0
  53. data/lib/buildmaster/site/templatelets/code.rb +82 -0
  54. data/lib/buildmaster/{templatelets → site/templatelets}/each.rb +7 -5
  55. data/lib/buildmaster/{templatelets → site/templatelets}/href.rb +1 -1
  56. data/lib/buildmaster/{templatelets → site/templatelets}/include.rb +0 -0
  57. data/lib/buildmaster/{templatelets → site/templatelets}/link.rb +2 -3
  58. data/lib/buildmaster/{templatelets → site/templatelets}/text.rb +1 -1
  59. data/lib/buildmaster/{templatelets → site/templatelets}/when.rb +4 -7
  60. data/lib/buildmaster/site/templates/buildmaster/content/border_bottom.gif +0 -0
  61. data/lib/buildmaster/site/templates/buildmaster/content/buildmaster.css +370 -0
  62. data/lib/buildmaster/site/templates/buildmaster/content/logo.gif +0 -0
  63. data/lib/buildmaster/site/templates/buildmaster/content/news-rss2.xml +4 -0
  64. data/lib/buildmaster/site/templates/buildmaster/content/print.css +65 -0
  65. data/lib/buildmaster/site/templates/buildmaster/content/ruby.css +14 -0
  66. data/lib/buildmaster/site/templates/buildmaster/template.html +121 -0
  67. data/lib/buildmaster/site/templates/cotta/content/border_bottom.gif +0 -0
  68. data/lib/buildmaster/site/templates/cotta/content/cotta.css +363 -0
  69. data/lib/buildmaster/site/templates/cotta/content/cotta.gif +0 -0
  70. data/lib/buildmaster/site/templates/cotta/content/news-rss2.xml +2 -0
  71. data/lib/buildmaster/site/templates/cotta/template.html +106 -0
  72. data/lib/buildmaster/site/xtemplate.rb +26 -0
  73. data/lib/buildmaster/version +1 -0
  74. data/test/buildmaster/common/tc_properties.rb +24 -0
  75. data/test/buildmaster/{tc_tree_to_object.rb → common/tc_tree_to_object.rb} +18 -18
  76. data/test/buildmaster/cotta/cotta_specifications.rb +88 -64
  77. data/test/buildmaster/cotta/physical_system_stub.rb +3 -3
  78. data/test/buildmaster/cotta/system_file_specifications.rb +38 -47
  79. data/test/buildmaster/cotta/tc_command_interface.rb +46 -0
  80. data/test/buildmaster/cotta/tc_command_runner.rb +28 -0
  81. data/test/buildmaster/cotta/tc_cotta.rb +35 -9
  82. data/test/buildmaster/cotta/tc_cotta_dir_in_memory.rb +10 -5
  83. data/test/buildmaster/cotta/tc_cotta_file_in_memory.rb +3 -3
  84. data/test/buildmaster/cotta/tc_in_memory_system.rb +7 -2
  85. data/test/buildmaster/cotta/tc_pathname.rb +22 -0
  86. data/test/buildmaster/cotta/tc_physical_system.rb +12 -2
  87. data/test/buildmaster/{build.xml → project/build.xml} +0 -0
  88. data/test/buildmaster/{manifest.mf → project/manifest.mf} +0 -0
  89. data/test/buildmaster/{tc_ant_driver.rb → project/tc_ant_driver.rb} +3 -3
  90. data/test/buildmaster/{tc_build_number_file.rb → project/tc_build_number_file.rb} +7 -7
  91. data/test/buildmaster/{tc_cvs_driver.rb → project/tc_cvs_driver.rb} +14 -14
  92. data/test/buildmaster/{tc_java_manifest.rb → project/tc_java_manifest.rb} +7 -7
  93. data/test/buildmaster/project/tc_release.rb +61 -0
  94. data/test/buildmaster/project/tc_server_manager.rb +70 -0
  95. data/test/buildmaster/project/tc_svn_driver.rb +104 -0
  96. data/test/buildmaster/project/tc_svn_status_info.rb +37 -0
  97. data/test/buildmaster/project/tc_version_number_file.rb +46 -0
  98. data/test/buildmaster/{windows → project/windows}/tc_iis_driver.rb +5 -4
  99. data/test/buildmaster/{windows → project/windows}/tc_sql_server_driver.rb +4 -4
  100. data/test/buildmaster/site/content/tc_content_engine_repository.rb +63 -0
  101. data/test/buildmaster/site/tc_element_processor_by_name.rb +29 -0
  102. data/test/buildmaster/site/tc_file_processor.rb +141 -0
  103. data/test/buildmaster/site/tc_site.rb +42 -11
  104. data/test/buildmaster/site/tc_site_server.rb +43 -0
  105. data/test/buildmaster/{tc_site_spec.rb → site/tc_site_spec.rb} +9 -9
  106. data/test/buildmaster/{tc_source_file_handler.rb → site/tc_source_file_handler.rb} +10 -9
  107. data/test/buildmaster/site/tc_template_builder.rb +23 -23
  108. data/test/buildmaster/site/tc_template_error.rb +15 -0
  109. data/test/buildmaster/{tc_template_runner.rb → site/tc_template_runner.rb} +22 -17
  110. data/test/buildmaster/site/tc_templatelets.rb +37 -0
  111. data/test/buildmaster/{tc_xtemplate.rb → site/tc_xtemplate.rb} +14 -15
  112. data/test/buildmaster/{template.xhtml → site/template.xhtml} +0 -0
  113. data/test/buildmaster/{templatelets → site/templatelets}/common_templatelet_test.rb +11 -7
  114. data/test/buildmaster/{templatelets → site/templatelets}/tc_attribute.rb +14 -10
  115. data/test/buildmaster/site/templatelets/tc_code.rb +132 -0
  116. data/test/buildmaster/{templatelets → site/templatelets}/tc_each.rb +25 -12
  117. data/test/buildmaster/{templatelets → site/templatelets}/tc_href.rb +6 -8
  118. data/test/buildmaster/{templatelets → site/templatelets}/tc_include.rb +3 -12
  119. data/test/buildmaster/{templatelets → site/templatelets}/tc_link.rb +11 -18
  120. data/test/buildmaster/{templatelets → site/templatelets}/tc_text.rb +2 -9
  121. data/test/buildmaster/{templatelets → site/templatelets}/tc_when.rb +8 -15
  122. data/test/manual/bms.rb +10 -0
  123. data/test/tmp/svn_test/repository/README.txt +5 -0
  124. data/test/tmp/svn_test/repository/conf/authz +21 -0
  125. data/test/tmp/svn_test/repository/conf/passwd +8 -0
  126. data/test/tmp/svn_test/repository/conf/svnserve.conf +30 -0
  127. data/test/tmp/svn_test/repository/db/current +1 -0
  128. data/test/tmp/svn_test/repository/db/format +1 -0
  129. data/test/tmp/svn_test/repository/db/fs-type +1 -0
  130. data/test/tmp/svn_test/repository/db/revprops/0 +5 -0
  131. data/test/tmp/svn_test/repository/db/revprops/1 +13 -0
  132. data/test/tmp/svn_test/repository/db/revprops/2 +13 -0
  133. data/test/tmp/svn_test/repository/db/revprops/3 +13 -0
  134. data/test/tmp/svn_test/repository/db/revprops/4 +13 -0
  135. data/test/tmp/svn_test/repository/db/revs/0 +11 -0
  136. data/test/tmp/svn_test/repository/db/revs/1 +25 -0
  137. data/test/tmp/svn_test/repository/db/revs/2 +29 -0
  138. data/test/tmp/svn_test/repository/db/revs/3 +33 -0
  139. data/test/tmp/svn_test/repository/db/revs/4 +0 -0
  140. data/test/tmp/svn_test/repository/db/uuid +1 -0
  141. data/test/tmp/svn_test/repository/db/write-lock +0 -0
  142. data/test/tmp/svn_test/repository/format +1 -0
  143. data/test/tmp/svn_test/repository/hooks/post-commit.tmpl +51 -0
  144. data/test/tmp/svn_test/repository/hooks/post-lock.tmpl +44 -0
  145. data/test/tmp/svn_test/repository/hooks/post-revprop-change.tmpl +56 -0
  146. data/test/tmp/svn_test/repository/hooks/post-unlock.tmpl +42 -0
  147. data/test/tmp/svn_test/repository/hooks/pre-commit.tmpl +70 -0
  148. data/test/tmp/svn_test/repository/hooks/pre-lock.tmpl +64 -0
  149. data/test/tmp/svn_test/repository/hooks/pre-revprop-change.tmpl +66 -0
  150. data/test/tmp/svn_test/repository/hooks/pre-unlock.tmpl +60 -0
  151. data/test/tmp/svn_test/repository/hooks/start-commit.tmpl +54 -0
  152. data/test/tmp/svn_test/repository/locks/db-logs.lock +3 -0
  153. data/test/tmp/svn_test/repository/locks/db.lock +3 -0
  154. data/test/tmp/svn_test/second/test.txt +1 -0
  155. data/test/tmp/svn_test/workdir/test.txt +1 -0
  156. data/test/ts_buildmaster.rb +0 -1
  157. metadata +168 -69
  158. data/lib/buildmaster.rb +0 -10
  159. data/lib/buildmaster/build_file.rb +0 -11
  160. data/lib/buildmaster/buildnumber +0 -1
  161. data/lib/buildmaster/file_processor.rb +0 -138
  162. data/lib/buildmaster/site_server.rb +0 -33
  163. data/lib/buildmaster/source_content.rb +0 -11
  164. data/lib/buildmaster/svn_driver.rb +0 -78
  165. data/lib/buildmaster/template_error.rb +0 -8
  166. data/lib/buildmaster/templatelets/attribute.rb +0 -16
  167. data/lib/buildmaster/xtemplate.rb +0 -27
  168. data/lib/mock.rb +0 -3
  169. data/lib/mock/mock_base.rb +0 -24
  170. data/test/buildmaster/tc_file_processor.rb +0 -125
  171. data/test/buildmaster/tc_svn_driver.rb +0 -81
  172. data/test/tmp/output/index.html +0 -8
  173. data/test/tmp/output/markdown.html +0 -8
  174. data/test/tmp/output/textile.html +0 -8
@@ -0,0 +1,3 @@
1
+ require 'buildmaster/svn_helper'
2
+
3
+ BuildMaster::SvnHelper.from_directory('.').fix
@@ -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,3 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'common')
2
+ require 'properties'
3
+ require 'tree_to_object'
@@ -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
@@ -1,4 +1,4 @@
1
1
  $:.unshift File.join(File.dirname(__FILE__))
2
2
 
3
3
  require 'cotta/cotta'
4
- require 'cotta/file_not_found_error'
4
+ require 'cotta/file_not_found_error'
@@ -1,5 +1,10 @@
1
1
  module BuildMaster
2
2
  class CommandError < StandardError
3
-
3
+ attr_reader :proc_status, :output
4
+
5
+ def initialize(proc_status, output)
6
+ @proc_status = proc_status
7
+ @output = output
8
+ end
4
9
  end
5
10
  end
@@ -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 shell(command_line)
15
- puts "$> #{command_line}"
16
- @system.shell(command_line)
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
- return @path.basename.to_s
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
- if (@name == '.')
29
- return nil
30
- end
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
- return "#{super}-#@system-#@path"
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
- return "#{super}-#@system-#@path"
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
@@ -0,0 +1,9 @@
1
+ class Pathname
2
+ def cotta_parent
3
+ parent_path = parent
4
+ if (parent_path == self || parent_path.to_s == '..')
5
+ return nil
6
+ end
7
+ return parent_path
8
+ end
9
+ end
@@ -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
- content = path_content(pathname)
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.parent).add(create_dir(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.parent
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.parent
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
- return @file_system[pathname]
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.parent].delete(pathname.basename.to_s)
155
+ @file_system[pathname.cotta_parent].delete(pathname.basename.to_s)
145
156
  end
146
157
 
147
158
  end