app-info 2.8.5 → 3.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +12 -7
  3. data/.github/workflows/ci.yml +3 -1
  4. data/.rubocop.yml +31 -11
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile +7 -1
  7. data/README.md +64 -9
  8. data/Rakefile +11 -0
  9. data/app_info.gemspec +12 -3
  10. data/lib/app_info/aab.rb +58 -39
  11. data/lib/app_info/android/signature.rb +114 -0
  12. data/lib/app_info/android/signatures/base.rb +49 -0
  13. data/lib/app_info/android/signatures/info.rb +152 -0
  14. data/lib/app_info/android/signatures/v1.rb +59 -0
  15. data/lib/app_info/android/signatures/v2.rb +117 -0
  16. data/lib/app_info/android/signatures/v3.rb +127 -0
  17. data/lib/app_info/android/signatures/v4.rb +14 -0
  18. data/lib/app_info/apk.rb +43 -46
  19. data/lib/app_info/certificate.rb +181 -0
  20. data/lib/app_info/const.rb +41 -0
  21. data/lib/app_info/core_ext/object/try.rb +3 -1
  22. data/lib/app_info/core_ext/string/inflector.rb +2 -0
  23. data/lib/app_info/dsym/debug_info.rb +72 -0
  24. data/lib/app_info/dsym/macho.rb +55 -0
  25. data/lib/app_info/dsym.rb +27 -134
  26. data/lib/app_info/error.rb +7 -1
  27. data/lib/app_info/file.rb +23 -0
  28. data/lib/app_info/helper/archive.rb +37 -0
  29. data/lib/app_info/helper/file_size.rb +25 -0
  30. data/lib/app_info/helper/generate_class.rb +29 -0
  31. data/lib/app_info/helper/protobuf.rb +12 -0
  32. data/lib/app_info/helper/signatures.rb +229 -0
  33. data/lib/app_info/helper.rb +5 -126
  34. data/lib/app_info/info_plist.rb +14 -6
  35. data/lib/app_info/ipa/framework.rb +4 -4
  36. data/lib/app_info/ipa.rb +41 -36
  37. data/lib/app_info/macos.rb +34 -26
  38. data/lib/app_info/mobile_provision.rb +19 -30
  39. data/lib/app_info/pe.rb +226 -0
  40. data/lib/app_info/png_uncrush.rb +5 -4
  41. data/lib/app_info/proguard.rb +11 -17
  42. data/lib/app_info/protobuf/manifest.rb +1 -2
  43. data/lib/app_info/protobuf/models/Configuration_pb.rb +1 -0
  44. data/lib/app_info/protobuf/models/README.md +7 -0
  45. data/lib/app_info/protobuf/models/Resources_pb.rb +2 -0
  46. data/lib/app_info/protobuf/resources.rb +5 -5
  47. data/lib/app_info/version.rb +1 -1
  48. data/lib/app_info.rb +88 -45
  49. metadata +46 -35
@@ -7,7 +7,7 @@ require 'cfpropertylist'
7
7
 
8
8
  module AppInfo
9
9
  # MacOS App parser
10
- class Macos
10
+ class Macos < File
11
11
  include Helper::HumanFileSize
12
12
  include Helper::Archive
13
13
  extend Forwardable
@@ -21,18 +21,26 @@ module AppInfo
21
21
  APPSTORE = 'AppStore'
22
22
  end
23
23
 
24
- def initialize(file)
25
- @file = file
26
- end
27
-
24
+ # return file size
25
+ # @example Read file size in integer
26
+ # aab.size # => 3618865
27
+ #
28
+ # @example Read file size in human readabale
29
+ # aab.size(human_size: true) # => '3.45 MB'
30
+ #
31
+ # @param [Boolean] human_size Convert integer value to human readable.
32
+ # @return [Integer, String]
28
33
  def size(human_size: false)
29
34
  file_to_human_size(@file, human_size: human_size)
