screwcap 0.2 → 0.3
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/Manifest.txt +0 -1
- data/Rakefile +1 -1
- data/lib/exts.rb +1 -7
- data/lib/screwcap.rb +4 -2
- data/lib/screwcap/base.rb +0 -42
- data/lib/screwcap/deployer.rb +7 -6
- data/lib/screwcap/server.rb +1 -1
- data/lib/screwcap/task.rb +15 -65
- data/screwcap.gemspec +1 -1
- data/spec/command_set_spec.rb +7 -1
- data/spec/deployer_spec.rb +5 -3
- data/spec/sequence_spec.rb +1 -0
- data/spec/server_spec.rb +3 -6
- data/spec/spec_helper.rb +21 -7
- data/spec/task_spec.rb +16 -9
- data/test/config/command_sets.rb +8 -0
- data/test/config/expect.rb +4 -18
- metadata +4 -5
- data/lib/screwcap/command_set.rb +0 -56
    
        data/Manifest.txt
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | @@ -11,7 +11,7 @@ Hoe.plugin :newgem | |
| 11 11 | 
             
            # Generate all the Rake tasks
         | 
| 12 12 | 
             
            # Run 'rake -T' to see list of generated tasks (from gem root directory)
         | 
| 13 13 | 
             
            $hoe = Hoe.spec 'screwcap' do
         | 
| 14 | 
            -
              self.version  = '0. | 
| 14 | 
            +
              self.version  = '0.3'
         | 
| 15 15 | 
             
              self.developer 'Grant Ammons', 'grant@pipelinedeals.com'
         | 
| 16 16 | 
             
              self.rubyforge_name       = self.name # TODO this is default value
         | 
| 17 17 | 
             
              self.extra_deps         = [['net-ssh','>= 2.0.23'],['net-ssh-gateway','>=1.0.1'], ['net-scp','>=1.0.4']]
         | 
    
        data/lib/exts.rb
    CHANGED
    
    
    
        data/lib/screwcap.rb
    CHANGED
    
    | @@ -8,15 +8,16 @@ require 'ostruct' | |
| 8 8 | 
             
            require 'logger'
         | 
| 9 9 |  | 
| 10 10 | 
             
            require 'exts'
         | 
| 11 | 
            +
            require 'screwcap/message_logger'
         | 
| 11 12 | 
             
            require 'screwcap/base'
         | 
| 12 | 
            -
            require 'screwcap/command_set'
         | 
| 13 13 | 
             
            require 'screwcap/task'
         | 
| 14 14 | 
             
            require 'screwcap/server'
         | 
| 15 | 
            +
            require 'screwcap/runner'
         | 
| 15 16 | 
             
            require 'screwcap/sequence'
         | 
| 16 17 | 
             
            require 'screwcap/deployer'
         | 
| 17 18 |  | 
| 18 19 | 
             
            module Screwcap
         | 
| 19 | 
            -
              VERSION='0. | 
| 20 | 
            +
              VERSION='0.3'
         | 
| 20 21 |  | 
| 21 22 | 
             
              class TaskNotFound < RuntimeError; end
         | 
| 22 23 | 
             
              class NoServersDefined < Exception; end
         | 
| @@ -25,5 +26,6 @@ module Screwcap | |
| 25 26 | 
             
              class IncludeFileNotFound < Exception; end
         | 
| 26 27 | 
             
              class InvalidServer < Exception; end
         | 
| 27 28 | 
             
              class CommandSetDependencyError < Exception; end
         | 
| 29 | 
            +
              class CommandError < Exception; end
         | 
| 28 30 | 
             
            end
         | 
| 29 31 |  | 
    
        data/lib/screwcap/base.rb
    CHANGED
    
    | @@ -10,47 +10,5 @@ module Screwcap | |
| 10 10 | 
             
                def set(var, *args)
         | 
| 11 11 | 
             
                  method_missing((var.to_s + "=").to_sym, args.first)
         | 
| 12 12 | 
             
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                def log(msg, options = {})
         | 
| 15 | 
            -
                  $stdout << msg unless self.__options[:silent] == true
         | 
| 16 | 
            -
                end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def errorlog(msg)
         | 
| 19 | 
            -
                  $stderr << msg unless self.__options[:silent] == true
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def bluebold(msg, options = {:clear => true})
         | 
| 23 | 
            -
                  if self.__options[:nocolor] == true
         | 
| 24 | 
            -
                    msg
         | 
| 25 | 
            -
                  else
         | 
