app-info 2.5.4 → 2.6.3

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]
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.4'
4
+ VERSION = '2.6.3'
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.4
4
+ version: 2.6.3
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-07-08 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -124,6 +124,20 @@ dependencies:
124
124
  - - "<"
125
125
  - !ruby/object:Gem::Version
126
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
127
141
  - !ruby/object:Gem::Dependency
128
142
  name: bundler
129
143
  requirement: !ruby/object:Gem::Requirement
@@ -166,18 +180,34 @@ dependencies:
166
180
  - - "~>"
167
181
  - !ruby/object:Gem::Version
168
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'
169
197
  description: Teardown tool for ipa/apk files and dSYM file, even support for info.plist
170
198
  and .mobileprovision files
171
199
  email:
172
200
  - icyleaf.cn@gmail.com
173
- executables: []
201
+ executables:
202
+ - app-info
174
203
  extensions: []
175
204
  extra_rdoc_files: []
176
205
  files:
206
+ - ".github/dependabot.yml"
207
+ - ".github/workflows/ci.yml"
177
208
  - ".gitignore"
178
209
  - ".rspec"
179
210
  - ".rubocop.yml"
180
- - ".travis.yml"
181
211
  - CHANGELOG.md
182
212
  - CODE_OF_CONDUCT.md
183
213
  - Gemfile
@@ -185,18 +215,21 @@ files:
185
215
  - README.md
186
216
  - Rakefile
187
217
  - app_info.gemspec
218
+ - exe/app-info
188
219
  - lib/app-info.rb
189
220
  - lib/app_info.rb
190
221
  - lib/app_info/apk.rb
191
222
  - lib/app_info/core_ext/object/try.rb
192
223
  - lib/app_info/dsym.rb
224
+ - lib/app_info/info_plist.rb
193
225
  - lib/app_info/ipa.rb
194
226
  - lib/app_info/ipa/framework.rb
195
- - lib/app_info/ipa/info_plist.rb
196
- - lib/app_info/ipa/mobile_provision.rb
197
227
  - lib/app_info/ipa/plugin.rb
228
+ - lib/app_info/macos.rb
229
+ - lib/app_info/mobile_provision.rb
198
230
  - lib/app_info/png_uncrush.rb
199
231
  - lib/app_info/proguard.rb
232
+ - lib/app_info/shell.rb
200
233
  - lib/app_info/util.rb
201
234
  - lib/app_info/version.rb
202
235
  homepage: http://github.com/icyleaf/app-info
@@ -211,7 +244,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
211
244
  requirements:
212
245
  - - ">="
213
246
  - !ruby/object:Gem::Version
214
- version: '2.3'
247
+ version: '2.5'
215
248
  required_rubygems_version: !ruby/object:Gem::Requirement
216
249
  requirements:
217
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,162 +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
- uncrushed_file = nil unless File.exists?(uncrushed_file)
128
- end
129
-
130
- {
131
- name: File.basename(file),
132
- file: file,
133
- uncrushed_file: uncrushed_file,
134
- dimensions: PngUncrush.dimensions(file)
135
- }
136
- end
137
-
138
- def info
139
- return unless File.file?(info_path)
140
-
141
- @info ||= CFPropertyList.native_types(CFPropertyList::List.new(file: info_path).value)
142
- end
143
-
144
- def info_path
145
- File.join(@app_path, 'Info.plist')
146
- end
147
-
148
- IPHONE_KEY = 'CFBundleIcons'
149
- IPAD_KEY = 'CFBundleIcons~ipad'
150
-
151
- def icons_root_path
152
- case device_type
153
- when 'iPhone'
154
- [IPHONE_KEY]
155
- when 'iPad'
156
- [IPAD_KEY]
157
- when 'Universal'
158
- [IPHONE_KEY, IPAD_KEY]
159
- end
160
- end
161
- end
162
- end