app-info 2.5.1 → 2.6.0

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.
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'uuidtools'
4
4
  require 'rexml/document'
5
- require 'app_info/util'
6
5
 
7
6
  module AppInfo
8
7
  # Proguard parser
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'irb'
4
+
5
+ module AppInfo
6
+ class Shell
7
+ PREFIX = "app-info (#{AppInfo::VERSION})"
8
+
9
+ PROMPT = {
10
+ PROMPT_I: "#{PREFIX}> ",
11
+ PROMPT_S: "#{PREFIX}> ",
12
+ PROMPT_C: "#{PREFIX}> ",
13
+ PROMPT_N: "#{PREFIX}> ",
14
+ RETURN: "=> %s\n"
15
+ }.freeze
16
+
17
+ class << self
18
+ def run
19
+ setup
20
+
21
+ irb = IRB::Irb.new
22
+ irb.run
23
+ end
24
+
25
+ def setup
26
+ IRB.setup nil
27
+
28
+ IRB.conf[:PROMPT][:APPINFO] = PROMPT
29
+ IRB.conf[:PROMPT_MODE] = :APPINFO
30
+ IRB.conf[:AUTO_INDENT] = true
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/app_info/util.rb CHANGED
@@ -5,23 +5,54 @@ require 'fileutils'
5
5
  require 'securerandom'
6
6
 
7
7
  module AppInfo
8
+ class Error < StandardError; end
9
+
10
+ class NotFoundError < Error; end
11
+
12
+ class UnkownFileTypeError < Error; end
13
+
14
+ # App Platform
15
+ module Platform
16
+ MACOS = 'macOS'
17
+ IOS = 'iOS'
18
+ ANDROID = 'Android'
19
+ DSYM = 'dSYM'
20
+ PROGUARD = 'Proguard'
21
+ end
22
+
23
+ # Device Type
24
+ module Device
25
+ MACOS = 'macOS'
26
+ IPHONE = 'iPhone'
27
+ IPAD = 'iPad'
28
+ UNIVERSAL = 'Universal'
29
+ end
30
+
31
+ # Icon Key
32
+ ICON_KEYS = {
33
+ AppInfo::Device::IPHONE => ['CFBundleIcons'],
34
+ AppInfo::Device::IPAD => ['CFBundleIcons~ipad'],
35
+ AppInfo::Device::UNIVERSAL => ['CFBundleIcons', 'CFBundleIcons~ipad'],
36
+ AppInfo::Device::MACOS => %w[CFBundleIconFile CFBundleIconName]
37
+ }.freeze
38
+
39
+ FILE_SIZE_UNITS = %w[B KB MB GB TB].freeze
40
+
8
41
  # AppInfo Util
9
42
  module Util
10
- FILE_SIZE_UNITS = %w[B KB MB GB TB].freeze
11
-
12
43
  def self.format_key(key)
13
44
  key = key.to_s
14
45
  return key unless key.include?('_')
15
46
 
16
- key.split('_').map(&:capitalize).join('')
47
+ key.split('_').map(&:capitalize).join
17
48
  end
18
49
 
19
- def self.file_size(file, humanable)
50
+ def self.file_size(file, human_size)
20
51
  file_size = File.size(file)
21
- humanable ? size_to_humanable(file_size) : file_size
52
+ human_size ? size_to_human_size(file_size) : file_size
22
53
  end
23
54
 
24
- def self.size_to_humanable(number)
55
+ def self.size_to_human_size(number)
25
56
  if number.to_i < 1024
26
57
  exponent = 0
27
58
  else
@@ -54,5 +85,14 @@ module AppInfo
54
85
 
55
86
  root_path
56
87
  end
88
+
89
+ def self.tempdir(file, prefix:)
90
+ dest_path ||= File.join(File.dirname(file), prefix)
91
+ dest_file = File.join(dest_path, File.basename(file))
92
+
93
+ Dir.mkdir(dest_path, 0_700) unless Dir.exist?(dest_path)
94
+
95
+ dest_file
96
+ end
57
97
  end
58
98
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppInfo
4
- VERSION = '2.5.1'
4
+ VERSION = '2.6.0'
5
5
  end
