lib/app_info/dsym.rb in app-info-2.8.5 vs lib/app_info/dsym.rb in app-info-3.0.0.beta1
- old
+ new
@@ -1,165 +1,58 @@
# frozen_string_literal: true
-require 'macho'
+require 'app_info/dsym/debug_info'
module AppInfo
# DSYM parser
- class DSYM
+ class DSYM < File
include Helper::Archive
- attr_reader :file
-
- def initialize(file)
- @file = file
- end
-
def file_type
- Platform::DSYM
+ Format::DSYM
end
- def object
- @object ||= File.basename(app_path)
+ def each_file(&block)
+ files.each { |file| block.call(file) }
end
- def macho_type
- @macho_type ||= ::MachO.open(app_path)
- end
-
- def machos
- @machos ||= case macho_type
- when ::MachO::MachOFile
- [MachO.new(macho_type, File.size(app_path))]
- else
- size = macho_type.fat_archs.each_with_object([]) do |arch, obj|
- obj << arch.size
- end
-
- machos = []
- macho_type.machos.each_with_index do |file, i|
- machos << MachO.new(file, size[i])
- end
- machos
- end
- end
-
- def release_version
- info.try(:[], 'CFBundleShortVersionString')
- end
-
- def build_version
- info.try(:[], 'CFBundleVersion')
- end
-
- def identifier
- info.try(:[], 'CFBundleIdentifier').sub('com.apple.xcode.dsym.', '')
- end
- alias bundle_id identifier
-
- def info
- return nil unless File.exist?(info_path)
-
- @info ||= CFPropertyList.native_types(CFPropertyList::List.new(file: info_path).value)
- end
-
- def info_path
- @info_path ||= File.join(contents, 'Contents', 'Info.plist')
- end
-
- def app_path
- unless @app_path
- path = File.join(contents, 'Contents', 'Resources', 'DWARF')
- name = Dir.entries(path).reject { |f| ['.', '..'].include?(f) }.first
- @app_path = File.join(path, name)
+ def files
+ @files ||= Dir.children(contents).each_with_object([]) do |file, obj|
+ obj << DebugInfo.new(::File.join(contents, file))
end
-
- @app_path
end
def clear!
return unless @contents
FileUtils.rm_rf(@contents)
@contents = nil
- @app_path = nil
- @info = nil
- @object = nil
- @macho_type = nil
+ @files = nil
end
def contents
- unless @contents
- if File.directory?(@file)
- @contents = @file
- else
- dsym_dir = nil
- @contents = unarchive(@file, path: 'dsym') do |path, zip_file|
- zip_file.each do |f|
- unless dsym_dir
- dsym_dir = f.name
- # fix filename is xxx.app.dSYM/Contents
- dsym_dir = dsym_dir.split('/')[0] if dsym_dir.include?('/')
- end
+ @contents ||= lambda {
+ return @file if ::File.directory?(@file)
- f_path = File.join(path, f.name)
- FileUtils.mkdir_p(File.dirname(f_path))
- f.extract(f_path) unless File.exist?(f_path)
- end
- end
+ dsym_filenames = []
+ unarchive(@file, prefix: 'dsym') do |base_path, zip_file|
+ zip_file.each do |entry|
+ file_path = entry.name
+ next unless file_path.downcase.include?('.dsym/contents/')
+ next if ::File.basename(file_path).start_with?('.')
- @contents = File.join(@contents, dsym_dir)
- end
- end
+ dsym_filename = file_path.split('/').select { |f| f.downcase.end_with?('.dsym') }.last
+ dsym_filenames << dsym_filename unless dsym_filenames.include?(dsym_filename)
- @contents
- end
+ unless file_path.start_with?(dsym_filename)
+ file_path = file_path.split('/')[1..-1].join('/')
+ end
- # DSYM Mach-O
- class MachO
- include Helper::HumanFileSize
-
- def initialize(file, size = 0)
- @file = file
- @size = size
- end
-
- def cpu_name
- @file.cpusubtype
- end
-
- def cpu_type
- @file.cputype
- end
-
- def type
- @file.filetype
- end
-
- def size(human_size: false)
- return number_to_human_size(@size) if human_size
-
- @size
- end
-
- def uuid
- @file[:LC_UUID][0].uuid_string
- end
- alias debug_id uuid
-
- def header
- @header ||= @file.header
- end
-
- def to_h
- {
- uuid: uuid,
- type: type,
- cpu_name: cpu_name,
- cpu_type: cpu_type,
- size: size,
- human_size: size(human_size: true)
- }
- end
+ dest_path = ::File.join(base_path, file_path)
+ entry.extract(dest_path) unless ::File.exist?(dest_path)
+ end
+ end
+ }.call
end
end
end