Class: Pliney::IPA
- Inherits:
-
Object
- Object
- Pliney::IPA
- Defined in:
- lib/pliney/ipa.rb
Defined Under Namespace
Classes: ZipExtractError
Constant Summary collapse
- SYSTEM_HAS_UNZIP =
system("which unzip > /dev/null")
Instance Attribute Summary collapse
-
#zipfile ⇒ Object
readonly
TODO - creating an ipa from scratch? def self.create(path) new(Zip::File.open(path, Zip::File::CREATE)) end.
Class Method Summary collapse
Instance Method Summary collapse
- #appdir ⇒ Object
- #bundle_identifier ⇒ Object
- #bundle_short_version ⇒ Object
- #bundle_version ⇒ Object
- #canonical_name ⇒ Object
- #close ⇒ Object
- #codesignature_for_entry(file_entry) ⇒ Object
- #each_executable_entry ⇒ Object
- #each_file_entry ⇒ Object
- #entitlements_data_for_entry(file_entry) ⇒ Object
- #entitlements_for_entry(file_entry) ⇒ Object
- #executable_codesignature ⇒ Object
- #executable_entitlements ⇒ Object
- #executable_entitlements_data ⇒ Object
- #executable_entries ⇒ Object
- #executable_entry ⇒ Object
- #executable_path ⇒ Object
- #extract(path) ⇒ Object
- #find_appdir ⇒ Object
- #get_entry(path) ⇒ Object
- #info_plist ⇒ Object
-
#initialize(zipfile) ⇒ IPA
constructor
A new instance of IPA.
- #ls ⇒ Object
- #parse_plist_entry(path) ⇒ Object
- #provisioning_profile ⇒ Object
- #read_path(path, *args) ⇒ Object
- #team_identifier ⇒ Object
- #with_executable_macho(&block) ⇒ Object
- #with_extracted_tmpdir(&block) ⇒ Object
- #with_extracted_tmpfile(ent, &block) ⇒ Object
- #with_macho_for_entry(file_entry) ⇒ Object
Constructor Details
#initialize(zipfile) ⇒ IPA
Returns a new instance of IPA.
32 33 34 |
# File 'lib/pliney/ipa.rb', line 32 def initialize(zipfile) @zipfile = zipfile end |
Instance Attribute Details
#zipfile ⇒ Object (readonly)
TODO - creating an ipa from scratch? def self.create(path)
new(Zip::File.open(path, Zip::File::CREATE))
end
30 31 32 |
# File 'lib/pliney/ipa.rb', line 30 def zipfile @zipfile end |
Class Method Details
.from_path(path) ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/pliney/ipa.rb', line 14 def self.from_path(path) ipa = new(Zip::File.open(path)) if block_given? ret = yield(ipa) ipa.close return ret else return ipa end end |
Instance Method Details
#appdir ⇒ Object
36 37 38 |
# File 'lib/pliney/ipa.rb', line 36 def appdir @appdir ||= find_appdir end |
#bundle_identifier ⇒ Object
58 59 60 |
# File 'lib/pliney/ipa.rb', line 58 def bundle_identifier return info_plist["CFBundleIdentifier"] end |
#bundle_short_version ⇒ Object
66 67 68 |
# File 'lib/pliney/ipa.rb', line 66 def bundle_short_version return info_plist["CFBundleShortVersionString"] end |
#bundle_version ⇒ Object
62 63 64 |
# File 'lib/pliney/ipa.rb', line 62 def bundle_version return info_plist["CFBundleVersion"] end |
#canonical_name ⇒ Object
213 214 215 |
# File 'lib/pliney/ipa.rb', line 213 def canonical_name return "#{self.team_identifier}.#{self.bundle_identifier}.v#{self.bundle_short_version}" end |
#close ⇒ Object
82 83 84 |
# File 'lib/pliney/ipa.rb', line 82 def close @zipfile.close end |
#codesignature_for_entry(file_entry) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/pliney/ipa.rb', line 110 def codesignature_for_entry(file_entry) _with_tmpdir do |tmp_path| tmpf = tmp_path.join("executable") file_entry.extract(tmpf.to_s) return ::Pliney::AppleCodeSignature.from_path(tmpf.to_s) end end |
#each_executable_entry ⇒ Object
196 197 198 199 200 201 202 203 204 205 |
# File 'lib/pliney/ipa.rb', line 196 def each_executable_entry each_file_entry do |entry| next if (zipstream = entry.get_input_stream).nil? next if (magicbytes = zipstream.read(4)).nil? next if (magic = magicbytes.unpack("N").first).nil? if ::Pliney::MachO::is_macho_magic(magic) or ::Pliney::MachO::is_fat_magic(magic) yield(entry) end end end |
#each_file_entry ⇒ Object
187 188 189 190 191 192 193 194 |
# File 'lib/pliney/ipa.rb', line 187 def each_file_entry zipfile.entries.select do |ent| not ent.name_is_directory? end.each do |ent| yield(ent) end return nil end |
#entitlements_data_for_entry(file_entry) ⇒ Object
122 123 124 125 126 127 128 129 130 |
# File 'lib/pliney/ipa.rb', line 122 def entitlements_data_for_entry(file_entry) cs = self.codesignature_for_entry(file_entry) if cs ents_blob = cs.contents.find{|c| c.is_a? ::Pliney::AppleCodeSignature::Entitlement} if ents_blob return ents_blob.data end end end |
#entitlements_for_entry(file_entry) ⇒ Object
132 133 134 135 136 137 |
# File 'lib/pliney/ipa.rb', line 132 def entitlements_for_entry(file_entry) dat = entitlements_data_for_entry(file_entry) if dat return ::Pliney.parse_plist(dat) end end |
#executable_codesignature ⇒ Object
118 119 120 |
# File 'lib/pliney/ipa.rb', line 118 def executable_codesignature return codesignature_for_entry(self.executable_entry) end |
#executable_entitlements ⇒ Object
143 144 145 |
# File 'lib/pliney/ipa.rb', line 143 def executable_entitlements return entitlements_for_entry(self.executable_entry) end |
#executable_entitlements_data ⇒ Object
139 140 141 |
# File 'lib/pliney/ipa.rb', line 139 def executable_entitlements_data return entitlements_data_for_entry(self.executable_entry) end |
#executable_entries ⇒ Object
207 208 209 210 211 |
# File 'lib/pliney/ipa.rb', line 207 def executable_entries a = [] each_executable_entry{|e| a << e} return a end |
#executable_entry ⇒ Object
74 75 76 |
# File 'lib/pliney/ipa.rb', line 74 def executable_entry return get_entry(executable_path) end |
#executable_path ⇒ Object
70 71 72 |
# File 'lib/pliney/ipa.rb', line 70 def executable_path return appdir.join(info_plist["CFBundleExecutable"]) end |
#extract(path) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/pliney/ipa.rb', line 154 def extract(path) if SYSTEM_HAS_UNZIP ret = system("unzip", "-qd", path.to_s, self.zipfile.name.to_s) unless ret raise(ZipExtractError, "'unzip' command returned non-zero status: #{$?.inspect}") end else path = Pathname(path) zipfile.each do |ent| extract_path = path.join(ent.name) FileUtils.mkdir_p(extract_path.dirname) ent.extract(extract_path.to_s) extract_path.chmod(ent.unix_perms & 0777) end end return path end |
#find_appdir ⇒ Object
44 45 46 47 48 |
# File 'lib/pliney/ipa.rb', line 44 def find_appdir if e = @zipfile.find{|ent| ent.directory? and ent.name =~ /^Payload\/[^\/]*\.app\/$/ } return Pathname(e.name) end end |
#get_entry(path) ⇒ Object
86 87 88 |
# File 'lib/pliney/ipa.rb', line 86 def get_entry(path) return @zipfile.find_entry(path.to_s) end |
#info_plist ⇒ Object
54 55 56 |
# File 'lib/pliney/ipa.rb', line 54 def info_plist return parse_plist_entry(appdir.join("Info.plist")) end |
#ls ⇒ Object
78 79 80 |
# File 'lib/pliney/ipa.rb', line 78 def ls return @zipfile.entries.map{|e| e.name} end |
#parse_plist_entry(path) ⇒ Object
40 41 42 |
# File 'lib/pliney/ipa.rb', line 40 def parse_plist_entry(path) Pliney.parse_plist(read_path(path)) end |
#provisioning_profile ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/pliney/ipa.rb', line 90 def provisioning_profile begin profile_data = read_path(appdir.join("embedded.mobileprovision")) rescue Errno::ENOENT return nil end ProvisioningProfile.from_asn1(profile_data) end |
#read_path(path, *args) ⇒ Object
50 51 52 |
# File 'lib/pliney/ipa.rb', line 50 def read_path(path, *args) return @zipfile.get_input_stream(path.to_s){|sio| sio.read(*args)} end |
#team_identifier ⇒ Object
147 148 149 150 151 152 |
# File 'lib/pliney/ipa.rb', line 147 def team_identifier entitlements = executable_entitlements() if entitlements return entitlements["com.apple.developer.team-identifier"] end end |
#with_executable_macho(&block) ⇒ Object
106 107 108 |
# File 'lib/pliney/ipa.rb', line 106 def with_executable_macho(&block) with_macho_for_entry(self.executable_entry, &block) end |
#with_extracted_tmpdir(&block) ⇒ Object
172 173 174 |
# File 'lib/pliney/ipa.rb', line 172 def with_extracted_tmpdir(&block) _with_tmpdir {|tmp_path| yield(extract(tmp_path)) } end |
#with_extracted_tmpfile(ent, &block) ⇒ Object
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/pliney/ipa.rb', line 176 def with_extracted_tmpfile(ent, &block) tmpf = Tempfile.new("ent") begin Zip::IOExtras.copy_stream(tmpf, ent.get_input_stream) tmpf.rewind yield(tmpf) ensure tmpf.unlink() end end |