gym/lib/gym/detect_values.rb in fastlane-2.44.0.beta.20170630010021 vs gym/lib/gym/detect_values.rb in fastlane-2.44.0
- old
+ new
@@ -12,10 +12,12 @@
# Detect the project
FastlaneCore::Project.detect_projects(config)
Gym.project = FastlaneCore::Project.new(config)
+ detect_selected_provisioning_profiles
+
# Go into the project's folder, as there might be a Gymfile there
Dir.chdir(File.expand_path("..", Gym.project.path)) do
config.load_configuration_file(Gym.gymfile_name)
end
@@ -51,9 +53,82 @@
end
def self.xcode_preferences_dictionary(path)
CFPropertyList.native_types(CFPropertyList::List.new(file: path).value)
end
+
+ # Since Xcode 9 you need to provide the explicit mapping of what provisioning profile to use for
+ # each target of your app
+ # rubocop:disable Style/MultilineBlockChain
+ def self.detect_selected_provisioning_profiles
+ return if Gym.config[:export_options] && Gym.config[:export_options][:provisioningProfiles]
+
+ require 'xcodeproj'
+
+ provisioning_profile_mapping = {}
+
+ # Find the xcodeproj file, as the information isn't included in the workspace file
+ if Gym.project.workspace?
+ # We have a reference to the workspace, let's find the xcodeproj file
+ # For some reason the `plist` gem can't parse the content file
+ # so we'll use a regex to find all group references
+
+ workspace_data_path = File.join(Gym.project.path, "contents.xcworkspacedata")
+ workspace_data = File.read(workspace_data_path)
+ project_paths = workspace_data.scan(/\"group:(.*)\"/).collect do |current_match|
+ # It's a relative path from the workspace file
+ File.join(File.expand_path("..", Gym.project.path), current_match.first)
+ end.find_all do |current_match|
+ !current_match.end_with?("Pods/Pods.xcodeproj")
+ end
+ else
+ project_paths = [Gym.project.path]
+ end
+
+ # Because there might be multiple projects inside a workspace
+ # we iterate over all of them (except for CocoaPods)
+ project_paths.each do |project_path|
+ UI.verbose("Parsing project file '#{project_path}' to find selected provisioning profiles")
+ begin
+ project = Xcodeproj::Project.open(project_path)
+ project.targets.each do |target|
+ target.build_configuration_list.build_configurations.each do |build_configuration|
+ current = build_configuration.build_settings
+
+ bundle_identifier = current["PRODUCT_BUNDLE_IDENTIFIER"]
+ provisioning_profile_specifier = current["PROVISIONING_PROFILE_SPECIFIER"]
+ next if provisioning_profile_specifier.to_s.length == 0
+
+ provisioning_profile_mapping[bundle_identifier] = provisioning_profile_specifier
+ end
+ end
+ rescue => ex
+ # We catch errors here, as we might run into an exception on one included project
+ # But maybe the next project actually contains the information we need
+ if Helper.xcode_at_least?("9.0")
+ UI.error(ex)
+ UI.verbose(ex.backtrace.join("\n"))
+ end
+ end
+ end
+
+ return if provisioning_profile_mapping.count == 0
+
+ Gym.config[:export_options] ||= {}
+ Gym.config[:export_options][:provisioningProfiles] = provisioning_profile_mapping
+ UI.message("Detected provisioning profile mapping: #{provisioning_profile_mapping}")
+ rescue => ex
+ # We don't want to fail the build if the automatic detection doesn't work
+ # especially since the mapping is optional for pre Xcode 9 setups
+ if Helper.xcode_at_least?("9.0")
+ UI.error("Couldn't automatically detect the provisioning profile mapping")
+ UI.error("Since Xcode 9 you need to provide an explicit mapping of what")
+ UI.error("provisioning profile to use for each target of your app")
+ UI.error(ex)
+ UI.verbose(ex.backtrace.join("\n"))
+ end
+ end
+ # rubocop:enable Style/MultilineBlockChain
def self.detect_scheme
Gym.project.select_scheme
end