module MultiZip::Backend::Cli::InfoZip

Constants

BUFFER_SIZE
UNZIP_PROGRAM
UNZIP_PROGRAM_EMPTY_ZIPFILE_MESSAGE

TODO: does this change between versions? TODO: does this change with system language?

UNZIP_PROGRAM_INVALID_FILE_MESSAGE
UNZIP_PROGRAM_LIST_MEMBERS_SWITCHES
UNZIP_PROGRAM_MEMBER_INFO_SWITCHES
UNZIP_PROGRAM_MEMBER_NOT_FOUND_MESSAGE
UNZIP_PROGRAM_READ_MEMBER_SWITCH
UNZIP_PROGRAM_SIGNATURE
UNZIP_PROGRAM_SIGNATURE_SWITCH
WHICH_PROGRAM

TODO: better way to find full path to programs?

ZIP_AND_UNZIP_ARE_SAME_PROGRAM
ZIP_PROGRAM
ZIP_PROGRAM_REMOVE_MEMBER_SWITCH
ZIP_PROGRAM_SIGNATURE
ZIP_PROGRAM_SIGNATURE_SWITCH

Public Class Methods

_spawn(argv, input, output, error) click to toggle source

Blatant copy from github.com/seamusabshere/unix_utils/blob/master/lib/unix_utils.rb

# File lib/multi_zip/backend/cli/info_zip.rb, line 109
def self._spawn(argv, input, output, error)
  # lifted from posix-spawn
  # https://github.com/rtomayko/posix-spawn/blob/master/lib/posix/spawn/child.rb
  Open3.popen3(*argv) do |stdin, stdout, stderr|
    readers = [stdout, stderr]
    if RUBY_DESCRIPTION =~ /jruby 1.7.0/
      readers.delete stderr
    end
    writers = if input
      [stdin]
    else
      stdin.close
      []
    end
    while readers.any? or writers.any?
      ready = IO.select(readers, writers, readers + writers)
      # write to stdin stream
      ready[1].each do |fd|
        begin
          boom = nil
          size = fd.write input.read(BUFFER_SIZE)
        rescue Errno::EPIPE => boom
        rescue Errno::EAGAIN, Errno::EINTR
        end
        if boom || size < BUFFER_SIZE
          stdin.close
          input.close
          writers.delete stdin
        end
      end
      # read from stdout and stderr streams
      ready[0].each do |fd|
        buf = (fd == stdout) ? output : error
        if fd.eof?
          readers.delete fd
          fd.close
        else
          begin
            # buf << fd.gets(BUFFER_SIZE) # maybe?
            buf << fd.readpartial(BUFFER_SIZE)
          rescue Errno::EAGAIN, Errno::EINTR
          end
        end
      end
    end
    # thanks @tmm1 and @rtomayko for showing how it's done!
  end
end
available?() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 43
def self.available?
  @available ||= programs_found?
end
extend_class() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 35
def self.extend_class
  lambda { MultiZip::Backend::Cli::InfoZip::InstanceMethods }
end
human_name() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 39
def self.human_name
  'Info-ZIP - zip(1L)/unzip(1L)'
end
programs_found?() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 47
def self.programs_found?
  if ZIP_AND_UNZIP_ARE_SAME_PROGRAM
    zip_program_found?
  else
    zip_program_found? && unzip_program_found?
  end
end
require_name() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 31
def self.require_name
  'info_zip'
end
unzip_program_found?() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 63
def self.unzip_program_found?
  unzip_program_path = `#{WHICH_PROGRAM} #{UNZIP_PROGRAM}`.strip
  return false unless unzip_program_path =~ /#{UNZIP_PROGRAM}/
  return false unless File.exists?(unzip_program_path)

  spawn([UNZIP_PROGRAM, UNZIP_PROGRAM_SIGNATURE_SWITCH]).first =~ UNZIP_PROGRAM_SIGNATURE
end
zip_program_found?() click to toggle source
# File lib/multi_zip/backend/cli/info_zip.rb, line 55
def self.zip_program_found?
  zip_program_path = `#{WHICH_PROGRAM} #{ZIP_PROGRAM}`.strip
  return false unless zip_program_path =~ /#{ZIP_PROGRAM}/
  return false unless File.exists?(zip_program_path)

  spawn([ZIP_PROGRAM, ZIP_PROGRAM_SIGNATURE_SWITCH]).first =~ ZIP_PROGRAM_SIGNATURE
end