30
35
  end
31
36
 
32
- def os
37
+ def file_type
38
+ Format::MACOS
39
+ end
40
+
41
+ def platform
33
42
  Platform::MACOS
34
43
  end
35
- alias file_type os
36
44
 
37
45
  def_delegators :info, :macos?, :iphone?, :ipad?, :universal?, :build_version, :name,
38
46
  :release_version, :identifier, :bundle_id, :display_name,
@@ -56,14 +64,14 @@ module AppInfo
56
64
  end
57
65
 
58
66
  def stored?
59
- File.exist?(store_path)
67
+ ::File.exist?(store_path)
60
68
  end
61
69
 
62
70
  def icons(convert: true)
63
71
  return unless icon_file
64
72
 
65
73
  data = {
66
- name: File.basename(icon_file),
74
+ name: ::File.basename(icon_file),
67
75
  file: icon_file
68
76
  }
69
77
 
@@ -72,7 +80,7 @@ module AppInfo
72
80
  end
73
81
 
74
82
  def archs
75
- return unless File.exist?(binary_path)
83
+ return unless ::File.exist?(binary_path)
76
84
 
77
85
  file = MachO.open(binary_path)
78
86
  case file
@@ -97,25 +105,25 @@ module AppInfo
97
105
  end
98
106
 
99
107
  def mobileprovision?
100
- File.exist?(mobileprovision_path)
108
+ ::File.exist?(mobileprovision_path)
101
109
  end
102
110
 
103
111
  def mobileprovision_path
104
- @mobileprovision_path ||= File.join(app_path, 'Contents', 'embedded.provisionprofile')
112
+ @mobileprovision_path ||= ::File.join(app_path, 'Contents', 'embedded.provisionprofile')
105
113
  end
106
114
 
107
115
  def store_path
108
- @store_path ||= File.join(app_path, 'Contents', '_MASReceipt', 'receipt')
116
+ @store_path ||= ::File.join(app_path, 'Contents', '_MASReceipt', 'receipt')
109
117
  end
110
118
 
111
119
  def binary_path
112
120
  return @binary_path if @binary_path
113
121
 
114
- base_path = File.join(app_path, 'Contents', 'MacOS')
122
+ base_path = ::File.join(app_path, 'Contents', 'MacOS')
115
123
  binary = info['CFBundleExecutable']
116
- return File.join(base_path, binary) if binary
124
+ return ::File.join(base_path, binary) if binary
117
125
 
118
- @binary_path ||= Dir.glob(File.join(base_path, '*')).first
126
+ @binary_path ||= Dir.glob(::File.join(base_path, '*')).first
119
127
  end
120
128
 
121
129
  def info
@@ -123,11 +131,11 @@ module AppInfo
123
131
  end
124
132
 
125
133
  def info_path
126
- @info_path ||= File.join(app_path, 'Contents', 'Info.plist')
134
+ @info_path ||= ::File.join(app_path, 'Contents', 'Info.plist')
127
135
  end
128
136
 
129
137
  def app_path
130
- @app_path ||= Dir.glob(File.join(contents, '*.app')).first
138
+ @app_path ||= Dir.glob(::File.join(contents, '*.app')).first
131
139
  end
132
140
 
133
141
  def clear!
@@ -137,14 +145,14 @@ module AppInfo
137
145
 
138
146
  @contents = nil
139
147
  @app_path = nil
140
- @binrary_path = nil
148
+ @binary_path = nil
141
149
  @info_path = nil
142
150
  @info = nil
143
151
  @icons = nil
144
152
  end
145
153
 
146
154
  def contents
147
- @contents ||= unarchive(@file, path: 'macos')
155
+ @contents ||= unarchive(@file, prefix: 'macos')
148
156
  end
149
157
 
150
158
  private
@@ -155,8 +163,8 @@ module AppInfo
155
163
  info.icons.each do |key|
