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
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            $:.unshift File.dirname(__FILE__)
         | 
| 2 2 |  | 
| 3 | 
            -
            require ' | 
| 3 | 
            +
            require 'template_error'
         | 
| 4 4 |  | 
| 5 5 | 
             
            module BuildMaster
         | 
| 6 6 | 
             
              class TemplateRunner
         | 
| @@ -50,7 +50,7 @@ module BuildMaster | |
| 50 50 | 
             
                  message = "process_#{template_element.name}_directive"
         | 
| 51 51 | 
             
                  templatelet = @templatelets[template_element.name]
         | 
| 52 52 | 
             
                  if (not templatelet)
         | 
| 53 | 
            -
                    raise  | 
| 53 | 
            +
                    raise TemplateError, "unable to process element template:#{template_element.name}"
         | 
| 54 54 | 
             
                  end
         | 
| 55 55 | 
             
                  templatelet.process(target, template_element, @source_instance)
         | 
| 56 56 | 
             
                end
         | 
| @@ -8,7 +8,7 @@ class Attribute | |
| 8 8 | 
             
                name = template.attribute_value!('name')
         | 
| 9 9 | 
             
                eval = template.attribute_value!('eval')
         | 
| 10 10 | 
             
                if (not @evaluator.respond_to?(eval))
         | 
| 11 | 
            -
                  raise  | 
| 11 | 
            +
                  raise TemplateError, '#{@evaluator.class} cannot evaluate expression #{eval}'
         | 
| 12 12 | 
             
                end
         | 
| 13 13 | 
             
                target.attributes[name] = @evaluator.send(eval, source.path)
         | 
| 14 14 | 
             
              end
         | 
| @@ -7,7 +7,7 @@ class Text | |
| 7 7 | 
             
              def process(target, template, source)
         | 
| 8 8 | 
             
                  property = template.attribute_value!('property')
         | 
| 9 9 | 
             
                  value = @properties[property]
         | 
| 10 | 
            -
                  raise  | 
| 10 | 
            +
                  raise TemplateError, "property value for '#{property}' not found" unless value
         | 
| 11 11 | 
             
                  target.add(REXML::Text.new(value))
         | 
| 12 12 | 
             
              end
         | 
| 13 13 | 
             
            end
         | 
| @@ -12,7 +12,7 @@ class When | |
| 12 12 | 
             
              def process(target, template, source)
         | 
| 13 13 | 
             
                eval = template.attribute_value!('test')
         | 
| 14 14 | 
             
                if (not @evaluator.respond_to?(eval))
         | 
| 15 | 
            -
                  raise  | 
| 15 | 
            +
                  raise TemplateError, "#{@evaluator.class} cannot evaluate expression #{eval}"
         | 
| 16 16 | 
             
                end
         | 
| 17 17 | 
             
                if (@evaluator.send(eval, source.path))
         | 
| 18 18 | 
             
                  runner = TemplateRunner.new(target, template, source)
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            $:.unshift File.join(File.dirname(__FILE__), '..')
         | 
| 2 | 
            +
            require 'cotta/cotta'
         | 
| 3 | 
            +
            require 'cotta/in_memory_system'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module BuildMaster
         | 
| 6 | 
            +
            class IisDriver
         | 
| 7 | 
            +
              def initialize(cotta=Cotta.new)
         | 
| 8 | 
            +
                @cotta = cotta
         | 
| 9 | 
            +
                @executable = 'C:\\WINDOWS\\system32\\iisreset.exe'
         | 
| 10 | 
            +
                if (not File.exists?(@executable))
         | 
| 11 | 
            +
                  raise "#{@executable} not found"
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              def status
         | 
| 16 | 
            +
                execute('query')
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def start
         | 
| 20 | 
            +
                execute('start')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def stop
         | 
| 24 | 
            +
                execute('stop')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              private
         | 
| 28 | 
            +
              def execute(command)
         | 
| 29 | 
            +
                #@cotta.shell("#{@executable} /#{command}")
         | 
| 30 | 
            +
                @cotta.shell("sc #{command} W3SVC")
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            $:.unshift File.join(File.dirname(__FILE__), '..', 'cotta')
         | 
| 2 | 
            +
            module BuildMaster
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class SqlServerDriver
         | 
| 5 | 
            +
              def initialize(cotta=Cotta.new)
         | 
