app-info 2.8.5 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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