156
164
  next unless value = info[key]
157
165
 
158
- file = File.join(app_path, 'Contents', 'Resources', "#{value}.icns")
159
- next unless File.file?(file)
166
+ file = ::File.join(app_path, 'Contents', 'Resources', "#{value}.icns")
167
+ next unless ::File.file?(file)
160
168
 
161
169
  return @icon_file = file
162
170
  end
@@ -173,14 +181,14 @@ module AppInfo
173
181
  file = data[:file]
174
182
  reader = Icns::Reader.new(file)
175
183
  Icns::SIZE_TO_TYPE.each do |size, _|
176
- dest_filename = "#{File.basename(file, '.icns')}_#{size}x#{size}.png"
177
- dest_file = tempdir(File.join(File.dirname(file), dest_filename), prefix: 'converted')
184
+ dest_filename = "#{::File.basename(file, '.icns')}_#{size}x#{size}.png"
185
+ dest_file = tempdir(::File.join(::File.dirname(file), dest_filename), prefix: 'converted')
178
186
  next unless icon_data = reader.image(size: size)
179
187
 
180
- File.write(dest_file, icon_data, encoding: Encoding::BINARY)
188
+ ::File.write(dest_file, icon_data, encoding: Encoding::BINARY)
181
189
 
182
190
  data[:sets] << {
183
- name: File.basename(dest_filename),
191
+ name: ::File.basename(dest_filename),
184
192
  file: dest_file,
185
193
  dimensions: ImageSize.path(dest_file).size
186
194
  }
@@ -5,9 +5,9 @@ require 'cfpropertylist'
5
5
 
6
6
  module AppInfo
7
7
  # .mobileprovision file parser
8
- class MobileProvision
9
- def initialize(path)
10
- @path = path
8
+ class MobileProvision < File
9
+ def file_type
10
+ Format::MOBILEPROVISION
11
11
  end
12
12
 
13
13
  def name
@@ -66,12 +66,22 @@ module AppInfo
66
66
  mobileprovision.try(:[], 'Entitlements')
67
67
  end
68
68
 
69
+ # return developer certificates.
70
+ #
71
+ # @deprecated Use {#certificates} instead of this method.
69
72
  def developer_certs
73
+ certificates
74
+ end
75
+
76
+ # return developer certificates.
77
+ #
78
+ # @return [Array<Certificate>]
79
+ def certificates
70
80
  certs = mobileprovision.try(:[], 'DeveloperCertificates')
71
81
  return if certs.empty?
72
82
 
73
- certs.each_with_object([]) do |cert, obj|
74
- obj << DeveloperCertificate.new(cert)
83
+ certs.each_with_object([]) do |cert_data, obj|
84
+ obj << Certificate.parse(cert_data)
75
85
  end
76
86
  end
77
87
 
@@ -142,10 +152,10 @@ module AppInfo
142
152
  when 'com.apple.developer.networking.vpn.api'
143
153
  capabilities << 'Personal VPN'
144
154
  when 'com.apple.developer.healthkit',
145
- 'com.apple.developer.healthkit.access'
155
+ 'com.apple.developer.healthkit.access'
146
156
  capabilities << 'HealthKit' unless capabilities.include?('HealthKit')
147
157
  when 'com.apple.developer.icloud-services',
148
- 'com.apple.developer.icloud-container-identifiers'
158
+ 'com.apple.developer.icloud-container-identifiers'
149
159
  capabilities << 'iCloud' unless capabilities.include?('iCloud')
150
160
  when 'com.apple.developer.in-app-payments'
151
161
  capabilities << 'Apple Pay'
@@ -201,9 +211,9 @@ module AppInfo
201
211
  end
202
212
 
203
213
  def mobileprovision
204
- return @mobileprovision = nil unless File.exist?(@path)
214
+ return @mobileprovision = nil unless ::File.exist?(@file)
205
215
 