| 6 | 
            +
                @instance_name = 'MSSQLSERVER'
         | 
| 7 | 
            +
                @cotta = cotta
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def start
         | 
| 11 | 
            +
                execute('start')
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              def status
         | 
| 15 | 
            +
                execute('query')
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              def stop
         | 
| 19 | 
            +
                execute('stop')
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              private
         | 
| 23 | 
            +
              def execute(command)
         | 
| 24 | 
            +
                @cotta.shell("sc #{command} #{@instance_name}")
         | 
| 25 | 
            +
              end    
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,172 @@ | |
| 1 | 
            +
            $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'buildmaster/cotta'
         | 
| 4 | 
            +
            require 'buildmaster/cotta/cotta_file'
         | 
| 5 | 
            +
            require 'buildmaster/cotta/cotta_dir'
         | 
| 6 | 
            +
            require 'buildmaster/cotta/in_memory_system'
         | 
| 7 | 
            +
            require 'spec'
         | 
| 8 | 
            +
            require 'pathname'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module CottaSpecifications
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            def register_cotta_file_specifications
         | 
| 13 | 
            +
              setup do
         | 
| 14 | 
            +
                @file = BuildMaster::CottaFile.new(@system, Pathname.new('dir/file.txt'))
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              specify 'file can be created with system and pathname' do
         | 
| 18 | 
            +
                @file.name.should_equal 'file.txt'
         | 
| 19 | 
            +
                @file.path.should_equal Pathname.new('dir/file.txt')
         | 
| 20 | 
            +
                @file.exists?.should_equal false
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              specify 'file should know properties like parent, name, etc.' do
         | 
| 24 | 
            +
                @file.parent.should_equal BuildMaster::CottaDir.new(@system, Pathname.new('dir'))
         | 
| 25 | 
            +
                @file.name.should_equal 'file.txt'
         | 
| 26 | 
            +
                @file.path.should_equal Pathname.new('dir/file.txt')
         | 
| 27 | 
            +
                @file.extname.should_equal '.txt'
         | 
| 28 | 
            +
                @file.basename.should_equal 'file'
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              specify 'should load and save file content' do
         | 
| 32 | 
            +
                @file.exists?.should_equal false
         | 
| 33 | 
            +
                @file.parent.exists?.should_equal false
         | 
| 34 | 
            +
                @file.save("content to save\nsecond line")
         | 
| 35 | 
            +
                @file.exists?.should_equal true
         | 
| 36 | 
            +
                @file.load.should_equal("content to save\nsecond line")
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              specify 'should open file to read' do
         | 
| 40 | 
            +
                @file.save("one\ntwo")
         | 
| 41 | 
            +
                @file.read do |file|
         | 
| 42 | 
            +
                  file.gets.should_equal("one\n")
         | 
| 43 | 
            +
                  file.gets.should_equal('two')
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
              
         | 
| 47 | 
            +
              specify 'should equal if same system and pathname' do
         | 
| 48 | 
            +
                file2 = BuildMaster::CottaFile.new(@system, Pathname.new('dir/file.txt'))
         | 
| 49 | 
            +
                file2.should_equal @file
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
              
         | 
| 52 | 
            +
              specify 'should copy to another file' do
         | 
| 53 | 
            +
                file2 = BuildMaster::CottaFile.new(@system, Pathname.new('dir2/file.txt'))
         | 
| 54 | 
            +
                file2.exists?.should_equal false
         | 
| 55 | 
            +
                @file.save('my content')
         | 
| 56 | 
            +
                @file.copy_to(file2)
         | 
| 57 | 
            +
                file2.exists?.should_equal true
         | 
| 58 | 
            +
                file2.load.should_equal 'my content'
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
              
         | 
| 61 | 
            +
              specify 'should move file' do
         | 
| 62 | 
            +
                file2 = BuildMaster::CottaFile.new(@system, Pathname.new('dir2/file.txt'))
         | 
| 63 | 
            +
                file2.exists?.should_equal false
         | 
| 64 | 
            +
                @file.save('content')
         | 
| 65 | 
            +
                @file.move_to(file2)
         | 
| 66 | 
            +
                file2.exists?.should_equal true
         | 
| 67 | 
            +
                file2.load.should_equal 'content'
         | 
| 68 | 
            +
                @file.exists?.should_equal false
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
              
         | 