| 26 | 
            -
                    "\033[1;36m#{msg}#{"\033[0m" if options[:clear]}"
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                def blue(msg, options = {:clear => true})
         | 
| 31 | 
            -
                  if self.__options[:nocolor] == true
         | 
| 32 | 
            -
                    msg
         | 
| 33 | 
            -
                  else
         | 
| 34 | 
            -
                    "\033[0;36m#{msg}#{"\033[0m" if options[:clear]}"
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                def red(msg)
         | 
| 40 | 
            -
                  if self.__options[:nocolor] == true
         | 
| 41 | 
            -
                    msg
         | 
| 42 | 
            -
                  else
         | 
| 43 | 
            -
                    "\033[0;31m#{msg}\033[0m"
         | 
| 44 | 
            -
                  end
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                def green(msg)
         | 
| 48 | 
            -
                  if self.__options[:nocolor] == true
         | 
| 49 | 
            -
                    msg
         | 
| 50 | 
            -
                  else
         | 
| 51 | 
            -
                    "\033[0;32m#{msg}\033[0m"
         | 
| 52 | 
            -
                  end
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
             | 
| 55 13 | 
             
              end
         | 
| 56 14 | 
             
            end
         | 
    
        data/lib/screwcap/deployer.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ | |
| 2 2 | 
             
            #
         | 
| 3 3 | 
             
            # The deployer can be thought of as the "global scope" of your tasks file.
         | 
| 4 4 | 
             
            class Deployer < Screwcap::Base
         | 
| 5 | 
            +
              include MessageLogger
         | 
| 5 6 |  | 
| 6 7 | 
             
              # create a new deployer.
         | 
| 7 8 | 
             
              def initialize(opts = {})
         | 
| @@ -16,7 +17,7 @@ class Deployer < Screwcap::Base | |
| 16 17 | 
             
                # ensure that deployer options will not be passed to tasks
         | 
| 17 18 | 
             
                opts.each_key {|k| self.delete_field(k) }
         | 
| 18 19 |  | 
| 19 | 
            -
                log "Reading #{self.__options[:recipe_file]}\n" unless self.__options[:silent] == true
         | 
| 20 | 
            +
                Deployer.log "Reading #{self.__options[:recipe_file]}\n" unless self.__options[:silent] == true
         | 
| 20 21 |  | 
| 21 22 | 
             
                file = File.open(File.expand_path("./#{self.__options[:recipe_file]}"))
         | 
| 22 23 | 
             
                data = file.read
         | 
| @@ -27,14 +28,14 @@ class Deployer < Screwcap::Base | |
| 27 28 |  | 
| 28 29 | 
             
              # create a task.  Minimally, a task needs a :server specified to run the task on.
         | 
| 29 30 | 
             
              def task_for name, options = {}, &block
         | 
| 30 | 
            -
                t = Task.new(options.merge(:name => name, :nocolor => self.__options[:nocolor], :silent => self.__options[:silent], :deployment_servers => self.__servers), &block)
         | 
| 31 | 
            +
                t = Task.new(options.merge(:name => name, :nocolor => self.__options[:nocolor], :silent => self.__options[:silent], :deployment_servers => self.__servers, :command_sets => self.__command_sets), &block)
         | 
| 31 32 | 
             
                clone_table_for(t)
         | 
| 32 33 | 
             
                t.instance_eval(&block)
         | 
| 33 34 | 
             
                self.__tasks << t
         | 
| 34 35 | 
             
              end
         | 
| 35 36 |  | 
| 36 37 | 
             
              def command_set(name,options = {},&block)
         | 
| 37 | 
            -
                t =  | 
| 38 | 
            +
                t = Task.new(options.merge(:name => name, :validate => false, :command_set => true, :command_sets => self.__command_sets), &block)
         | 
| 38 39 | 
             
                clone_table_for(t)
         | 
| 39 40 | 
             
                self.__command_sets << t
         | 
| 40 41 | 
             
              end
         | 
| @@ -66,9 +67,9 @@ class Deployer < Screwcap::Base | |
| 66 67 | 
             
                tasks.each do |t| 
         | 
| 67 68 | 
             
                  sequence = self.__sequences.find {|s| s.__name == t }
         | 
| 68 69 | 
             
                  if sequence
         | 
| 69 | 
            -
                    sequence.__task_names.each {|task_name| self.__tasks.find {|task| task.__name == task_name }. | 
| 70 | 
            +
                    sequence.__task_names.each {|task_name| Runner.execute! self.__tasks.find {|task| task.__name == task_name }, self.__options}
         | 
| 70 71 | 
             
                  else
         | 
| 71 | 
            -
                    self.__tasks.select {|task| task.name.to_s == t.to_s }.first. | 
| 72 | 
            +
                    Runner.execute! self.__tasks.select {|task| task.name.to_s == t.to_s }.first, self.__options
         | 
| 72 73 | 
             
                  end
         | 
| 73 74 | 
             
                end
         | 
| 74 75 | 
             
                $stdout << "\033[0m"
         | 
| @@ -98,7 +99,7 @@ class Deployer < Screwcap::Base | |
| 98 99 |  | 
| 99 100 | 
             
              def clone_table_for(object)
         | 
| 100 101 | 
             
                self.table.each do |k,v|
         | 
| 101 | 
            -
                  object.set(k, v) unless [:__options, :__tasks, :__servers].include?(k)
         | 
| 102 | 
            +
                  object.set(k, v) unless [:__options, :__tasks, :__servers, :__command_sets].include?(k)
         | 
| 102 103 | 
             
                end
         | 
| 103 104 | 
             
              end
         | 
| 104 105 | 
             
            end
         | 
    
        data/lib/screwcap/server.rb
    CHANGED
    
    | @@ -32,7 +32,7 @@ class Server < Screwcap::Base | |
| 32 32 | 
             
              end
         | 
| 33 33 |  | 
| 34 34 | 
             
              def __upload_to!(address, local, remote)
         | 
| 35 | 
            -
                 | 
| 35 | 
            +
                self.__with_connection_for(address) {|ssh| ssh.scp.upload! local, remote }
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 38 | 
             
              protected
         | 
    
        data/lib/screwcap/task.rb
    CHANGED
    
    | @@ -1,11 +1,14 @@ | |
| 1 1 | 
             
            class Task < Screwcap::Base
         | 
| 2 | 
            +
              include MessageLogger
         | 
| 3 | 
            +
             | 
| 2 4 | 
             
              def initialize(opts = {}, &block)
         | 
| 3 5 | 
             
                super
         | 
| 4 6 | 
             
                self.__name = opts[:name]
         | 
| 5 7 | 
             
                self.__options = opts
         | 
| 6 8 | 
             
                self.__commands = []
         | 
| 7 | 
            -
                self.__command_sets = []
         | 
| 9 | 
            +
                self.__command_sets = opts[:command_sets] || []
         | 
| 8 10 | 
             
                self.__server_names = []
         | 
| 11 | 
            +
                self.__block = block if opts[:command_set] == true
         | 
| 9 12 |  | 
| 10 13 |  | 
| 11 14 | 
             
                if opts[:server] and opts[:servers].nil?
         | 
| @@ -14,15 +17,16 @@ class Task < Screwcap::Base | |
| 14 17 | 
             
                  self.__server_names = opts[:servers]
         | 
| 15 18 | 
             
                end
         | 
| 16 19 |  | 
| 17 | 
            -
                validate(opts[:deployment_servers])
         | 
| 20 | 
            +
                validate(opts[:deployment_servers]) unless opts[:validate] == false
         | 
| 18 21 | 
             
              end
         | 
| 19 22 |  | 
| 20 23 | 
             
              # run a command. basically just pass it a string containing the command you want to run.
         | 
| 21 24 | 
             
              def run arg, options = {}
         | 
| 25 | 
            +
             | 
| 22 26 | 
             
                if arg.class == Symbol
         | 
| 23 | 
            -
                  self.__commands << {:command => self.send(arg), :type => :remote}
         | 
| 27 | 
            +
                  self.__commands << options.merge({:command => self.send(arg), :type => :remote, :from => self.__name})
         | 
| 24 28 | 
             
                else
         | 
| 25 | 
            -
                  self.__commands << {:command => arg, :type => :remote}
         | 
| 29 | 
            +
                  self.__commands << options.merge({:command => arg, :type => :remote, :from => self.__name})
         | 
| 26 30 | 
             
                end
         | 
| 27 31 | 
             
              end
         | 
| 28 32 |  | 
| @@ -33,25 +37,15 @@ class Task < Screwcap::Base | |
| 33 37 | 
             
              # run a command. basically just pass it a string containing the command you want to run.
         | 
| 34 38 | 
             
              def local arg, options = {}
         | 
| 35 39 | 
             
                if arg.class == Symbol
         | 
| 36 | 
            -
                  self.__commands << {:command => self.send(arg), :type => :local}
         | 
| 40 | 
            +
                  self.__commands << options.merge({:command => self.send(arg), :type => :local, :from => self.__name})
         | 
| 37 41 | 
             
                else
         | 
| 38 | 
            -
                  self.__commands << {:command => arg, :type => :local}
         | 
| 42 | 
            +
                  self.__commands << options.merge({:command => arg, :type => :local, :from => self.__name})
         | 
| 39 43 | 
             
                end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
              def execute!
         | 
| 44 | 
            -
                threads = []
         | 
| 45 | 
            -
                self.__servers.each do |_server|
         | 
| 46 | 
            -
                  _server.__addresses.each do |_address|
         | 
| 47 | 
            -
                    if self.__options[:parallel] == false
         | 
| 48 | 
            -
                      execute_on(_server, _address)
         | 
| 49 | 
            -
                    else
         | 
| 50 | 
            -
                      threads << Thread.new(_server, _address) { |server, address| execute_on(server, address) }
         | 
| 51 | 
            -
                    end
         | 
| 44 | 
            +
                if failure_cmd = self.__commands.last[:onfailure]
         | 
| 45 | 
            +
                  unless self.__command_sets.find {|cs| cs.__name == failure_cmd }
         | 
| 46 | 
            +
                    raise ScrewCap::ConfigurationError, "Could not find failure command set named '#{failure_cmd}' for task '#{self.__name}'"
         | 
| 52 47 | 
             
                  end
         | 
| 53 48 | 
             
                end
         | 
| 54 | 
            -
                threads.each {|t| t.join }
         | 
| 55 49 | 
             
              end
         | 
| 56 50 |  | 
| 57 51 | 
             
              protected
         | 
| @@ -60,7 +54,7 @@ class Task < Screwcap::Base | |
| 60 54 | 
             
                if m.to_s[0..1] == "__" or [:run].include?(m) or m.to_s.reverse[0..0] == "="
         | 
| 61 55 | 
             
                  super(m, args.first) 
         | 
| 62 56 | 
             
                else
         | 
| 63 | 
            -
                  if cs = self.__command_sets.find {|cs| cs. | 
| 57 | 
            +
                  if cs = self.__command_sets.find {|cs| cs.__name == m }
         | 
| 64 58 | 
             
                    # eval what is in the block
         | 
| 65 59 | 
             
                    clone_table_for(cs)
         | 
| 66 60 | 
             
                    cs.__commands = []
         | 
| @@ -76,7 +70,7 @@ class Task < Screwcap::Base | |
| 76 70 |  | 
| 77 71 | 
             
              def clone_table_for(object)
         | 
| 78 72 | 
             
                self.table.each do |k,v|
         | 
| 79 | 
            -
                  object.set(k, v) unless [: | 
| 73 | 
            +
                  object.set(k, v) unless [:__block, :__tasks, :__name, :__command_sets, :__commands, :__options].include?(k)
         | 
| 80 74 | 
             
                end
         | 
| 81 75 | 
             
              end
         | 
| 82 76 |  | 
| @@ -91,48 +85,4 @@ class Task < Screwcap::Base | |
| 91 85 | 
             
                self.__servers = self.__server_names.map {|name| servers.find {|s| s.name == name } }
         | 
| 92 86 | 
             
              end
         | 
| 93 87 |  | 
| 94 | 
            -
              def execute_on(server, address) 
         | 
| 95 | 
            -
                begin
         | 
| 96 | 
            -
                  log blue("\n*** BEGIN executing task #{self.__name} on #{server.name} with address #{address}\n") unless self.__options[:silent] == true
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                  server.__with_connection_for(address) do |ssh|
         | 
| 99 | 
            -
                    error = false
         | 
| 100 | 
            -
                    self.__commands.each do |command|
         | 
| 101 | 
            -
                      next if error and self.__options[:stop_on_errors]
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                      if command[:type] == :remote
         | 
| 104 | 
            -
                        log green("    I: (#{address}):  #{command[:command]}\n")
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                          ssh.exec! command[:command] do |ch,stream,data|
         | 
| 107 | 
            -
                            if stream == :stderr
         | 
| 108 | 
            -
                              error = true
         | 
| 109 | 
            -
                            errorlog red("    E: (#{address}): #{data}")
         | 
| 110 | 
            -
                          else
         | 
| 111 | 
            -
                            log green("    O: (#{address}):  #{data}")
         | 
| 112 | 
            -
                          end
         | 
| 113 | 
            -
                        end # ssh.exec
         | 
| 114 | 
            -
                      elsif command[:type] == :local
         | 
| 115 | 
            -
                        ret = `#{command[:command]}`
         | 
| 116 | 
            -
                        if $?.to_i == 0
         | 
| 117 | 
            -
                          log blue("    I: (local):  #{command[:command]}\n")
         | 
| 118 | 
            -
                          log blue("    O: (local):  #{ret}\n")
         | 
| 119 | 
            -
                        else
         | 
| 120 | 
            -
                          log blue("    I: (local):  #{command[:command]}\n")
         | 
| 121 | 
            -
                          errorlog red("    O: (local):  #{ret}\n")
         | 
| 122 | 
            -
                        end
         | 
| 123 | 
            -
                      elsif command[:type] == :scp
         | 
| 124 | 
            -
                        server.__upload_to!(address, command[:local], command[:remote])
         | 
| 125 | 
            -
                        log green("    I: (#{address}): SCP #{command[:local]} to #{server.__user}@#{address}:#{command[:remote]}")
         | 
| 126 | 
            -
                      end
         | 
| 127 | 
            -
                    end # commands.each
         | 
| 128 | 
            -
                  end # net.ssh start
         | 
| 129 | 
            -
                rescue Net::SSH::AuthenticationFailed => e
         | 
| 130 | 
            -
                  raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}.  Please check your authentication credentials."
         | 
| 131 | 
            -
                rescue Exception => e
         | 
| 132 | 
            -
                  errorlog red("    F: (#{address}): #{e}")
         | 
| 133 | 
            -
                ensure
         | 
| 134 | 
            -
                  log blue("*** END executing task #{self.__name} on #{server.name} with address #{address}\n\n") unless self.__options[:silent] == true
         | 
| 135 | 
            -
                end
         | 
| 136 | 
            -
              end
         | 
| 137 | 
            -
             | 
| 138 88 | 
             
            end
         | 
    
        data/screwcap.gemspec
    CHANGED
    
    
    
        data/spec/command_set_spec.rb
    CHANGED
    
    | @@ -4,7 +4,7 @@ describe "Command sets" do | |
| 4 4 | 
             
              before(:all) do
         | 
| 5 5 | 
             
                @stdout = []
         | 
| 6 6 | 
             
                Deployer.any_instance.stubs(:log).with() { |msg| @stdout << msg}
         | 
| 7 | 
            -
                @deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent =>  | 
| 7 | 
            +
                @deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent => true)
         | 
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 10 | 
             
              it "should be able to define a generic list of commands" do
         | 
| @@ -48,4 +48,10 @@ describe "Command sets" do | |
| 48 48 | 
             
                task.__command_sets.first.instance_eval(&task.__command_sets.first.__block)
         | 
| 49 49 | 
             
                task.__commands.map {|c| c[:command]}.should == %w(birdo nested birdo task)
         | 
| 50 50 | 
             
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it "should be able to call scp just like a task" do
         | 
| 53 | 
            +
                task = @deployer.__tasks.find {|t| t.__name == :task_use_scp}
         | 
| 54 | 
            +
                task.__command_sets.first.instance_eval(&task.__command_sets.first.__block)
         | 
| 55 | 
            +
                task.__commands.map {|c| c[:command]}.should == [nil]
         | 
| 56 | 
            +
              end
         | 
| 51 57 | 
             
            end
         | 
    
        data/spec/deployer_spec.rb
    CHANGED
    
    | @@ -3,6 +3,7 @@ require 'spec_helper' | |
| 3 3 | 
             
            describe "Deployers" do
         | 
| 4 4 | 
             
              before(:all) do
         | 
| 5 5 | 
             
                Net::SSH.stubs(:start).yields(SSHObject.new(:return_stream => :stdout, :return_data => "hostname = asdf\n"))
         | 
| 6 | 
            +
                Runner.stubs(:ssh_exec!).returns(["ok","",0,nil])
         | 
| 6 7 | 
             
              end
         | 
| 7 8 |  | 
| 8 9 | 
             
              it "should complain if no server was defined" do
         | 
| @@ -40,7 +41,7 @@ describe "Deployers" do | |
| 40 41 |  | 
| 41 42 | 
             
              it "should be able to define command sets" do
         | 
| 42 43 | 
             
                deployer = Deployer.new(:recipe_file => "./test/config/command_sets.rb", :silent => true)
         | 
| 43 | 
            -
                deployer.should have( | 
| 44 | 
            +
                deployer.should have(9).__command_sets
         | 
| 44 45 | 
             
              end
         | 
| 45 46 |  | 
| 46 47 | 
             
              it "should be able to define gateways" do
         | 
| @@ -51,12 +52,13 @@ describe "Deployers" do | |
| 51 52 |  | 
| 52 53 | 
             
              it "should be able to define sequences" do
         | 
| 53 54 | 
             
                deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
         | 
| 54 | 
            -
                deployer.should have | 
| 55 | 
            +
                deployer.should have(1).__sequences
         | 
| 55 56 | 
             
              end
         | 
| 56 57 |  | 
| 57 58 | 
             
              it "should be able to run a single task" do
         | 
| 58 59 | 
             
                deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
         | 
| 59 | 
            -
                 | 
| 60 | 
            +
                deployer.run! :task1
         | 
| 61 | 
            +
                #lambda { deployer.run! :task1 }.should_not raise_error
         | 
| 60 62 | 
             
              end
         | 
| 61 63 |  | 
| 62 64 | 
             
              it "should be able to run multiple tasks" do
         | 
    
        data/spec/sequence_spec.rb
    CHANGED
    
    
    
        data/spec/server_spec.rb
    CHANGED
    
    | @@ -4,11 +4,8 @@ describe "Servers" do | |
| 4 4 | 
             
              before(:each) do
         | 
| 5 5 | 
             
                @stdout = []
         | 
| 6 6 | 
             
                @stderr = []
         | 
| 7 | 
            -
                 | 
| 8 | 
            -
                 | 
| 9 | 
            -
                Deployer.any_instance.stubs(:log).with() { |msg| @stdout <<  msg }
         | 
| 10 | 
            -
                Deployer.any_instance.stubs(:errorlog).with() { |msg| @stderr <<  msg }
         | 
| 11 | 
            -
             | 
| 7 | 
            +
                Runner.stubs(:log).with() { |msg,opts| @stdout <<  msg }
         | 
| 8 | 
            +
                Runner.stubs(:errorlog).with() { |msg,opts| @stderr <<  msg }
         | 
| 12 9 | 
             
                Net::SSH::Gateway.stubs(:new).returns(SSHObject.new)
         | 
| 13 10 | 
             
              end
         | 
| 14 11 |  | 
| @@ -34,7 +31,7 @@ describe "Servers" do | |
| 34 31 | 
             
              end
         | 
| 35 32 |  | 
| 36 33 | 
             
              it "should provide a connection to the server with a gateway" do
         | 
| 37 | 
            -
                @deployer = Deployer.new(:recipe_file => "./test/config/gateway.rb", :silent =>  | 
| 34 | 
            +
                @deployer = Deployer.new(:recipe_file => "./test/config/gateway.rb", :silent => true)
         | 
| 38 35 | 
             
                server = @deployer.__servers.find {|s| s.__name == :test}
         | 
| 39 36 | 
             
                gateway = @deployer.__servers.find {|s| s.__name == :gateway1}
         | 
| 40 37 |  | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -7,19 +7,33 @@ require 'mocha' | |
| 7 7 | 
             
            require 'ruby-debug' rescue nil
         | 
| 8 8 | 
             
            require 'net/ssh'
         | 
| 9 9 |  | 
| 10 | 
            -
            class SSHObject
         | 
| 10 | 
            +
            class SSHObject < OpenStruct
         | 
| 11 11 | 
             
              attr_accessor :options
         | 
| 12 12 |  | 
| 13 13 | 
             
              def initialize(options = {})
         | 
| 14 | 
            -
                @options = {:return_stream => :stdout}
         | 
| 15 | 
            -
                @options = options
         | 
| 16 14 | 
             
              end
         | 
| 17 15 |  | 
| 18 | 
            -
              def  | 
| 19 | 
            -
                yield  | 
| 16 | 
            +
              def on_data
         | 
| 17 | 
            +
                yield SSHObject.new, ""
         | 
| 20 18 | 
             
              end
         | 
| 21 19 |  | 
| 22 | 
            -
              def  | 
| 23 | 
            -
                yield  | 
| 20 | 
            +
              def on_extended_data
         | 
| 21 | 
            +
                yield SSHObject.new, "", ""
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def read_long
         | 
| 25 | 
            +
                ""
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def upload!(from, to)
         | 
| 29 | 
            +
                nil
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def scp
         | 
| 33 | 
            +
                SSHObject.new
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def on_request(item)
         | 
| 37 | 
            +
                yield SSHObject.new, SSHObject.new
         | 
| 24 38 | 
             
              end
         | 
| 25 39 | 
             
            end
         | 
    
        data/spec/task_spec.rb
    CHANGED
    
    | @@ -4,16 +4,15 @@ describe "Tasks" do | |
| 4 4 | 
             
              before(:each) do
         | 
| 5 5 | 
             
                @stdout = []
         | 
| 6 6 | 
             
                @stderr = []
         | 
| 7 | 
            -
                 | 
| 8 | 
            -
                 | 
| 9 | 
            -
                Deployer. | 
| 10 | 
            -
                Deployer.any_instance.stubs(:errorlog).with() { |msg| @stderr <<  msg }
         | 
| 11 | 
            -
                @deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => false)
         | 
| 7 | 
            +
                Runner.stubs(:log).with() { |msg,opts| @stdout <<  msg }
         | 
| 8 | 
            +
                Runner.stubs(:errorlog).with() { |msg,opts| @stderr <<  msg }
         | 
| 9 | 
            +
                @deployer = Deployer.new(:recipe_file => "./test/config/simple_recipe.rb", :silent => true)
         | 
| 12 10 | 
             
              end
         | 
| 13 11 |  | 
| 14 12 | 
             
              before(:all) do
         | 
| 15 13 | 
             
                Net::SSH.stubs(:start).yields(SSHObject.new(:return_stream => :stdout, :return_data => "hostname = asdf\n"))
         | 
| 16 14 | 
             
                Net::SCP.stubs(:upload!).returns(nil)
         | 
| 15 | 
            +
                Runner.stubs(:ssh_exec!).returns(["ok","",0,nil])
         | 
| 17 16 | 
             
              end
         | 
| 18 17 |  | 
| 19 18 | 
             
              it "should be able to create variables" do
         | 
| @@ -28,9 +27,9 @@ describe "Tasks" do | |
| 28 27 |  | 
| 29 28 | 
             
              it "should be able to execute statements on a remote server" do
         | 
| 30 29 | 
             
                task = @deployer.__tasks.find {|t| t.name == :task1 }
         | 
| 31 | 
            -
                 | 
| 30 | 
            +
                Runner.execute! task, @deployer.__options
         | 
| 32 31 | 
             
                @stderr.should == []
         | 
| 33 | 
            -
                @stdout.size.should ==  | 
| 32 | 
            +
                @stdout.size.should == 26
         | 
| 34 33 | 
             
              end
         | 
| 35 34 |  | 
| 36 35 | 
             
              it "should be able to use variables in the run statement" do
         | 
| @@ -52,11 +51,11 @@ describe "Tasks" do | |
| 52 51 | 
             
              end
         | 
| 53 52 |  | 
| 54 53 | 
             
              it "should complain if you do not pass the task a server argument" do
         | 
| 55 | 
            -
                lambda { Deployer.new(:recipe_file => "./test/config/no_server.rb", :silent =>  | 
| 54 | 
            +
                lambda { Deployer.new(:recipe_file => "./test/config/no_server.rb", :silent => true)}.should raise_error(Screwcap::ConfigurationError)
         | 
| 56 55 | 
             
              end
         | 
| 57 56 |  | 
| 58 57 | 
             
              it "should complain if you pass a server that is not defined" do
         | 
| 59 | 
            -
                lambda { Deployer.new(:recipe_file => "./test/config/undefined_server.rb", :silent =>  | 
| 58 | 
            +
                lambda { Deployer.new(:recipe_file => "./test/config/undefined_server.rb", :silent => true)}.should raise_error(Screwcap::ConfigurationError)
         | 
| 60 59 | 
             
              end
         | 
| 61 60 |  | 
| 62 61 | 
             
              it "should be able to disable parallel running" do
         | 
| @@ -72,4 +71,12 @@ describe "Tasks" do | |
| 72 71 | 
             
                deployer = Deployer.new(:recipe_file => "./test/config/upload.rb", :silent => true)
         | 
| 73 72 | 
             
                deployer.run! :upload
         | 
| 74 73 | 
             
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              it "should respond to onfailure" do
         | 
| 76 | 
            +
                deployer = Deployer.new(:recipe_file => "./test/config/expect.rb", :silent => true)
         | 
| 77 | 
            +
                t = deployer.__tasks.find {|t| t.__name == :expect }
         | 
| 78 | 
            +
                Runner.stubs(:ssh_exec!).returns(["","fail",1,nil]).then.returns(["ok","",0,nil])
         | 
| 79 | 
            +
                Runner.execute! t, deployer.__options
         | 
| 80 | 
            +
                t.__commands.map {|c| [c[:command], c[:from]] }.first.should == ["echo 'we failed'", :failover]
         | 
| 81 | 
            +
              end
         | 
| 75 82 | 
             
            end
         | 
    
        data/test/config/command_sets.rb
    CHANGED
    
    | @@ -47,6 +47,10 @@ command_set :nested_outside_with_var do | |
| 47 47 | 
             
              run :nested_var
         | 
| 48 48 | 
             
            end
         | 
| 49 49 |  | 
| 50 | 
            +
            command_set :use_scp do
         | 
| 51 | 
            +
              scp :local => "/tmp/test", :remote => "/tmp/test"
         | 
| 52 | 
            +
            end
         | 
| 53 | 
            +
             | 
| 50 54 |  | 
| 51 55 | 
             
            task_for :use_command_set_no_override, :server => :test do
         | 
| 52 56 | 
             
              push_to_thang
         | 
| @@ -85,3 +89,7 @@ task_for :nested_scoping, :server => :test do | |
| 85 89 | 
             
              nested_outside_with_var
         | 
| 86 90 | 
             
              run :nested_var
         | 
| 87 91 | 
             
            end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            task_for :task_use_scp, :server => :test do
         | 
| 94 | 
            +
              use_scp
         | 
| 95 | 
            +
            end
         | 
    
        data/test/config/expect.rb
    CHANGED
    
    | @@ -5,26 +5,12 @@ command_set :revert do | |
| 5 5 | 
             
              run "revert"
         | 
| 6 6 | 
             
            end
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
               | 
| 10 | 
            -
              when 1
         | 
| 11 | 
            -
                run "1"
         | 
| 12 | 
            -
              when 2
         | 
| 13 | 
            -
                run "2"
         | 
| 14 | 
            -
              else
         | 
| 15 | 
            -
                run "none"
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
            end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
            command_set :fail do
         | 
| 20 | 
            -
              run "ls"
         | 
| 21 | 
            -
            end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            command_set :success do
         | 
| 24 | 
            -
              run "ls"
         | 
| 8 | 
            +
            command_set :failover do
         | 
| 9 | 
            +
              run "echo 'we failed'"
         | 
| 25 10 | 
             
            end
         | 
| 26 11 |  | 
| 27 12 | 
             
            task_for :expect, :server => :test do 
         | 
| 28 | 
            -
              run " | 
| 13 | 
            +
              run "this will fail", :onfailure => :failover
         | 
| 14 | 
            +
              run "ls"
         | 
| 29 15 | 
             
            end
         | 
| 30 16 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,12 +1,12 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: screwcap
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 13
         | 
| 5 5 | 
             
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              version: "0. | 
| 8 | 
            +
              - 3
         | 
| 9 | 
            +
              version: "0.3"
         | 
| 10 10 | 
             
            platform: ruby
         | 
| 11 11 | 
             
            authors: 
         | 
| 12 12 | 
             
            - Grant Ammons
         | 
| @@ -14,7 +14,7 @@ autorequire: | |
| 14 14 | 
             
            bindir: bin
         | 
| 15 15 | 
             
            cert_chain: []
         | 
| 16 16 |  | 
| 17 | 
            -
            date: 2010-10- | 
| 17 | 
            +
            date: 2010-10-25 00:00:00 -04:00
         | 
| 18 18 | 
             
            default_executable: 
         | 
| 19 19 | 
             
            dependencies: 
         | 
| 20 20 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -122,7 +122,6 @@ files: | |
| 122 122 | 
             
            - lib/exts.rb
         | 
| 123 123 | 
             
            - lib/screwcap.rb
         | 
| 124 124 | 
             
            - lib/screwcap/base.rb
         | 
| 125 | 
            -
            - lib/screwcap/command_set.rb
         | 
| 126 125 | 
             
            - lib/screwcap/deployer.rb
         | 
| 127 126 | 
             
            - lib/screwcap/sequence.rb
         | 
| 128 127 | 
             
            - lib/screwcap/server.rb
         | 
    
        data/lib/screwcap/command_set.rb
    DELETED
    
    | @@ -1,56 +0,0 @@ | |
| 1 | 
            -
            class CommandSet < Screwcap::Base
         | 
| 2 | 
            -
              def initialize(opts = {}, &block)
         | 
| 3 | 
            -
                super
         | 
| 4 | 
            -
                self.__name = opts[:name]
         | 
| 5 | 
            -
                self.__options = opts
         | 
| 6 | 
            -
                self.__commands = []
         | 
| 7 | 
            -
                self.__command_sets = []
         | 
| 8 | 
            -
                self.__block = block
         | 
| 9 | 
            -
              end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              # run a command. basically just pass it a string containing the command you want to run.
         | 
| 12 | 
            -
              def run arg, options = {}
         | 
| 13 | 
            -
                if arg.class == Symbol
         | 
| 14 | 
            -
                  self.__commands << {:command => self.send(arg), :type => :remote}
         | 
| 15 | 
            -
                else
         | 
| 16 | 
            -
                  self.__commands << {:command => arg, :type => :remote}
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
              end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
              # run a command. basically just pass it a string containing the command you want to run.
         | 
| 21 | 
            -
              def local arg, options = {}
         | 
| 22 | 
            -
                if arg.class == Symbol
         | 
| 23 | 
            -
                  self.__commands << {:command => self.send(arg), :type => :local}
         | 
| 24 | 
            -
                else
         | 
| 25 | 
            -
                  self.__commands << {:command => arg, :type => :local}
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
              protected
         | 
| 31 | 
            -
             | 
| 32 | 
            -
              def method_missing(m, *args)
         | 
| 33 | 
            -
                if m.to_s[0..1] == "__" or [:run].include?(m) or m.to_s.reverse[0..0] == "="
         | 
| 34 | 
            -
                  super(m, args.first) 
         | 
| 35 | 
            -
                else
         | 
| 36 | 
            -
                  if cs = self.__command_sets.find {|cs| cs.name == m }
         | 
| 37 | 
            -
                    # eval what is in the block
         | 
| 38 | 
            -
                    clone_table_for(cs)
         | 
| 39 | 
            -
                    cs.__commands = []
         | 
| 40 | 
            -
                    cs.instance_eval(&cs.__block)
         | 
| 41 | 
            -
                    self.__commands += cs.__commands
         | 
| 42 | 
            -
                  else
         | 
| 43 | 
            -
                    raise NoMethodError, "Undefined method '#{m.to_s}' for Command Set :#{self.name.to_s}"
         | 
| 44 | 
            -
                  end
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
              end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
              private
         | 
| 49 | 
            -
             | 
| 50 | 
            -
              def clone_table_for(object)
         | 
| 51 | 
            -
                self.table.each do |k,v|
         | 
| 52 | 
            -
                  object.set(k, v) unless [:__command_sets, :name, :__commands, :__options, :__block].include?(k)
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
            end
         |