206
- data = File.read(@path)
216
+ data = ::File.read(@file)
207
217
  data = strip_plist_wrapper(data) unless bplist?(data)
208
218
  list = CFPropertyList::List.new(data: data).value
209
219
  @mobileprovision = CFPropertyList.native_types(list)
@@ -235,26 +245,5 @@ module AppInfo
235
245
  end_point = raw.index(end_tag) + end_tag.size - 1
236
246
  raw[start_point..end_point]
237
247
  end
238
-
239
- # Developer Certificate
240
- class DeveloperCertificate
241
- attr_reader :raw
242
-
243
- def initialize(data)
244
- @raw = OpenSSL::X509::Certificate.new(data)
245
- end
246
-
247
- def name
248
- @raw.subject.to_a.find { |name, _, _| name == 'CN' }[1].force_encoding('UTF-8')
249
- end
250
-
251
- def created_date
252
- @raw.not_after
253
- end
254
-
255
- def expired_date
256
- @raw.not_before
257
- end
258
- end
259
248
  end
260
249
  end
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pedump'
4
+ require 'fileutils'
5
+ require 'forwardable'
6
+
7
+ module AppInfo
8
+ # Windows PE parser
9
+ #
10
+ # @see https://learn.microsoft.com/zh-cn/windows/win32/debug/pe-format Microsoft PE Format
11
+ class PE < File
12
+ include Helper::HumanFileSize
13
+ include Helper::Archive
14
+ extend Forwardable
15
+
16
+ ARCH = {
17
+ 0x014c => 'x86',
18
+ 0x0200 => 'Intel Itanium',
19
+ 0x8664 => 'x64',
20
+ 0x1c0 => 'arm',
21
+ 0xaa64 => 'arm64',
22
+ 0x5032 => 'RISC-v 32',
23
+ 0x5064 => 'RISC-v 64',
24
+ 0x5128 => 'RISC-v 128'
25
+ }.freeze
26
+
27
+ def file_type
28
+ Format::PE
29
+ end
30
+
31
+ def platform
32
+ Platform::WINDOWS
33
+ end
34
+
35
+ # return file size
36
+ # @example Read file size in integer
37
+ # aab.size # => 3618865
38
+ #
39
+ # @example Read file size in human readabale
40
+ # aab.size(human_size: true) # => '3.45 MB'
41
+ #
42
+ # @param [Boolean] human_size Convert integer value to human readable.
43
+ # @return [Integer, String]
44
+ def size(human_size: false)
45
+ file_to_human_size(@file, human_size: human_size)
46
+ end
47
+
48
+ def binary_size(human_size: false)
49
+ file_to_human_size(binary_file, human_size: human_size)
50
+ end
51
+
52
+ def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version
53
+
54
+ alias name product_name
55
+ alias release_version product_version
56
+ alias build_version assembly_version
57
+
58
+ def archs
59
+ ARCH[image_file_header.Machine] || 'unknown'
60
+ end
61
+ alias architectures archs
62
+
63
+ def imports
64
+ @imports ||= pe.imports.each_with_object({}) do |import, obj|
65
+ obj[import.module_name] = import.first_thunk.map(&:name).compact
66
+ end
67
+ end
68
+
69
+ def icons
70
+ @icons ||= lambda {
71
+ # Fetch the largest size icon
72
+ files = []
73
+ pe.resources&.find_all do |res|
74
+ next unless res.type == 'ICON'
75
+
76
+ filename = "#{::File.basename(file, '.*')}-#{res.type}-#{res.id}.bmp"
77
+ icon_file = tempdir(filename, prefix: 'pe', system: true)
78
+ mask_icon_file = icon_file.sub('.bmp', '.mask.bmp')
79
+
80
+ begin
81
+ ::File.open(icon_file, 'wb') do |f|
82
+ f << res.restore_bitmap(io)
83
+ end
84
+
85
+ if res.bitmap_mask(io)
86
+ mask_icon_file = icon_file.sub('.bmp', '.mask.bmp')
87
+ ::File.open(mask_icon_file, 'wb') do |f|
88
+ f << res.bitmap_mask(io)
89
+ end
90
+ end
91
+ rescue StandardError => e
92
+ # ignore pedump throws any exception.
93
+ raise e unless e.backtrace.first.include?('pedump')
94
+
95
+ FileUtils.rm_f(icon_file)
96
+ ensure
97
+ next unless ::File.exist?(icon_file)
98
+
99
+ mask_file = ::File.exist?(mask_icon_file) ? mask_icon_file : nil
100
+ files << icon_metadata(icon_file, mask_file: mask_file)
101
+ end
102
+ end
103
+
104
+ files
105
+ }.call
106
+ end
107
+
108
+ def pe
109
+ @pe ||= lambda {
110
+ pe = PEdump.new(io)
111
+ pe.logger.level = Logger::FATAL # ignore :warn logger output
112
+ pe
113
+ }.call
114
+ end
115
+
116
+ def version_info
117
+ @version_info ||= VersionInfo.new(pe.version_info)
118
+ end
119
+
120
+ def clear!
121
+ @io = nil
122
+ @pe = nil
123
+ @icons = nil
124
+ @imports = nil
125
+ end
126
+
127
+ def binary_file
128
+ @binary_file ||= lambda {
129
+ file_io = ::File.open(@file, 'rb')
130
+ return @file unless file_io.read(100) =~ AppInfo::ZIP_RETGEX
131
+
132
+ zip_file = Zip::File.open(@file)
133
+ zip_entry = zip_file.glob('*.exe').first
134
+ raise NotFoundWinBinraryError, 'Not found .exe file in archive file' if zip_entry.nil?
135
+
136
+ exe_file = tempdir(zip_entry.name, prefix: 'pe-exe', system: true)
137
+ zip_entry.extract(exe_file)
138
+ zip_file.close
139
+
140
+ return exe_file
141
+ }.call
142
+ end
143
+
144
+ private
145
+
146
+ def image_file_header
147
+ @image_file_header ||= pe.pe.image_file_header
148
+ end
149
+
150
+ def icon_metadata(file, mask_file: nil)
151
+ {
152
+ name: ::File.basename(file),
153
+ file: file,
154
+ mask: mask_file,
155
+ dimensions: ImageSize.path(file).size
156
+ }
157
+ end
158
+
159
+ def io
160
+ @io ||= ::File.open(binary_file, 'rb')
161
+ end
162
+
163
+ # VersionInfo class
164
+ #
165
+ # Ref: https://learn.microsoft.com/zh-cn/windows/win32/menurc/versioninfo-resource
166
+ class VersionInfo
167
+ def initialize(raw)
168
+ @raw = raw
169
+ end
170
+
171
+ def company_name
172
+ @company_name ||= value_of('CompanyName')
173
+ end
174
+
175
+ def product_name
176
+ @product_name ||= value_of('ProductName')
177
+ end
178
+
179
+ def product_version
180
+ @product_version ||= value_of('ProductVersion')
181
+ end
182
+
183
+ def assembly_version
184
+ @assembly_version ||= value_of('Assembly Version')
185
+ end
186
+
187
+ def file_version
188
+ @file_version ||= value_of('FileVersion')
189
+ end
190
+
191
+ def file_description
192
+ @file_description ||= value_of('FileDescription')
193
+ end
194
+
195
+ def copyright
196
+ @copyright ||= value_of('LegalCopyright')
197
+ end
198
+
199
+ private
200
+
201
+ def value_of(key)
202
+ info.each do |v|
203
+ return v[:Value] if v[:szKey] == key.to_s
204
+ end
205
+
206
+ nil
207
+ end
208
+
209
+ def info
210
+ return @info if @info
211
+
212
+ @raw.each do |item|
213
+ next unless item.is_a?(PEdump::VS_VERSIONINFO)
214
+
215
+ versions = item[:Children].select { |v| v.is_a?(PEdump::StringFileInfo) }
216
+ next if versions.empty?
217
+
218
+ @info = versions[0][:Children][0][:Children]
219
+ return @info
220
+ end
221
+
222
+ @info = []
223
+ end
224
+ end
225
+ end
226
+ end
@@ -7,9 +7,10 @@ require 'zlib'
7
7
  require 'stringio'