data/lib/app_info.rb CHANGED
@@ -1,30 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'app_info/util'
3
4
  require 'app_info/core_ext/object/try'
4
5
  require 'app_info/version'
6
+ require 'app_info/info_plist'
7
+ require 'app_info/mobile_provision'
5
8
  require 'app_info/ipa'
6
- require 'app_info/ipa/info_plist'
7
- require 'app_info/ipa/mobile_provision'
8
9
  require 'app_info/ipa/plugin'
9
10
  require 'app_info/ipa/framework'
10
11
  require 'app_info/apk'
11
- require 'app_info/dsym'
12
12
  require 'app_info/proguard'
13
+ require 'app_info/dsym'
14
+ require 'app_info/macos'
15
+
16
+ # fix invaild date format warnings
17
+ Zip.warn_invalid_date = false
13
18
 
14
19
  # AppInfo Module
15
20
  module AppInfo
16
- class Error < StandardError; end
17
- class NotFoundError < Error; end
18
- class UnkownFileTypeError < Error; end
19
-
20
- # App Platform
21
- module Platform
22
- IOS = 'iOS'
23
- ANDROID = 'Android'
24
- DSYM = 'dSYM'
25
- PROGUARD = 'Proguard'
26
- end
27
-
28
21
  # Get a new parser for automatic
29
22
  def self.parse(file)
30
23
  raise NotFoundError, file unless File.exist?(file)
@@ -35,6 +28,7 @@ module AppInfo
35
28
  when :mobileprovision then MobileProvision.new(file)
36
29
  when :dsym then DSYM.new(file)
37
30
  when :proguard then Proguard.new(file)
31
+ when :macos then Macos.new(file)
38
32
  else
39
33
  raise UnkownFileTypeError, "Sorry, AppInfo can not detect file type: #{file}"
40
34
  end
@@ -61,8 +55,11 @@ module AppInfo
61
55
  zip_file = Zip::File.open(file)
62
56
 
63
57
  return :proguard unless zip_file.glob('*mapping*.txt').empty?
64
- return :apk unless zip_file.find_entry('AndroidManifest.xml').nil? &&
65
- zip_file.find_entry('classes.dex').nil?
58
+ return :apk if !zip_file.find_entry('AndroidManifest.xml').nil? &&
59
+ !zip_file.find_entry('classes.dex').nil?
60
+
61
+ return :macos if !zip_file.glob('*/Contents/MacOS/*').empty? &&
62
+ !zip_file.glob('*/Contents/Info.plist').empty?
66
63
 
67
64
  zip_file.each do |f|
68
65
  path = f.name
@@ -70,19 +67,18 @@ module AppInfo
70
67
  return :ipa if path.include?('Payload/') && path.end_with?('Info.plist')
71
68
  return :dsym if path.include?('Contents/Resources/DWARF/')
72
69
  end
70
+ ensure
71
+ zip_file.close
73
72
  end
74
73
  private_class_method :detect_zip_file
75
74
 
75
+ PLIST_REGEX = /\x3C\x3F\x78\x6D\x6C/.freeze
76
+ BPLIST_REGEX = /^\x62\x70\x6C\x69\x73\x74/.freeze
77
+
76
78
  # :nodoc:
77
79
  def self.detect_mobileprovision(hex)
78
- if hex =~ /^\x3C\x3F\x78\x6D\x6C/
79
- # plist
80
- :mobileprovision
81
- elsif hex =~ /^\x62\x70\x6C\x69\x73\x74/
82
- # bplist
83
- :mobileprovision
84
- elsif hex =~ /\x3C\x3F\x78\x6D\x6C/
85
- # signed plist
80
+ case hex
81
+ when PLIST_REGEX, BPLIST_REGEX
86
82
  :mobileprovision
87
83
  end
88
84
  end
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: 2.5.1
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - icyleaf
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-14 00:00:00.000000000 Z
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -54,16 +54,22 @@ dependencies:
54
54
  name: ruby-macho
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - "~>"
57
+ - - "<"
58
+ - !ruby/object:Gem::Version
59
+ version: '3'
60
+ - - ">="
58
61
  - !ruby/object:Gem::Version