| 71 | 
            +
              specify 'should support foreach' do
         | 
| 72 | 
            +
                @file.write do |file|
         | 
| 73 | 
            +
                  file.puts 'line one'
         | 
| 74 | 
            +
                  file.puts 'line two'
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
                collected = Array.new
         | 
| 77 | 
            +
                @file.foreach do |line|
         | 
| 78 | 
            +
                  collected.push line
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
                collected.size.should_equal 2
         | 
| 81 | 
            +
                collected[0].should_equal "line one\n"
         | 
| 82 | 
            +
                collected[1].should_equal "line two\n"
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
              
         | 
| 85 | 
            +
              specify 'should delete file' do
         | 
| 86 | 
            +
                @file.save
         | 
| 87 | 
            +
                @file.exists?.should_equal true
         | 
| 88 | 
            +
                @file.delete
         | 
| 89 | 
            +
                @file.exists?.should_equal false
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
              
         | 
| 92 | 
            +
              specify 'should raise error if file to delete does not exist' do
         | 
| 93 | 
            +
                lambda {@file.delete}.should_raise Errno::ENOENT
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            def register_cotta_dir_specifications
         | 
| 99 | 
            +
              setup do
         | 
| 100 | 
            +
                @dir = BuildMaster::CottaDir.new(@system, Pathname.new('dir'))
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              specify 'load dir with basic information' do
         | 
| 104 | 
            +
                @dir.name.should_equal 'dir'
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
              
         | 
| 107 | 
            +
              specify 'dir objects are value objects, equal on system and path' do
         | 
| 108 | 
            +
                (BuildMaster::CottaDir.new(@system, Pathname.new('dir')) == @dir).should_equal true
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
              
         | 
| 111 | 
            +
              specify 'dir should not be equal if path different' do
         | 
| 112 | 
            +
                (BuildMaster::CottaDir.new(@system, Pathname.new('/dir')) == @dir).should_equal false
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
              
         | 
| 115 | 
            +
              specify 'dir should know its parent' do
         | 
| 116 | 
            +
                @dir.parent.name.should_equal '.'
         | 
| 117 | 
            +
                @dir.parent.parent.should_equal nil
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
              
         | 
| 120 | 
            +
              specify 'dir should return sub directory' do
         | 
| 121 | 
            +
                @dir.dir('sub').path.should_equal Pathname.new('dir/sub')
         | 
| 122 | 
            +
                @dir.dir('sub').parent.should_equal @dir
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
              
         | 
| 125 | 
            +
              specify 'dir should return a directory from a relative pathname' do
         | 
| 126 | 
            +
                @dir.dir(Pathname.new('one/two/three')).should_equal @dir.dir('one').dir('two').dir('three')
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
              
         | 
| 129 | 
            +
              specify 'should get file in current directory' do
         | 
| 130 | 
            +
                file = @dir.file('file.txt')
         | 
| 131 | 
            +
                file.name.should_equal 'file.txt'
         | 
| 132 | 
            +
                file.path.should_equal Pathname.new('dir/file.txt')
         | 
| 133 | 
            +
                file.parent.should_equal @dir
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
              
         | 
| 136 | 
            +
              specify 'should create dir and its parent' do
         | 
| 137 | 
            +
                dir = @dir.dir('one').dir('two')
         | 
| 138 | 
            +
                dir.exists?.should_equal false
         | 
| 139 | 
            +
                dir.parent.exists?.should_equal false
         | 
| 140 | 
            +
                dir.mkdirs
         | 
| 141 | 
            +
                dir.exists?.should_equal true
         | 
| 142 | 
            +
                dir.parent.exists?.should_equal true
         | 
| 143 | 
            +
              end
         | 
| 144 | 
            +
              
         | 
| 145 | 
            +
              specify 'should delete dir and its children' do
         | 
| 146 | 
            +
                dir = @dir.dir('one').dir('two').dir('three')
         | 
| 147 | 
            +
                dir.mkdirs
         | 
| 148 | 
            +
                @dir.exists?.should_equal true
         | 
| 149 | 
            +
                @dir.delete
         | 
| 150 | 
            +
                dir.exists?.should_equal false
         | 
| 151 | 
            +
                @dir.exists?.should_equal false
         | 
| 152 | 
            +
              end
         | 
| 153 | 
            +
              
         | 