8
8
 
9
9
  module AppInfo
10
+ # Decompress iOS Png image file.
11
+ # @see https://github.com/swcai/iphone-png-normalizer swcai/iphone-png-normalizer
12
+ # @author Wenwei Cai
10
13
  class PngUncrush
11
- class Error < StandardError; end
12
-
13
14
  class FormatError < Error; end
14
15
 
15
16
  class PngReader # :nodoc:
@@ -69,7 +70,7 @@ module AppInfo
69
70
  end
70
71
 
71
72
  def initialize(filename)
72
- @io = PngReader.new(File.open(filename))
73
+ @io = PngReader.new(::File.open(filename))
73
74
  raise FormatError, 'not a png file' unless @io.png?
74
75
  end
75
76
 
@@ -125,7 +126,7 @@ module AppInfo
125
126
  end
126
127
 
127
128
  def write_file(path, content)
128
- File.write(path, content, encoding: Encoding::BINARY)
129
+ ::File.write(path, content, encoding: Encoding::BINARY)
129
130
  true
130
131
  end
131
132
 
@@ -5,37 +5,31 @@ require 'rexml/document'
5
5
 
6
6
  module AppInfo
7
7
  # Proguard parser
8
- class Proguard
8
+ class Proguard < File
9
9
  include Helper::Archive
