app-info 1.1.2 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/CHANGELOG.md +43 -0
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +62 -11
- data/app_info.gemspec +7 -4
- data/lib/app-info.rb +2 -0
- data/lib/app_info.rb +52 -7
- data/lib/app_info/parser.rb +6 -6
- data/lib/app_info/parser/apk.rb +16 -12
- data/lib/app_info/parser/dsym.rb +119 -0
- data/lib/app_info/parser/ipa.rb +11 -13
- data/lib/app_info/parser/ipa/info_plist.rb +9 -7
- data/lib/app_info/parser/ipa/mobile_provision.rb +27 -7
- data/lib/app_info/version.rb +3 -1
- data/plist.mobileprovision +0 -0
- metadata +40 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f09c53a666307caf08ffdb39369ad9f888cdeff01cbbcf2c4e63eff5f396bfd5
|
4
|
+
data.tar.gz: aff28d8f4b7356f11edd6793a13270f8eac843d3c02c79bf14aaad92218aca9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89ee897a4b5a3efa228ad73632cd01b6977465ffdc48c13900a4c8cbdb254ff413ce6a27ae96563661d5d9809a1adbdeed7b641254764bd288c875f17de1c7d
|
7
|
+
data.tar.gz: 939cbe074276c8e708fdfbe3db8cf02bb42933041cf77e2e1b40850e8f77aad6eca5d211d26ff635cde276a9cc6874d945444188922be2589e90d6aff6308e0a
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
> List all changes before release a new version.
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Added .dSYM.zip format support
|
15
|
+
- Added parse mobileprovision in Linux
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Parse macho-o header to detect file type instead of file extension name. (Maby be not fully support)
|
20
|
+
- Dropped Ruby 2.2 and below versions support
|
21
|
+
|
22
|
+
## [1.1.2] (2019-09-19)
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
|
26
|
+
- Fixed fetch key from ipa.info by Hash way. (thanks @[MobilEKG](https://github.com/MobilEKG))
|
27
|
+
|
28
|
+
## [1.1.0] (2019-06-17)
|
29
|
+
|
30
|
+
### Added
|
31
|
+
|
32
|
+
- Added more methods to Android parser.
|
33
|
+
|
34
|
+
## [1.0.5] (2019-03-30)
|
35
|
+
|
36
|
+
### Changed
|
37
|
+
|
38
|
+
- Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
|
39
|
+
|
40
|
+
[Unreleased]: https://github.com/icyleaf/app-info/compare/v1.1.0..HEAD
|
41
|
+
[1.1.0]: https://github.com/icyleaf/app-info/compare/v1.0.5...v1.1.0
|
42
|
+
[1.0.5]: https://github.com/icyleaf/app-info/compare/v0.9.0...v1.0.5
|
43
|
+
|
data/{LICENSE.txt → LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# app_info
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/icyleaf/app_info)
|
4
|
+
[](https://rubygems.org/gems/app_info)
|
5
|
+
[](LICENSE)
|
6
|
+
|
7
|
+
Teardown tool for mobile app(ipa/apk) and dSYM.zip file, analysis metedata like version, name, icon etc.
|
4
8
|
|
5
9
|
## Support
|
6
10
|
|
@@ -8,13 +12,14 @@ Teardown tool for mobile app(ipa/apk), analysis metedata like version, name, ico
|
|
8
12
|
- iOS ipa file
|
9
13
|
- Info.plist file
|
10
14
|
- .mobileprovision file
|
15
|
+
- dSYM(.zip) file
|
11
16
|
|
12
17
|
## Installation
|
13
18
|
|
14
19
|
Add this line to your application's Gemfile:
|
15
20
|
|
16
21
|
```ruby
|
17
|
-
gem '
|
22
|
+
gem 'app-info'
|
18
23
|
```
|
19
24
|
|
20
25
|
And then execute:
|
@@ -26,7 +31,7 @@ $ bundle
|
|
26
31
|
Or install it yourself as:
|
27
32
|
|
28
33
|
```bash
|
29
|
-
$ gem install
|
34
|
+
$ gem install app-info
|
30
35
|
```
|
31
36
|
|
32
37
|
## Usage
|
@@ -34,14 +39,22 @@ $ gem install app_info
|
|
34
39
|
### Initialize
|
35
40
|
|
36
41
|
```ruby
|
37
|
-
require '
|
42
|
+
require 'app-info'
|
38
43
|
|
39
44
|
# Automatic detect file extsion and parse
|
40
45
|
parser = AppInfo.parse('iphone.ipa')
|
41
46
|
parser = AppInfo.parse('ipad.ipa')
|
42
|
-
parser = AppInfo.parse('android.
|
47
|
+
parser = AppInfo.parse('android.apk')
|
43
48
|
parser = AppInfo.parse('App/Info.plist')
|
44
49
|
parser = AppInfo.parse('provisioning_profile/uuid.mobileprovision')
|
50
|
+
parser = AppInfo.parse('App.dSYm.zip')
|
51
|
+
|
52
|
+
# If detect file type failed, you can parse in other way
|
53
|
+
parser = AppInfo::Parser::IPA.new('iphone.ipa')
|
54
|
+
parser = AppInfo::Parser::IPA.new('android.apk')
|
55
|
+
parser = AppInfo::Parser::InfoPlist.new('App/Info.plist')
|
56
|
+
parser = AppInfo::Parser::MobileProvision.new('provisioning_profile/uuid.mobileprovision')
|
57
|
+
parser = AppInfo::Parser::DSYM.new('App.dSYm.zip')
|
45
58
|
```
|
46
59
|
|
47
60
|
### iOS
|
@@ -112,17 +125,57 @@ profile.devices
|
|
112
125
|
# => ['18cf53cddee60c5af9c97b1521e7cbf8342628da']
|
113
126
|
```
|
114
127
|
|
128
|
+
### dSYM
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
dsym = AppInfo.parse('ios.dSYM.zip')
|
132
|
+
|
133
|
+
# get object name
|
134
|
+
dsym.object
|
135
|
+
# => iOS
|
136
|
+
|
137
|
+
# get macho size
|
138
|
+
dsym.machos.size
|
139
|
+
# => 1 or 2
|
140
|
+
|
141
|
+
dsym.machos.each do |macho|
|
142
|
+
# get cpu type
|
143
|
+
macho.cpu_type
|
144
|
+
# => :arm
|
145
|
+
|
146
|
+
# get cpu name
|
147
|
+
macho.cpu_name
|
148
|
+
# => armv7
|
149
|
+
|
150
|
+
# get UUID (debug id)
|
151
|
+
macho.uuid
|
152
|
+
# => 26dfc15d-bdce-351f-b5de-6ee9f5dd6d85
|
153
|
+
|
154
|
+
# get macho size
|
155
|
+
macho.size
|
156
|
+
# => 866526
|
157
|
+
|
158
|
+
# get macho size in human reable.
|
159
|
+
macho.size(true)
|
160
|
+
# => 862 KB
|
161
|
+
|
162
|
+
# dump data to Hash
|
163
|
+
macho.to_h
|
164
|
+
# => {uuid:"26dfc15d-bdce-351f-b5de-6ee9f5dd6d85", cpu_type: :arm, cpu_name: :armv7, ...}
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
115
168
|
### Android
|
116
169
|
|
117
170
|
```ruby
|
118
171
|
apk = AppInfo.parse('android.apk')
|
119
172
|
|
120
173
|
# get app file size
|
121
|
-
|
174
|
+
apk.size
|
122
175
|
# => 3093823
|
123
176
|
|
124
177
|
# get app file size in human reable.
|
125
|
-
|
178
|
+
apk.size(true)
|
126
179
|
# => 29 MB
|
127
180
|
|
128
181
|
# get app release version
|
@@ -162,8 +215,8 @@ apk.signs
|
|
162
215
|
# => [...]
|
163
216
|
|
164
217
|
# detect app type (It's difficult to detect phone or tablet)
|
165
|
-
|
166
|
-
|
218
|
+
apk.tv?
|
219
|
+
apk.wear?
|
167
220
|
```
|
168
221
|
|
169
222
|
## Development
|
@@ -176,8 +229,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
176
229
|
|
177
230
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/app-info. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
178
231
|
|
179
|
-
|
180
232
|
## License
|
181
233
|
|
182
234
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
183
|
-
|
data/app_info.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'app_info/version'
|
@@ -9,18 +10,20 @@ Gem::Specification.new do |spec|
|
|
9
10
|
spec.authors = ['icyleaf']
|
10
11
|
spec.email = ['icyleaf.cn@gmail.com']
|
11
12
|
|
12
|
-
spec.summary = 'Teardown tool for mobile app(ipa/apk), analysis metedata like version, name, icon'
|
13
|
-
spec.description = 'Teardown tool for ipa/apk files, even support for info.plist and .mobileprovision files'
|
13
|
+
spec.summary = 'Teardown tool for mobile app(ipa/apk) and dSYM file, analysis metedata like version, name, icon'
|
14
|
+
spec.description = 'Teardown tool for ipa/apk files and dSYM file, even support for info.plist and .mobileprovision files'
|
14
15
|
spec.homepage = 'http://github.com/icyleaf/app-info'
|
15
16
|
spec.license = 'MIT'
|
16
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
19
|
spec.require_paths = ['lib']
|
20
|
+
spec.required_ruby_version = '>= 2.3'
|
19
21
|
|
20
22
|
spec.add_dependency 'CFPropertyList', ['< 3.1.0', '>= 2.3.4']
|
23
|
+
spec.add_dependency 'image_size', '>= 1.5', '< 2.1'
|
21
24
|
spec.add_dependency 'pngdefry', '~> 0.1.2'
|
25
|
+
spec.add_dependency 'ruby-macho', '~> 2.2.0'
|
22
26
|
spec.add_dependency 'ruby_android', '~> 0.7.7'
|
23
|
-
spec.add_dependency 'image_size', '~> 1.5.0'
|
24
27
|
|
25
28
|
spec.add_development_dependency 'bundler', '>= 1.12'
|
26
29
|
spec.add_development_dependency 'rake', '>= 10.0'
|
data/lib/app-info.rb
CHANGED
data/lib/app_info.rb
CHANGED
@@ -1,24 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'app_info/version'
|
2
4
|
require 'app_info/parser'
|
3
5
|
|
4
6
|
#
|
5
7
|
# AppInfo Module
|
6
8
|
module AppInfo
|
7
|
-
|
9
|
+
class NotFoundError < StandardError; end
|
10
|
+
class NotAppError < StandardError; end
|
11
|
+
|
8
12
|
# Get a new parser for automatic
|
9
13
|
def self.parse(file)
|
10
14
|
raise NotFoundError, file unless File.exist?(file)
|
11
15
|
|
12
|
-
case
|
13
|
-
when
|
14
|
-
when
|
15
|
-
when
|
16
|
+
case detect_file_type(file)
|
17
|
+
when :ipa then Parser::IPA.new(file)
|
18
|
+
when :apk then Parser::APK.new(file)
|
19
|
+
when :mobileprovision then Parser::MobileProvision.new(file)
|
20
|
+
when :dsym then Parser::DSYM.new(file)
|
16
21
|
else
|
17
22
|
raise NotAppError, file
|
18
23
|
end
|
19
24
|
end
|
20
25
|
singleton_class.send(:alias_method, :dump, :parse)
|
21
26
|
|
22
|
-
|
23
|
-
|
27
|
+
|
28
|
+
# Detect file type by read file header
|
29
|
+
#
|
30
|
+
# TODO: This can be better way to solvt, if anyone knows, tell me please.
|
31
|
+
def self.detect_file_type(file)
|
32
|
+
header_hex = IO.read(file, 100)
|
33
|
+
type = if header_hex =~ /^\x50\x4b\x03\x04/
|
34
|
+
detect_zip_format(header_hex)
|
35
|
+
else
|
36
|
+
detect_mobileprovision(header_hex)
|
37
|
+
end
|
38
|
+
|
39
|
+
type || :unkown
|
40
|
+
end
|
41
|
+
|
42
|
+
# :nodoc:
|
43
|
+
def self.detect_zip_format(hex)
|
44
|
+
if hex =~ /\x63\x6C\x61\x73\x73\x65/ ||
|
45
|
+
hex =~ /\x41\x6E\x64\x72\x6F\x69\x64\x4D\x61\x6E\x69\x66\x65\x73\x74/ ||
|
46
|
+
hex =~ /\x4D\x45\x54\x41\x2D\x49\x4E\x46/
|
47
|
+
:apk
|
48
|
+
elsif hex.slice(13, 1) == "\x48" ||
|
49
|
+
hex =~ /\x50\x61\x79\x6C\x6F\x61\x64/
|
50
|
+
:ipa
|
51
|
+
elsif hex.slice(12, 2) == "\x30\x4f"
|
52
|
+
:dsym
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# :nodoc:
|
57
|
+
def self.detect_mobileprovision(hex)
|
58
|
+
if hex =~ /^\x3C\x3F\x78\x6D\x6C/
|
59
|
+
# plist
|
60
|
+
:mobileprovision
|
61
|
+
elsif hex =~ /^\x62\x70\x6C\x69\x73\x74/
|
62
|
+
# bplist
|
63
|
+
:mobileprovision
|
64
|
+
elsif hex =~ /\x3C\x3F\x78\x6D\x6C/
|
65
|
+
# signed plist
|
66
|
+
:mobileprovision
|
67
|
+
end
|
68
|
+
end
|
24
69
|
end
|
data/lib/app_info/parser.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'app_info/parser/ipa'
|
2
4
|
require 'app_info/parser/ipa/info_plist'
|
3
5
|
require 'app_info/parser/ipa/mobile_provision'
|
4
6
|
require 'app_info/parser/apk'
|
7
|
+
require 'app_info/parser/dsym'
|
5
8
|
|
6
9
|
module AppInfo
|
7
10
|
module Parser
|
8
11
|
# App Platform
|
9
12
|
module Platform
|
10
|
-
IOS = 'iOS'
|
11
|
-
ANDROID = 'Android'
|
12
|
-
|
13
|
-
|
14
|
-
def self.mac?
|
15
|
-
RbConfig::CONFIG['host_os'] =~ /darwin/ ? true : false
|
13
|
+
IOS = 'iOS'
|
14
|
+
ANDROID = 'Android'
|
15
|
+
DSYM = 'dSYM'
|
16
16
|
end
|
17
17
|
|
18
18
|
module Util
|
data/lib/app_info/parser/apk.rb
CHANGED
@@ -29,6 +29,7 @@ module AppInfo
|
|
29
29
|
def os
|
30
30
|
Parser::Platform::ANDROID
|
31
31
|
end
|
32
|
+
alias file_type os
|
32
33
|
|
33
34
|
def build_version
|
34
35
|
manifest.version_code.to_s
|
@@ -45,6 +46,8 @@ module AppInfo
|
|
45
46
|
def bundle_id
|
46
47
|
manifest.package_name
|
47
48
|
end
|
49
|
+
alias identifier bundle_id
|
50
|
+
alias package_name bundle_id
|
48
51
|
|
49
52
|
def device_type
|
50
53
|
if wear?
|
@@ -74,7 +77,10 @@ module AppInfo
|
|
74
77
|
end
|
75
78
|
|
76
79
|
def target_sdk_version
|
77
|
-
manifest.doc
|
80
|
+
manifest.doc
|
81
|
+
.elements['/manifest/uses-sdk']
|
82
|
+
.attributes['targetSdkVersion']
|
83
|
+
.to_i
|
78
84
|
end
|
79
85
|
|
80
86
|
def use_permissions
|
@@ -98,11 +104,11 @@ module AppInfo
|
|
98
104
|
end
|
99
105
|
|
100
106
|
def activities
|
101
|
-
components.select {|c| c.type == 'activity' }
|
107
|
+
components.select { |c| c.type == 'activity' }
|
102
108
|
end
|
103
109
|
|
104
110
|
def services
|
105
|
-
components.select {|c| c.type == 'service' }
|
111
|
+
components.select { |c| c.type == 'service' }
|
106
112
|
end
|
107
113
|
|
108
114
|
def components
|
@@ -145,10 +151,6 @@ module AppInfo
|
|
145
151
|
@icons
|
146
152
|
end
|
147
153
|
|
148
|
-
alias identifier bundle_id
|
149
|
-
alias package_name bundle_id
|
150
|
-
alias device_type os
|
151
|
-
|
152
154
|
private
|
153
155
|
|
154
156
|
def manifest_values(path, key = 'name')
|
@@ -159,21 +161,23 @@ module AppInfo
|
|
159
161
|
values.uniq
|
160
162
|
end
|
161
163
|
|
164
|
+
# Android Certificate
|
162
165
|
class Certificate
|
163
166
|
attr_reader :path, :certificate
|
164
167
|
def initialize(path, certificate)
|
165
168
|
@path = path
|
166
169
|
@certificate = certificate
|
167
170
|
end
|
168
|
-
end
|
171
|
+
end
|
169
172
|
|
173
|
+
# Android Sign
|
170
174
|
class Sign
|
171
175
|
attr_reader :path, :sign
|
172
176
|
def initialize(path, sign)
|
173
177
|
@path = path
|
174
178
|
@sign = sign
|
175
179
|
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'macho'
|
2
|
+
require 'app_info/core_ext/object/try'
|
3
|
+
|
4
|
+
module AppInfo
|
5
|
+
module Parser
|
6
|
+
# DSYM parser
|
7
|
+
class DSYM
|
8
|
+
attr_reader :file
|
9
|
+
|
10
|
+
def initialize(file)
|
11
|
+
@file = file
|
12
|
+
end
|
13
|
+
|
14
|
+
def file_type
|
15
|
+
Parser::Platform::DSYM
|
16
|
+
end
|
17
|
+
|
18
|
+
def machos
|
19
|
+
@machos ||= case macho
|
20
|
+
when ::MachO::MachOFile
|
21
|
+
[MachO.new(macho, File.size(app_path))]
|
22
|
+
else
|
23
|
+
size = macho.fat_archs.each_with_object([]) do |arch, obj|
|
24
|
+
obj << arch.size
|
25
|
+
end
|
26
|
+
|
27
|
+
machos = []
|
28
|
+
macho.machos.each_with_index do |file, i|
|
29
|
+
machos << MachO.new(file, size[i])
|
30
|
+
end
|
31
|
+
machos
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def macho
|
36
|
+
@macho ||= ::MachO.open(app_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def object
|
40
|
+
@object ||= File.basename(app_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def app_path
|
44
|
+
@app_path ||= Dir.glob(File.join(contents, 'Contents', 'Resources', 'DWARF', '*')).first
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def contents
|
50
|
+
unless @contents
|
51
|
+
if File.directory?(@file)
|
52
|
+
@contents = @file
|
53
|
+
else
|
54
|
+
@contents = "#{Dir.mktmpdir}/AppInfo-dsym-#{SecureRandom.hex}"
|
55
|
+
dsym_dir = nil
|
56
|
+
Zip::File.open(@file) do |zip_file|
|
57
|
+
zip_file.each do |f|
|
58
|
+
dsym_dir ||= f.name
|
59
|
+
f_path = File.join(@contents, f.name)
|
60
|
+
FileUtils.mkdir_p(File.dirname(f_path))
|
61
|
+
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
@contents = File.join(@contents, dsym_dir)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@contents
|
70
|
+
end
|
71
|
+
|
72
|
+
# DSYM Mach-O
|
73
|
+
class MachO
|
74
|
+
def initialize(file, size = 0)
|
75
|
+
@file = file
|
76
|
+
@size = size
|
77
|
+
end
|
78
|
+
|
79
|
+
def cpu_name
|
80
|
+
@file.cpusubtype
|
81
|
+
end
|
82
|
+
|
83
|
+
def cpu_type
|
84
|
+
@file.cputype
|
85
|
+
end
|
86
|
+
|
87
|
+
def type
|
88
|
+
@file.filetype
|
89
|
+
end
|
90
|
+
|
91
|
+
def size(humanable = false)
|
92
|
+
return Util.size_to_humanable(@size) if humanable
|
93
|
+
|
94
|
+
@size
|
95
|
+
end
|
96
|
+
|
97
|
+
def uuid
|
98
|
+
@file[:LC_UUID][0].uuid_string
|
99
|
+
end
|
100
|
+
alias debug_id uuid
|
101
|
+
|
102
|
+
def header
|
103
|
+
@header ||= @file.header
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_h
|
107
|
+
{
|
108
|
+
uuid: uuid,
|
109
|
+
type: type,
|
110
|
+
cpu_name: cpu_name,
|
111
|
+
cpu_type: cpu_type,
|
112
|
+
size: size,
|
113
|
+
humanable_size: size(true)
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/app_info/parser/ipa.rb
CHANGED
@@ -8,7 +8,7 @@ module AppInfo
|
|
8
8
|
module Parser
|
9
9
|
# IPA parser
|
10
10
|
class IPA
|
11
|
-
attr_reader :file
|
11
|
+
attr_reader :file
|
12
12
|
|
13
13
|
# iOS Export types
|
14
14
|
module ExportType
|
@@ -21,7 +21,6 @@ module AppInfo
|
|
21
21
|
|
22
22
|
def initialize(file)
|
23
23
|
@file = file
|
24
|
-
@app_path = app_path
|
25
24
|
end
|
26
25
|
|
27
26
|
def size(humanable = false)
|
@@ -31,6 +30,7 @@ module AppInfo
|
|
31
30
|
def os
|
32
31
|
Parser::Platform::IOS
|
33
32
|
end
|
33
|
+
alias file_type os
|
34
34
|
|
35
35
|
def iphone?
|
36
36
|
info.iphone?
|
@@ -116,8 +116,6 @@ module AppInfo
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def build_type
|
119
|
-
return ExportType::UNKOWN unless AppInfo::Parser.mac?
|
120
|
-
|
121
119
|
if mobileprovision?
|
122
120
|
if devices
|
123
121
|
ExportType::ADHOC
|
@@ -141,9 +139,7 @@ module AppInfo
|
|
141
139
|
return unless mobileprovision?
|
142
140
|
return @mobileprovision if @mobileprovision
|
143
141
|
|
144
|
-
|
145
|
-
|
146
|
-
@mobileprovision = MobileProvision.new(file)
|
142
|
+
@mobileprovision = MobileProvision.new(mobileprovision_path)
|
147
143
|
end
|
148
144
|
|
149
145
|
def mobileprovision?
|
@@ -153,7 +149,7 @@ module AppInfo
|
|
153
149
|
def mobileprovision_path
|
154
150
|
filename = 'embedded.mobileprovision'
|
155
151
|
@mobileprovision_path ||= File.join(@file, filename)
|
156
|
-
unless File.exist
|
152
|
+
unless File.exist?(@mobileprovision_path)
|
157
153
|
@mobileprovision_path = File.join(app_path, filename)
|
158
154
|
end
|
159
155
|
|
@@ -162,6 +158,7 @@ module AppInfo
|
|
162
158
|
|
163
159
|
def metadata
|
164
160
|
return unless metadata?
|
161
|
+
|
165
162
|
@metadata ||= CFPropertyList.native_types(CFPropertyList::List.new(file: metadata_path).value)
|
166
163
|
end
|
167
164
|
|
@@ -170,11 +167,11 @@ module AppInfo
|
|
170
167
|
end
|
171
168
|
|
172
169
|
def metadata_path
|
173
|
-
@metadata_path ||= File.join(
|
170
|
+
@metadata_path ||= File.join(contents, 'iTunesMetadata.plist')
|
174
171
|
end
|
175
172
|
|
176
173
|
def info
|
177
|
-
@info ||= InfoPlist.new(
|
174
|
+
@info ||= InfoPlist.new(app_path)
|
178
175
|
end
|
179
176
|
|
180
177
|
def app_path
|
@@ -183,6 +180,7 @@ module AppInfo
|
|
183
180
|
|
184
181
|
def cleanup!
|
185
182
|
return unless @contents
|
183
|
+
|
186
184
|
FileUtils.rm_rf(@contents)
|
187
185
|
|
188
186
|
@contents = nil
|
@@ -226,6 +224,6 @@ module AppInfo
|
|
226
224
|
[iphone, ipad]
|
227
225
|
end
|
228
226
|
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cfpropertylist'
|
2
4
|
|
3
5
|
module AppInfo
|
@@ -49,7 +51,7 @@ module AppInfo
|
|
49
51
|
.try(:[], 'CFBundlePrimaryIcon')
|
50
52
|
.try(:[], 'CFBundleIconFiles')
|
51
53
|
|
52
|
-
next if icon_array.nil? || icon_array.
|
54
|
+
next if icon_array.nil? || icon_array.zero?
|
53
55
|
|
54
56
|
icon_array.each do |items|
|
55
57
|
Dir.glob(File.join(@app_path, "#{items}*")).find_all.each do |file|
|
@@ -115,17 +117,17 @@ module AppInfo
|
|
115
117
|
File.join(@app_path, 'Info.plist')
|
116
118
|
end
|
117
119
|
|
118
|
-
|
119
|
-
|
120
|
-
ipad = 'CFBundleIcons~ipad'.freeze
|
120
|
+
IPHONE_KEY = 'CFBundleIcons'
|
121
|
+
IPAD_KEY = 'CFBundleIcons~ipad'
|
121
122
|
|
123
|
+
def icons_root_path
|
122
124
|
case device_type
|
123
125
|
when 'iPhone'
|
124
|
-
[
|
126
|
+
[IPHONE_KEY]
|
125
127
|
when 'iPad'
|
126
|
-
[
|
128
|
+
[IPAD_KEY]
|
127
129
|
when 'Universal'
|
128
|
-
[
|
130
|
+
[IPHONE_KEY, IPAD_KEY]
|
129
131
|
end
|
130
132
|
end
|
131
133
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cfpropertylist'
|
2
4
|
|
3
5
|
module AppInfo
|
@@ -46,10 +48,13 @@ module AppInfo
|
|
46
48
|
|
47
49
|
def method_missing(method_name, *args, &block)
|
48
50
|
key = if method_name.to_s.include?('_')
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
method_name.to_s
|
52
|
+
.split('_')
|
53
|
+
.map(&:capitalize)
|
54
|
+
.join('')
|
55
|
+
else
|
56
|
+
method_name.to_s
|
57
|
+
end
|
53
58
|
|
54
59
|
mobileprovision.try(:[], key)
|
55
60
|
end
|
@@ -59,13 +64,28 @@ module AppInfo
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def mobileprovision
|
62
|
-
return @mobileprovision = nil
|
67
|
+
return @mobileprovision = nil unless File.exist?(@path)
|
63
68
|
|
64
|
-
data =
|
65
|
-
|
69
|
+
data = File.read(@path)
|
70
|
+
data = strip_plist_wrapper(data) unless bplist?(data)
|
71
|
+
list = CFPropertyList::List.new(data: data).value
|
72
|
+
@mobileprovision = CFPropertyList.native_types(list)
|
66
73
|
rescue CFFormatError
|
67
74
|
@mobileprovision = nil
|
68
75
|
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def bplist?(raw)
|
80
|
+
raw[0..5] == 'bplist'
|
81
|
+
end
|
82
|
+
|
83
|
+
def strip_plist_wrapper(raw)
|
84
|
+
end_tag = '</plist>'
|
85
|
+
start_point = raw.index('<?xml version=')
|
86
|
+
end_point = raw.index(end_tag) + end_tag.size - 1
|
87
|
+
raw[start_point..end_point]
|
88
|
+
end
|
69
89
|
end
|
70
90
|
end
|
71
91
|
end
|
data/lib/app_info/version.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: app-info
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- icyleaf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: CFPropertyList
|
@@ -30,6 +30,26 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 3.1.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: image_size
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.5'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '2.1'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.5'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '2.1'
|
33
53
|
- !ruby/object:Gem::Dependency
|
34
54
|
name: pngdefry
|
35
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,33 +65,33 @@ dependencies:
|
|
45
65
|
- !ruby/object:Gem::Version
|
46
66
|
version: 0.1.2
|
47
67
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
68
|
+
name: ruby-macho
|
49
69
|
requirement: !ruby/object:Gem::Requirement
|
50
70
|
requirements:
|
51
71
|
- - "~>"
|
52
72
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
73
|
+
version: 2.2.0
|
54
74
|
type: :runtime
|
55
75
|
prerelease: false
|
56
76
|
version_requirements: !ruby/object:Gem::Requirement
|
57
77
|
requirements:
|
58
78
|
- - "~>"
|
59
79
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
80
|
+
version: 2.2.0
|
61
81
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
82
|
+
name: ruby_android
|
63
83
|
requirement: !ruby/object:Gem::Requirement
|
64
84
|
requirements:
|
65
85
|
- - "~>"
|
66
86
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
87
|
+
version: 0.7.7
|
68
88
|
type: :runtime
|
69
89
|
prerelease: false
|
70
90
|
version_requirements: !ruby/object:Gem::Requirement
|
71
91
|
requirements:
|
72
92
|
- - "~>"
|
73
93
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
94
|
+
version: 0.7.7
|
75
95
|
- !ruby/object:Gem::Dependency
|
76
96
|
name: bundler
|
77
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,8 +134,8 @@ dependencies:
|
|
114
134
|
- - "~>"
|
115
135
|
- !ruby/object:Gem::Version
|
116
136
|
version: '3.0'
|
117
|
-
description: Teardown tool for ipa/apk files, even support for info.plist
|
118
|
-
files
|
137
|
+
description: Teardown tool for ipa/apk files and dSYM file, even support for info.plist
|
138
|
+
and .mobileprovision files
|
119
139
|
email:
|
120
140
|
- icyleaf.cn@gmail.com
|
121
141
|
executables: []
|
@@ -125,9 +145,10 @@ files:
|
|
125
145
|
- ".gitignore"
|
126
146
|
- ".rspec"
|
127
147
|
- ".travis.yml"
|
148
|
+
- CHANGELOG.md
|
128
149
|
- CODE_OF_CONDUCT.md
|
129
150
|
- Gemfile
|
130
|
-
- LICENSE
|
151
|
+
- LICENSE
|
131
152
|
- README.md
|
132
153
|
- Rakefile
|
133
154
|
- app_info.gemspec
|
@@ -136,10 +157,12 @@ files:
|
|
136
157
|
- lib/app_info/core_ext/object/try.rb
|
137
158
|
- lib/app_info/parser.rb
|
138
159
|
- lib/app_info/parser/apk.rb
|
160
|
+
- lib/app_info/parser/dsym.rb
|
139
161
|
- lib/app_info/parser/ipa.rb
|
140
162
|
- lib/app_info/parser/ipa/info_plist.rb
|
141
163
|
- lib/app_info/parser/ipa/mobile_provision.rb
|
142
164
|
- lib/app_info/version.rb
|
165
|
+
- plist.mobileprovision
|
143
166
|
homepage: http://github.com/icyleaf/app-info
|
144
167
|
licenses:
|
145
168
|
- MIT
|
@@ -152,16 +175,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
175
|
requirements:
|
153
176
|
- - ">="
|
154
177
|
- !ruby/object:Gem::Version
|
155
|
-
version: '
|
178
|
+
version: '2.3'
|
156
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
180
|
requirements:
|
158
|
-
- - "
|
181
|
+
- - ">"
|
159
182
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
183
|
+
version: 1.3.1
|
161
184
|
requirements: []
|
162
|
-
rubygems_version: 3.0.
|
185
|
+
rubygems_version: 3.0.6
|
163
186
|
signing_key:
|
164
187
|
specification_version: 4
|
165
|
-
summary: Teardown tool for mobile app(ipa/apk), analysis metedata like
|
166
|
-
icon
|
188
|
+
summary: Teardown tool for mobile app(ipa/apk) and dSYM file, analysis metedata like
|
189
|
+
version, name, icon
|
167
190
|
test_files: []
|