| 154 | 
            +
              specify 'should do nothing if dir already exists' do
         | 
| 155 | 
            +
                dir = @dir.dir('one').dir('two')
         | 
| 156 | 
            +
                dir.mkdirs
         | 
| 157 | 
            +
                dir.mkdirs
         | 
| 158 | 
            +
              end
         | 
| 159 | 
            +
              
         | 
| 160 | 
            +
              specify 'should list dirs' do
         | 
| 161 | 
            +
                @dir.dir('one').mkdirs
         | 
| 162 | 
            +
                @dir.file('one.txt').save
         | 
| 163 | 
            +
                actual_dir_list = @dir.list
         | 
| 164 | 
            +
                actual_dir_list.size.should_equal 2
         | 
| 165 | 
            +
                actual_dir_list[0].name.should_equal 'one'
         | 
| 166 | 
            +
                actual_dir_list[0].list.size.should_equal 0
         | 
| 167 | 
            +
                actual_dir_list[1].name.should_equal 'one.txt'
         | 
| 168 | 
            +
                actual_dir_list[1].save
         | 
| 169 | 
            +
              end
         | 
| 170 | 
            +
            end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
            end
         | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
         | 
| 2 | 
            +
            require 'buildmaster/cotta/physical_system'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module BuildMaster
         | 
| 5 | 
            +
            class PhysicalSystemStub
         | 
| 6 | 
            +
              attr_reader :executed_commands
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def initialize
         | 
| 9 | 
            +
                @executed_commands = Array.new
         | 
| 10 | 
            +
                tmp_path = File.join(File.dirname(__FILE__), '..', '..', '..', 'tmp')
         | 
| 11 | 
            +
                @system = PhysicalSystem.new
         | 
| 12 | 
            +
                ensure_clean_directory(tmp_path)
         | 
| 13 | 
            +
                Dir.mkdir(File.join(tmp_path, 'current'))
         | 
| 14 | 
            +
                Dir.mkdir(File.join(tmp_path, 'root'))
         | 
| 15 | 
            +
                @tmp_path = Pathname.new(tmp_path)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              def shell(command)
         | 
| 19 | 
            +
                @executed_commands.push command
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              def dir_exists?(pathname)
         | 
| 23 | 
            +
                @system.dir_exists?(relative_from_tmp(pathname))
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
              
         | 
| 26 | 
            +
              def file_exists?(pathname)
         | 
| 27 | 
            +
                @system.file_exists?(relative_from_tmp(pathname))
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
              
         | 
| 30 | 
            +
              def list(pathname)
         | 
| 31 | 
            +
                @system.list(relative_from_tmp(pathname))
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
              
         | 
| 34 | 
            +
              def mkdir(pathname)
         | 
| 35 | 
            +
                @system.mkdir(relative_from_tmp(pathname))
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
              
         | 
| 38 | 
            +
              def delete_file(pathname)
         | 
| 39 | 
            +
                @system.delete_file(relative_from_tmp(pathname))
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
              
         | 
| 42 | 
            +
              def delete_dir(pathname)
         | 
| 43 | 
            +
                @system.delete_dir(relative_from_tmp(pathname))
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
              def io(pathname, arguments)
         | 
| 47 | 
            +
                @system.io(relative_from_tmp(pathname), arguments)
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
              def copy(source, target)
         | 
| 51 | 
            +
                @system.copy(relative_from_tmp(source), relative_from_tmp(target))
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
              
         | 
| 54 | 
            +
              def move(source, target)
         | 
| 55 | 
            +
                @system.move(relative_from_tmp(source), relative_from_tmp(target))
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
              
         | 
| 58 | 
            +
              private
         | 
| 59 | 
            +
              def relative_from_tmp(pathname)
         | 
| 60 | 
            +
                tmp_pathname = nil
         | 
| 61 | 
            +
                if (pathname.absolute?)
         | 
| 62 | 
            +
                  tmp_pathname = Pathname.new("root#{pathname}")
         | 
| 63 | 
            +
                else
         | 
| 64 | 
            +
                  tmp_pathname = Pathname.new("current").join(pathname)
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
                return @tmp_path.join(tmp_pathname)
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
              
         | 
| 69 | 
            +
              def ensure_clean_directory(path)
         | 
| 70 | 
            +
                Dir.mkdir path unless File.directory? path
         | 
