lib/rye/box.rb in rye-0.8.6 vs lib/rye/box.rb in rye-0.8.7

- old
+ new

@@ -167,11 +167,11 @@ @rye_current_working_directory = newpath else @rye_current_working_directory = fpath end end - info "CWD: #{@rye_current_working_directory}" + debug "CWD: #{@rye_current_working_directory}" self end # Like [] except it returns an empty Rye::Rap object to mimick # a regular command method. Call with nil key (or no arg) to # reset. @@ -718,11 +718,11 @@ # to get a name collision. I could write a work around but I think # this is good enough for now. ## raise Rye::CommandNotFound unless self.can?(cmd) begin - info "COMMAND: #{cmd_internal}" + debug "COMMAND: #{cmd_internal}" if !@rye_quiet && @rye_pre_command_hook.is_a?(Proc) @rye_pre_command_hook.call(cmd_clean, user, host, nickname) end @@ -800,16 +800,16 @@ # http://www.ruby-forum.com/topic/141814 # http://www.ruby-forum.com/topic/169997 # def net_ssh_exec!(command) - block ||= Proc.new do |channel, type, data| + block ||= Proc.new do |channel, type, data, tt| channel[:stdout] ||= "" channel[:stderr] ||= "" - channel[:stdout] << data if type == :stdout + if type == :stderr # NOTE: Use sudo to test this since it prompts for a passwords. # Use sudo -K to kill the user's timestamp (ask for a password every time) if data =~ /password:/i ret = Annoy.get_user_input("Password: ", '*') @@ -822,11 +822,19 @@ # If someone tries to open an interactive ssh session # through a regular Rye::Box command, Net::SSH will # return the following error and appear to hang. We # catch it and raise the appropriate exception. raise Rye::NoPty if data =~ /Pseudo-terminal will not/ - + elsif type == :stdout + if data =~ /Select gem to uninstall/i + puts data + ret = Annoy.get_user_input('') + raise "No input given" if ret.nil? + channel.send_data "#{ret}\n" + else + channel[:stdout] << data + end end end channel = @rye_ssh.exec(command, &block) @@ -863,10 +871,11 @@ [channel[:stdout], channel[:stderr], channel[:exit_code], channel[:exit_signal]] end # * +direction+ is one of :upload, :download + # * +recursive+ should be true for directories and false for files. # * +files+ is an Array of file paths, the content is direction specific. # For downloads, +files+ is a list of files to download. The last element # must be the local directory to download to. If downloading a single file # the last element can be a file path. The target can also be a StringIO. # For uploads, +files+ is a list of files to upload. The last element is @@ -876,18 +885,18 @@ # it does not exist, but only when multiple files are being transferred. # This method will fail early if there are obvious problems with the input # parameters. An exception is raised and no files are transferred. # Uploads always return nil. Downloads return nil or a StringIO object if # one is specified for the target. - def net_scp_transfer!(direction, *files) - direction ||= '' + def net_scp_transfer!(direction, recursive, *files) + unless [:upload, :download].member?(direction.to_sym) raise "Must be one of: upload, download" end if @rye_current_working_directory - info "CWD (#{@rye_current_working_directory})" + debug "CWD (#{@rye_current_working_directory})" end files = [files].flatten.compact || [] # We allow a single file to be downloaded into a StringIO object @@ -909,11 +918,14 @@ target = files.pop end # Expand fileglobs (e.g. path/*.rb becomes [path/1.rb, path/2.rb]). # This should happen after checking files.size to determine the target - files = files.collect { |file| Dir.glob file }.flatten unless @rye_safe + unless @rye_safe + files.collect! { |file| Dir.glob File.expand_path(file) } + files.flatten! + end end # Fail early. We check whether the StringIO object is available to read files.each do |file| if file.is_a?(StringIO) @@ -922,29 +934,35 @@ # If a StringIO object is at end of file, SCP will hang. (TODO: SCP) file.rewind if file.eof? end end - info "#{direction.to_s.upcase} TO: #{target}" + info "#{direction.to_s} to: #{target}" debug "FILES: " << files.join(', ') - # Make sure the remote directory exists. We can do this only when + # Make sure the target directory exists. We can do this only when # there's more than one file because "target" could be a file name if files.size > 1 && !target.is_a?(StringIO) debug "CREATING TARGET DIRECTORY: #{target}" self.mkdir(:p, target) unless self.file_exists?(target) end Net::SCP.start(@rye_host, @rye_opts[:user], @rye_opts || {}) do |scp| transfers = [] + prev = "" files.each do |file| debug file.to_s - transfers << scp.send(direction, file, target) do |ch, n, s, t| - pinfo "#{n}: #{s}/#{t}b\r" # update line: "file: sent/total" + prev = "" + transfers << scp.send(direction, file, target, :recursive => recursive) do |ch, n, s, t| + line = "%-50s %6d/%-6d bytes" % [n, s, t] + spaces = (prev.size > line.size) ? ' '*(prev.size - line.size) : '' + pinfo "%s %s \r" % [line, spaces] # update line: "file: sent/total" @rye_info.flush if @rye_info # make sure every line is printed + prev = line end end transfers.each { |t| t.wait } # Run file transfers in parallel + pinfo (' '*prev.size) << "\r" info $/ end target.is_a?(StringIO) ? target : nil end