10
10
 
11
11
  NAMESPACE = UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, 'icyleaf.com')
12
12
 
13
- attr_reader :file
14
-
15
- def initialize(file)
16
- @file = file
17
- end
18
-
19
13
  def file_type
20
- Platform::PROGUARD
14
+ Format::PROGUARD
21
15
  end
22
16
 
23
17
  def uuid
24
18
  # Similar to https://docs.sentry.io/workflow/debug-files/#proguard-uuids
25
- UUIDTools::UUID.sha1_create(NAMESPACE, File.read(mapping_path)).to_s
19
+ UUIDTools::UUID.sha1_create(NAMESPACE, ::File.read(mapping_path)).to_s
26
20
  end
27
21
  alias debug_id uuid
28
22
 
29
23
  def mapping?
30
- File.exist?(mapping_path)
24
+ ::File.exist?(mapping_path)
31
25
  end
32
26
 
33
27
  def manifest?
34
- File.exist?(manifest_path)
28
+ ::File.exist?(manifest_path)
35
29
  end
36
30
 
37
31
  def symbol?
38
- File.exist?(symbol_path)
32
+ ::File.exist?(symbol_path)
39
33
  end
40
34
  alias resource? symbol?
41
35
 
@@ -68,24 +62,24 @@ module AppInfo
68
62
  def manifest
69
63
  return unless manifest?
70
64
 
71
- @manifest ||= REXML::Document.new(File.new(manifest_path))
65
+ @manifest ||= REXML::Document.new(::File.new(manifest_path))
72
66
  end
73
67
 
74
68
  def mapping_path
75
- @mapping_path ||= Dir.glob(File.join(contents, '*mapping*.txt')).first
69
+ @mapping_path ||= Dir.glob(::File.join(contents, '*mapping*.txt')).first
76
70
  end
77
71
 
78
72
  def manifest_path
79
- @manifest_path ||= File.join(contents, 'AndroidManifest.xml')
73
+ @manifest_path ||= ::File.join(contents, 'AndroidManifest.xml')
80
74
  end