59
- version: 2.2.0
62
+ version: '1.4'
60
63
  type: :runtime
61
64
  prerelease: false
62
65
  version_requirements: !ruby/object:Gem::Requirement
63
66
  requirements:
64
- - - "~>"
67
+ - - "<"
68
+ - !ruby/object:Gem::Version
69
+ version: '3'
70
+ - - ">="
65
71
  - !ruby/object:Gem::Version
66
- version: 2.2.0
72
+ version: '1.4'
67
73
  - !ruby/object:Gem::Dependency
68
74
  name: ruby_android
69
75
  requirement: !ruby/object:Gem::Requirement
@@ -118,6 +124,20 @@ dependencies:
118
124
  - - "<"
119
125
  - !ruby/object:Gem::Version
120
126
  version: 2.3.0
127
+ - !ruby/object:Gem::Dependency
128
+ name: icns
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - "~>"
132
+ - !ruby/object:Gem::Version
133
+ version: 0.2.0
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - "~>"
139
+ - !ruby/object:Gem::Version
140
+ version: 0.2.0
121
141
  - !ruby/object:Gem::Dependency
122
142
  name: bundler
123
143
  requirement: !ruby/object:Gem::Requirement
@@ -160,18 +180,34 @@ dependencies:
160
180
  - - "~>"
161
181
  - !ruby/object:Gem::Version
162
182
  version: '3.0'
183
+ - !ruby/object:Gem::Dependency
184
+ name: rubocop
185
+ requirement: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: '1.19'
190
+ type: :development
191
+ prerelease: false
192
+ version_requirements: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - "~>"
195
+ - !ruby/object:Gem::Version
196
+ version: '1.19'
163
197
  description: Teardown tool for ipa/apk files and dSYM file, even support for info.plist
164
198
  and .mobileprovision files
165
199
  email:
166
200
  - icyleaf.cn@gmail.com
167
- executables: []
201
+ executables:
202
+ - app-info
168
203
  extensions: []
169
204
  extra_rdoc_files: []
170
205
  files:
206
+ - ".github/dependabot.yml"
207
+ - ".github/workflows/ci.yml"
171
208
  - ".gitignore"
172
209
  - ".rspec"
173
210
  - ".rubocop.yml"
174
- - ".travis.yml"
175
211
  - CHANGELOG.md
176
212
  - CODE_OF_CONDUCT.md
177
213
  - Gemfile
@@ -179,18 +215,21 @@ files:
179
215
  - README.md
180
216
  - Rakefile
181
217
  - app_info.gemspec
218
+ - exe/app-info
182
219
  - lib/app-info.rb
183
220
  - lib/app_info.rb
184
221
  - lib/app_info/apk.rb
185
222
  - lib/app_info/core_ext/object/try.rb
186
223
  - lib/app_info/dsym.rb
224
+ - lib/app_info/info_plist.rb
187
225
  - lib/app_info/ipa.rb
188
226
  - lib/app_info/ipa/framework.rb
189
- - lib/app_info/ipa/info_plist.rb
190
- - lib/app_info/ipa/mobile_provision.rb
191
227
  - lib/app_info/ipa/plugin.rb
228
+ - lib/app_info/macos.rb
229
+ - lib/app_info/mobile_provision.rb
192
230
  - lib/app_info/png_uncrush.rb
193
231
  - lib/app_info/proguard.rb
232
+ - lib/app_info/shell.rb
194
233
  - lib/app_info/util.rb
195
234
  - lib/app_info/version.rb
196
235
  homepage: http://github.com/icyleaf/app-info
@@ -205,7 +244,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
205
244
  requirements:
206
245
  - - ">="
207
246
  - !ruby/object:Gem::Version
208
- version: '2.3'
247
+ version: '2.5'
209
248
  required_rubygems_version: !ruby/object:Gem::Requirement
210
249
  requirements:
211
250
  - - ">="
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3
5
- - 2.4
6
- - 2.5
7
- - 2.6
8
- - 2.7
9
- before_install: gem install bundler
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cfpropertylist'
4
- require 'app_info/png_uncrush'
5
- require 'app_info/util'
6
-
7
- module AppInfo
8
- # iOS Info.plist parser
9
- class InfoPlist
10
- def initialize(app_path)
11
- @app_path = app_path
12
- end
13
-
14
- def build_version
15
- info.try(:[], 'CFBundleVersion')
16
- end
17
-
18
- def release_version
19
- info.try(:[], 'CFBundleShortVersionString')
20
- end
21
-
22
- def identifier
23
- info.try(:[], 'CFBundleIdentifier')
24
- end
25
- alias bundle_id identifier
26
-
27
- def name
28
- display_name || bundle_name
29
- end
30
-
31
- def display_name
32
- info.try(:[], 'CFBundleDisplayName')
33
- end
34
-
35
- def bundle_name
36
- info.try(:[], 'CFBundleName')
37
- end
38
-
39
- #
40
- # Extract the Minimum OS Version from the Info.plist
41
- #
42
- def min_sdk_version
43
- info.try(:[], 'MinimumOSVersion')
44
- end
45
-
46
- def icons(uncrush = true)
47
- return @icons if @icons
48
-
49
- @icons = []
50
- icons_root_path.each do |name|
51
- icon_array = info.try(:[], name)
52
- .try(:[], 'CFBundlePrimaryIcon')
53
- .try(:[], 'CFBundleIconFiles')
54
-
55
- next if icon_array.nil? || icon_array.empty?
56
-
57
- icon_array.each do |items|
58
- Dir.glob(File.join(@app_path, "#{items}*")).find_all.each do |file|
59
- @icons << icon_info(file, uncrush)
60
- end
61
- end
62
- end
63
-
64
- @icons
65
- end
66
-
67
- def device_type
68
- device_family = info.try(:[], 'UIDeviceFamily')
69
- if device_family.length == 1
70
- case device_family
71
- when [1]
72
- 'iPhone'
73
- when [2]
74
- 'iPad'
75
- end
76
- elsif device_family.length == 2 && device_family == [1, 2]
77
- 'Universal'
78
- end
79
- end
80
-
81
- def iphone?
82
- device_type == 'iPhone'
83
- end
84
-
85
- def ipad?
86
- device_type == 'iPad'
87
- end
88
-
89
- def universal?
90
- device_type == 'Universal'
91
- end
92
-
93
- def release_type
94
- if stored?
95
- 'Store'
96
- else
97
- build_type
98
- end
99
- end
100
-
101
- def [](key)
102
- info.try(:[], key.to_s)
103
- end
104
-
105
- def method_missing(method_name, *args, &block)
106
- info.try(:[], Util.format_key(method_name)) ||
107
- info.send(method_name) ||
108
- super
109
- end
110
-
111
- def respond_to_missing?(method_name, *args)
112
- info.key?(Util.format_key(method_name)) ||
113
- info.respond_to?(method_name) ||
114
- super
115
- end
116
-
117
- private
118
-
119
- def icon_info(file, uncrush = true)
120
- uncrushed_file = nil
121
- if uncrush
122
- path = File.join(File.dirname(file), 'uncrushed')
123
- Dir.mkdir(path, 0700) unless Dir.exist?(path)
124
-
125
- uncrushed_file = File.join(path, File.basename(file))
126
- PngUncrush.decompress(file, uncrushed_file)
127
- end
128
-
129
- {
130
- name: File.basename(file),
131
- file: file,
132
- uncrushed_file: uncrushed_file,
133
- dimensions: PngUncrush.dimensions(file)
134
- }
135
- end
136
-
137
- def info
138
- return unless File.file?(info_path)
139
-
140
- @info ||= CFPropertyList.native_types(CFPropertyList::List.new(file: info_path).value)
141
- end
142
-
143
- def info_path
144
- File.join(@app_path, 'Info.plist')
145
- end
146
-
147
- IPHONE_KEY = 'CFBundleIcons'
148
- IPAD_KEY = 'CFBundleIcons~ipad'
149
-
150
- def icons_root_path
151
- case device_type
152
- when 'iPhone'
153
- [IPHONE_KEY]
154
- when 'iPad'
155
- [IPAD_KEY]
156
- when 'Universal'
157
- [IPHONE_KEY, IPAD_KEY]
158
- end
159
- end
160
- end
161
- end