| 71 | 
            +
                Dir.foreach(path) do |name|
         | 
| 72 | 
            +
                  if (name != '.' && name != '..')
         | 
| 73 | 
            +
                    child_path = File.join(path, name)
         | 
| 74 | 
            +
                    if (File.directory? child_path)
         | 
| 75 | 
            +
                      ensure_clean_directory(child_path)
         | 
| 76 | 
            +
                      Dir.rmdir(child_path)
         | 
| 77 | 
            +
                    else
         | 
| 78 | 
            +
                      File.delete(child_path)
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
                
         | 
| 84 | 
            +
            end
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,131 @@ | |
| 1 | 
            +
            $:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'buildmaster/cotta'
         | 
| 4 | 
            +
            require 'pathname'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def register_system_file_specifications
         | 
| 7 | 
            +
                  specify 'Log all the shell commands' do
         | 
| 8 | 
            +
                    @system.shell('my command')
         | 
| 9 | 
            +
                    @system.executed_commands.length.should_equal(1)
         | 
| 10 | 
            +
                    @system.executed_commands[0].should_equal 'my command'
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                  
         | 
| 13 | 
            +
                  specify 'root directory always exists' do
         | 
| 14 | 
            +
                    @system.dir_exists?(Pathname.new('/')).should_equal true
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  specify 'current directory always exists' do
         | 
| 18 | 
            +
                    @system.dir_exists?(Pathname.new('.')).should_equal true
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                  specify 'mkdir should create directory' do
         | 
| 22 | 
            +
                    pathname = Pathname.new('/one')
         | 
| 23 | 
            +
                    @system.dir_exists?(pathname).should_equal false
         | 
| 24 | 
            +
                    @system.mkdir(pathname)
         | 
| 25 | 
            +
                    @system.dir_exists?(pathname).should_equal true
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                  
         | 
| 28 | 
            +
                  specify 'mkdir raise error if dir already exists' do
         | 
| 29 | 
            +
                    pathname = Pathname.new('/one')
         | 
| 30 | 
            +
                    @system.mkdir(pathname)
         | 
| 31 | 
            +
                    lambda {@system.mkdir}.should_raise StandardError
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                  
         | 
| 34 | 
            +
                  specify 'io returns IO handle' do
         | 
| 35 | 
            +
                    pathname = Pathname.new('file.txt')
         | 
| 36 | 
            +
                    @system.file_exists?(pathname).should_equal false
         | 
| 37 | 
            +
                    write_io = load_io(pathname, 'w')
         | 
| 38 | 
            +
                    write_io.puts 'content'
         | 
| 39 | 
            +
                    write_io.close
         | 
| 40 | 
            +
                    @system.file_exists?(pathname).should_equal true
         | 
| 41 | 
            +
                    read_io = load_io(pathname, 'r')
         | 
| 42 | 
            +
                    read_io.gets.should_equal "content\n"
         | 
| 43 | 
            +
                    read_io.close
         | 
| 44 | 
            +
                    @system.delete_file(pathname)
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                  
         | 
| 47 | 
            +
                  specify 'file creation should leave file system consistent' do
         | 
| 48 | 
            +
                    pathname = Pathname.new('dir/sub/file.txt')
         | 
| 49 | 
            +
                    @system.mkdir(pathname.parent.parent)
         | 
| 50 | 
            +
                    @system.mkdir(pathname.parent)
         | 
| 51 | 
            +
                    @system.file_exists?(pathname).should_equal false
         | 
| 52 | 
            +
                    @system.dir_exists?(pathname.parent).should_equal true
         | 
| 53 | 
            +
                    load_io(pathname, 'w').close
         | 
| 54 | 
            +
                    @system.file_exists?(pathname).should_equal true
         | 
| 55 | 
            +
                    @system.dir_exists?(pathname).should_equal false
         | 
| 56 | 
            +
                    @system.dir_exists?(pathname.parent).should_equal true
         | 
| 57 | 
            +
                    children = @system.list(pathname.parent)
         | 
| 58 | 
            +
                    children.size.should_equal 1
         | 
| 59 | 
            +
                    children[0].should_equal pathname.basename.to_s
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                  
         | 
| 62 | 
            +
                  specify 'directory creation should leave file system consistent' do
         | 
| 63 | 
            +
                    pathname = Pathname.new('root/dir/sub')
         | 