81
75
 
82
76
  def symbol_path
83
- @symbol_path ||= File.join(contents, 'R.txt')
77
+ @symbol_path ||= ::File.join(contents, 'R.txt')
84
78
  end
85
79
  alias resource_path symbol_path
86
80
 
87
81
  def contents
88
- @contents ||= unarchive(@file, path: 'proguard')
82
+ @contents ||= unarchive(@file, prefix: 'proguard')
89
83
  end
90
84
 
91
85
  def clear!
@@ -7,7 +7,7 @@ require 'app_info/core_ext'
7
7
  module AppInfo
8
8
  module Protobuf
9
9
  class Base
10
- include Helper::Defines
10
+ include Helper::GenerateClass
11
11
 
12
12
  def initialize(doc, resources = nil)
13
13
  @resources = resources
@@ -222,7 +222,6 @@ module AppInfo
222
222
 
223
223
  type ||= name.split('.')[2]
224
224
  raise ProtobufParseError, 'Not found intent type' unless TYPES.include?(type)
225
-
226
225
  return false unless intent = send(type.to_sym)
227
226
 
228
227
  values = intent.select { |e| e.name == name }
@@ -118,6 +118,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
118
118
  end
119
119
  end
120
120
 
121
+ # @!visibility private
121
122
  module Aapt
122
123
  module Pb
123
124
  Configuration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("aapt.pb.Configuration").msgclass
@@ -9,6 +9,13 @@ protoc --ruby_out=. Resources.proto
9
9
  protoc --ruby_out=. Configuration.proto
10
10
  ```
11
11
 
12
+ ## Decode
13
+
14
+ ```bash
15
+ protoc --decode=aapt.pb.ResourceTable Resources.proto < aab/base/BundleConfig.pb > BundleConfig.txt
16
+ protoc --decode=aapt.pb.ResourceTable Resources.proto < aab/base/native.pb > native.txt
17
+ ```
18
+
12
19
  ## Resouces
13
20
 
14
21
  `Configuration.proto` and `Resources.proto` can be found in aapt2's github:
@@ -322,7 +322,9 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
322
322
  end
323
323
  end
324
324
 
325
+ # @!visibility private
325
326
  module Aapt
327
+
326
328
  module Pb
327
329
  StringPool = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("aapt.pb.StringPool").msgclass
328
330
  SourcePosition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("aapt.pb.SourcePosition").msgclass
@@ -12,7 +12,7 @@ module AppInfo
12
12
  new(doc)
13
13
  end
14
14
 
15
- include Helper::ReferenceParser
15
+ include Helper::Protobuf
16
16
 
17
17
  attr_reader :packages, :tool_fingerprint
18
18
 
@@ -53,7 +53,7 @@ module AppInfo
53
53
  end
54
54
 
55
55
  class Package
56
- include Helper::Defines
56
+ include Helper::GenerateClass
57
57
 
58
58
  attr_reader :name, :types
59
59
 
@@ -113,14 +113,14 @@ module AppInfo
113
113
  end
114
114
 
115
115
  class Entry
116
+ include Helper::GenerateClass
117
+
116
118
  def self.parse_from(type, package)
117
119
  type.entry.each_with_object([]) do |entry, obj|
118
120
  obj << Entry.new(entry, package)
119
121
  end
120
122
  end
121
123
 
122
- include Helper::Defines
123
-
124
124
  attr_reader :name, :values
125
125
 
126
126
  def initialize(doc, package)
@@ -155,7 +155,7 @@ module AppInfo
155
155
  end
156
156
 
157
157
  class Value
158
- include Helper::ReferenceParser
158
+ include Helper::Protobuf
159
159
  extend Forwardable
160
160
 
161
161
  attr_reader :locale, :config, :original_value, :value, :type
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppInfo
4
- VERSION = '2.8.5'
4
+ VERSION = '3.0.0.beta1'
5
5
  end