lib/run_loop/app.rb in run_loop-2.0.7 vs lib/run_loop/app.rb in run_loop-2.0.8

- old
+ new

@@ -23,11 +23,12 @@ Bundle must: 1. be a directory that exists, 2. have a .app extension, -3. and contain an Info.plist. +3. contain an Info.plist, +4. and the app binary (CFBundleExecutable) must exist } end end # @!visibility private @@ -47,14 +48,16 @@ # @!visibility private def self.valid?(app_bundle_path) return false if app_bundle_path.nil? - File.exist?(app_bundle_path) && - File.directory?(app_bundle_path) && - File.extname(app_bundle_path) == '.app' && - File.exist?(File.join(app_bundle_path, "Info.plist")) + return false if !File.directory?(app_bundle_path) + return false if !File.extname(app_bundle_path) == ".app" + + return false if !self.info_plist_exist?(app_bundle_path) + return false if !self.executable_file_exist?(app_bundle_path) + true end # Returns the Info.plist path. # @raise [RuntimeError] If there is no Info.plist. def info_plist_path @@ -64,11 +67,11 @@ # Inspects the app's Info.plist for the bundle identifier. # @return [String] The value of CFBundleIdentifier. # @raise [RuntimeError] If the plist cannot be read or the # CFBundleIdentifier is empty or does not exist. def bundle_identifier - identifier = plist_buddy.plist_read('CFBundleIdentifier', info_plist_path) + identifier = plist_buddy.plist_read("CFBundleIdentifier", info_plist_path) unless identifier raise "Expected key 'CFBundleIdentifier' in '#{info_plist_path}'" end identifier end @@ -76,17 +79,34 @@ # Inspects the app's Info.plist for the executable name. # @return [String] The value of CFBundleExecutable. # @raise [RuntimeError] If the plist cannot be read or the # CFBundleExecutable is empty or does not exist. def executable_name - identifier = plist_buddy.plist_read('CFBundleExecutable', info_plist_path) - unless identifier + name = plist_buddy.plist_read("CFBundleExecutable", info_plist_path) + unless name raise "Expected key 'CFBundleExecutable' in '#{info_plist_path}'" end - identifier + name end + # Returns the arches for the binary. + def arches + @arches ||= lipo.info + end + + # True if the app has been built for the simulator + def simulator? + arches.include?("i386") || arches.include?("x86_64") + end + + # True if the app has been built for physical devices + def physical_device? + arches.any? do |arch| + arch[/arm/, 0] + end + end + # Inspects the app's file for the server version def calabash_server_version version = nil executables.each do |executable| version = strings(executable).server_version @@ -113,11 +133,10 @@ # @!visibility private # Collects the paths to executables in the bundle. def executables executables = [] Dir.glob("#{path}/**/*") do |file| - next if File.directory?(file) next if skip_executable_check?(file) if otool(file).executable? executables << file end end @@ -130,10 +149,34 @@ end private # @!visibility private + def self.info_plist_exist?(app_bundle_path) + info_plist = File.join(app_bundle_path, "Info.plist") + File.exist?(info_plist) + end + + # @!visibility private + def self.executable_file_exist?(app_bundle_path) + return false if !self.info_plist_exist?(app_bundle_path) + info_plist = File.join(app_bundle_path, "Info.plist") + pbuddy = RunLoop::PlistBuddy.new + name = pbuddy.plist_read("CFBundleExecutable", info_plist) + if name + File.exist?(File.join(app_bundle_path, name)) + else + false + end + end + + # @!visibility private + def lipo + @lipo ||= RunLoop::Lipo.new(path) + end + + # @!visibility private def plist_buddy @plist_buddy ||= RunLoop::PlistBuddy.new end # @!visibility private @@ -148,72 +191,100 @@ RunLoop::Strings.new(file) end # @!visibility private def skip_executable_check?(file) - image?(file) || + File.directory?(file) || + image?(file) || text?(file) || plist?(file) || lproj_asset?(file) || code_signing_asset?(file) || - core_data_asset?(file) + core_data_asset?(file) || + font?(file) end # @!visibility private def text?(file) extension = File.extname(file) + filename = File.basename(file) extension == ".txt" || extension == ".md" || extension == ".html" || extension == ".xml" || extension == ".json" || extension == ".yaml" || extension == ".yml" || extension == ".rtf" || - file[/NOTICE|LICENSE|README|ABOUT/, 0] + + ["NOTICE", "LICENSE", "README", "ABOUT"].any? do |elm| + filename[/#{elm}/] + end end # @!visibility private def image?(file) - file[/jpeg|jpg|gif|png|tiff|svg|pdf|car|iTunesArtwork/, 0] + extension = File.extname(file) + + extension == ".jpeg" || + extension == ".jpg" || + extension == ".gif" || + extension == ".png" || + extension == ".tiff" || + extension == ".svg" || + extension == ".pdf" || + extension == ".car" || + file[/iTunesArtwork/, 0] end # @!visibility private def plist?(file) File.extname(file) == ".plist" end # @!visibility private def lproj_asset?(file) extension = File.extname(file) + dir_extension = File.extname(File.dirname(file)) - file[/lproj/, 0] || - file[/storyboard/, 0] || + dir_extension == ".lproj" || + dir_extension == ".storyboard" || + dir_extension == ".storyboardc" || extension == ".strings" || extension == ".xib" || extension == ".nib" end # @!visibility private def code_signing_asset?(file) name = File.basename(file) extension = File.extname(file) + dirname = File.basename(File.dirname(file)) name == "PkgInfo" || name == "embedded" || extension == ".mobileprovision" || extension == ".xcent" || - file[/_CodeSignature/, 0] + dirname == "_CodeSignature" end # @!visibility private def core_data_asset?(file) extension = File.extname(file) + dir_extension = File.extname(File.dirname(file)) - file[/momd/, 0] || + dir_extension == ".momd" || extension == ".mom" || - extension == ".db" + extension == ".db" || + extension == ".omo" + end + + # @!visibility private + def font?(file) + extension = File.extname(file) + + extension == ".tff" || extension == ".otf" end end end