| 64 | 
            +
                    @system.dir_exists?(pathname).should_equal false
         | 
| 65 | 
            +
                    @system.file_exists?(pathname).should_equal false
         | 
| 66 | 
            +
                    @system.dir_exists?(pathname.parent).should_equal false
         | 
| 67 | 
            +
                    @system.mkdir(pathname.parent.parent)
         | 
| 68 | 
            +
                    @system.mkdir(pathname.parent)
         | 
| 69 | 
            +
                    @system.mkdir(pathname)
         | 
| 70 | 
            +
                    @system.dir_exists?(pathname).should_equal true
         | 
| 71 | 
            +
                    @system.file_exists?(pathname).should_equal false
         | 
| 72 | 
            +
                    @system.dir_exists?(pathname.parent).should_equal true
         | 
| 73 | 
            +
                    list = @system.list(pathname.parent)
         | 
| 74 | 
            +
                    list.size.should_equal 1
         | 
| 75 | 
            +
                    list[0].should_equal(pathname.basename.to_s)
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                  
         | 
| 78 | 
            +
                  specify 'read io should raise error if file does not exists' do
         | 
| 79 | 
            +
                    pathname = Pathname.new('dir/file.txt')
         | 
| 80 | 
            +
                    Proc.new {@system.io(pathname, 'r')}.should_raise Errno::ENOENT
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                  
         | 
| 83 | 
            +
                  specify 'delete dir' do
         | 
| 84 | 
            +
                    pathname = Pathname.new('dir')
         | 
| 85 | 
            +
                    @system.mkdir(pathname)
         | 
| 86 | 
            +
                    @system.delete_dir(pathname)
         | 
| 87 | 
            +
                    @system.dir_exists?(pathname).should_equal false
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                  
         | 
| 90 | 
            +
                  specify 'deleting dir that does not exist should raise error' do
         | 
| 91 | 
            +
                    pathname = Pathname.new('dir/dir2')
         | 
| 92 | 
            +
                    Proc.new {@system.delete_dir(pathname)}.should_raise Errno::ENOENT
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                  
         | 
| 95 | 
            +
                  specify 'copy file' do
         | 
| 96 | 
            +
                    pathname = Pathname.new('file1')
         | 
| 97 | 
            +
                    write_io = load_io(pathname, 'w')
         | 
| 98 | 
            +
                    write_io.puts 'line'
         | 
| 99 | 
            +
                    write_io.close
         | 
| 100 | 
            +
                    target = Pathname.new('target')
         | 
| 101 | 
            +
                    @system.copy(pathname, target)
         | 
| 102 | 
            +
                    @system.file_exists?(target).should_equal true
         | 
| 103 | 
            +
                    read_io = load_io(target, 'r')
         | 
| 104 | 
            +
                    read_io.gets.should_equal "line\n"
         | 
| 105 | 
            +
                    read_io.close
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                  
         | 
| 108 | 
            +
                  specify 'move file' do
         | 
| 109 | 
            +
                    pathname = Pathname.new('file1')
         | 
| 110 | 
            +
                    write_io = load_io(pathname, 'w')
         | 
| 111 | 
            +
                    write_io.puts 'line'
         | 
| 112 | 
            +
                    write_io.close
         | 
| 113 | 
            +
                    target = Pathname.new('target')
         | 
| 114 | 
            +
                    @system.move(pathname, target)
         | 
| 115 | 
            +
                    @system.file_exists?(target).should_equal true
         | 
| 116 | 
            +
                    read_io = load_io(target, 'r')
         | 
| 117 | 
            +
                    read_io.gets.should_equal "line\n"
         | 
| 118 | 
            +
                    read_io.close
         | 
| 119 | 
            +
                    @system.file_exists?(pathname).should_equal false
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                  
         | 
| 122 | 
            +
              end    
         | 
| 123 | 
            +
              def load_io(*args)
         | 
| 124 | 
            +
                io = @system.io(*args)
         | 
| 125 | 
            +
                if (io)
         | 
| 126 | 
            +
                  @ios.push(io)
         | 
| 127 | 
            +
                else
         | 
| 128 | 
            +
                  raise "IO is null for: #{args}"
         | 
| 129 | 
            +
                end
         | 
| 130 | 
            +
                return io
         | 
| 131 | 
            +
              end
         |