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