Module: MultiZip::Backend::Cli::InfoZip
- Defined in:
- lib/multi_zip/backend/cli/info_zip.rb
Defined Under Namespace
Modules: InstanceMethods Classes: ResponseError
Constant Summary collapse
- BUFFER_SIZE =
8192
- WHICH_PROGRAM =
TODO: better way to find full path to programs?
'which'
- ZIP_AND_UNZIP_ARE_SAME_PROGRAM =
false
- ZIP_PROGRAM =
'zip'
- ZIP_PROGRAM_SIGNATURE =
/This is Zip [2-3].\d+\s.+, by Info-ZIP/
- ZIP_PROGRAM_SIGNATURE_SWITCH =
'-v'
- ZIP_PROGRAM_REMOVE_MEMBER_SWITCH =
'-d'
- UNZIP_PROGRAM =
'unzip'
- UNZIP_PROGRAM_SIGNATURE =
/UnZip [5-6]\.\d+ of .+, by Info-ZIP/
- UNZIP_PROGRAM_SIGNATURE_SWITCH =
'-v'
- UNZIP_PROGRAM_LIST_MEMBERS_SWITCHES =
['-Z', '-1']
- UNZIP_PROGRAM_READ_MEMBER_SWITCH =
'-p'
- UNZIP_PROGRAM_MEMBER_INFO_SWITCHES =
['-Z']
- UNZIP_PROGRAM_EMPTY_ZIPFILE_MESSAGE =
TODO: does this change between versions? TODO: does this change with system language?
'Empty zipfile.'
- UNZIP_PROGRAM_MEMBER_NOT_FOUND_MESSAGE =
'caution: filename not matched:'
- UNZIP_PROGRAM_INVALID_FILE_MESSAGE =
'End-of-central-directory signature not found'
Class Method Summary collapse
-
._spawn(argv, input, output, error) ⇒ Object
Blatant copy from github.com/seamusabshere/unix_utils/blob/master/lib/unix_utils.rb.
- .available? ⇒ Boolean
- .extend_class ⇒ Object
- .human_name ⇒ Object
- .programs_found? ⇒ Boolean
- .require_name ⇒ Object
-
.spawn(argv, options = {}) ⇒ Object
Blatant copy from github.com/seamusabshere/unix_utils/blob/master/lib/unix_utils.rb.
- .unzip_program_found? ⇒ Boolean
- .zip_program_found? ⇒ Boolean
Class Method Details
._spawn(argv, input, output, error) ⇒ Object
Blatant copy from github.com/seamusabshere/unix_utils/blob/master/lib/unix_utils.rb
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# 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? ⇒ Boolean
43 44 45 |
# File 'lib/multi_zip/backend/cli/info_zip.rb', line 43 def self.available? @available ||= programs_found? end |
.extend_class ⇒ Object
35 36 37 |
# File 'lib/multi_zip/backend/cli/info_zip.rb', line 35 def self.extend_class lambda { MultiZip::Backend::Cli::InfoZip::InstanceMethods } end |
.human_name ⇒ Object
39 40 41 |
# File 'lib/multi_zip/backend/cli/info_zip.rb', line 39 def self.human_name 'Info-ZIP - zip(1L)/unzip(1L)' end |
.programs_found? ⇒ Boolean
47 48 49 50 51 52 53 |
# 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 ⇒ Object
31 32 33 |
# File 'lib/multi_zip/backend/cli/info_zip.rb', line 31 def self.require_name 'info_zip' end |
.spawn(argv, options = {}) ⇒ Object
Blatant copy from github.com/seamusabshere/unix_utils/blob/master/lib/unix_utils.rb
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/multi_zip/backend/cli/info_zip.rb', line 72 def self.spawn(argv, = {}) # :nodoc: input = if (read_from = [:read_from]) if RUBY_DESCRIPTION =~ /jruby 1.7.0/ raise "MultiZip: Can't use `#{argv.first}` since JRuby 1.7.0 has a broken IO implementation!" end File.open(read_from, 'r') end output = if (write_to = [:write_to]) output_redirected = true File.open(write_to, 'wb') else output_redirected = false StringIO.new end error = StringIO.new if (chdir = [:chdir]) Dir.chdir(chdir) do _spawn argv, input, output, error end else _spawn argv, input, output, error end error.rewind whole_error = error.read unless whole_error.empty? $stderr.puts "MultiZip: `#{argv.join(' ')}` STDERR:" $stderr.puts whole_error end unless output_redirected output.rewind [output.read, whole_error].map{|o| o.empty? ? nil : o} end ensure [input, output, error].each { |io| io.close if io and not io.closed? } end |
.unzip_program_found? ⇒ Boolean
63 64 65 66 67 68 69 |
# 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? ⇒ Boolean
55 56 57 58 59 60 61 |
# 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 |