Class: Gym::DetectValues

Inherits:
Object
  • Object
show all
Defined in:
gym/lib/gym/detect_values.rb

Overview

This class detects all kinds of default values

Class Method Summary collapse

Class Method Details

.archive_path_from_local_xcode_preferencesObject


49
50
51
52
53
54
55
56
57
58
59
# File 'gym/lib/gym/detect_values.rb', line 49

def self.archive_path_from_local_xcode_preferences
  day = Time.now.strftime("%F") # e.g. 2015-08-07
  archive_path = File.expand_path("~/Library/Developer/Xcode/Archives/#{day}/")

  return archive_path unless has_xcode_preferences_plist?

  custom_archive_path = xcode_preferences_dictionary['IDECustomDistributionArchivesLocation']
  return archive_path if custom_archive_path.to_s.length == 0

  return File.join(custom_archive_path, day)
end

.detect_configurationObject

Detects the available configurations (e.g. Debug, Release)


126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'gym/lib/gym/detect_values.rb', line 126

def self.detect_configuration
  config = Gym.config
  configurations = Gym.project.configurations
  return if configurations.count == 0 # this is an optional value anyway

  if config[:configuration]
    # Verify the configuration is available
    unless configurations.include?(config[:configuration])
      UI.error("Couldn't find specified configuration '#{config[:configuration]}'.")
      config[:configuration] = nil
    end
  end
end

.detect_platformObject

Is it an iOS device or a Mac?


112
113
114
115
116
117
118
119
120
121
122
123
# File 'gym/lib/gym/detect_values.rb', line 112

def self.detect_platform
  return if Gym.config[:destination]
  platform = if Gym.project.mac?
               min_xcode8? ? "macOS" : "OS X"
             elsif Gym.project.tvos?
               "tvOS"
             else
               "iOS"
             end

  Gym.config[:destination] = "generic/platform=#{platform}"
end

.detect_schemeObject


103
104
105
# File 'gym/lib/gym/detect_values.rb', line 103

def self.detect_scheme
  Gym.project.select_scheme
end

.detect_selected_provisioning_profilesObject

Since Xcode 9 you need to provide the explicit mapping of what provisioning profile to use for each target of your app


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'gym/lib/gym/detect_values.rb', line 78

def self.detect_selected_provisioning_profiles
  Gym.config[:export_options] ||= {}
  hash_to_use = (Gym.config[:export_options][:provisioningProfiles] || {}).dup || {} # dup so we can show the original values in `verbose` mode

  unless Gym.config[:skip_profile_detection]
    mapping_object = CodeSigningMapping.new(project: Gym.project)
    hash_to_use = mapping_object.merge_profile_mapping(primary_mapping: hash_to_use,
                                                       export_method: Gym.config[:export_method])
  end

  return if hash_to_use.count == 0 # We don't want to set a mapping if we don't have one
  Gym.config[:export_options][:provisioningProfiles] = hash_to_use
  UI.message("Detected provisioning profile mapping: #{hash_to_use}")
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

.detect_toolchainObject

The toolchain parameter is used if you don't use the default toolchain of Xcode (e.g. Swift 2.3 with Xcode 8)


141
142
143
144
145
146
147
148
# File 'gym/lib/gym/detect_values.rb', line 141

def self.detect_toolchain
  return unless Gym.config[:toolchain]

  # Convert the aliases to the full string to make it easier for the user #justfastlanethings
  if Gym.config[:toolchain].to_s == "swift_2_3"
    Gym.config[:toolchain] = "com.apple.dt.toolchain.Swift_2_3"
  end
end

.ensure_export_options_is_hashObject


150
151
152
153
154
155
156
157
158
159
160
# File 'gym/lib/gym/detect_values.rb', line 150

def self.ensure_export_options_is_hash
  return if Gym.config[:export_options].nil? || Gym.config[:export_options].kind_of?(Hash)

  # Reads options from file
  plist_file_path = Gym.config[:export_options]
  UI.user_error!("Couldn't find plist file at path #{File.expand_path(plist_file_path)}") unless File.exist?(plist_file_path)
  hash = Plist.parse_xml(plist_file_path)
  UI.user_error!("Couldn't read provided plist at path #{File.expand_path(plist_file_path)}") if hash.nil?
  # Convert keys to symbols
  Gym.config[:export_options] = keys_to_symbols(hash)
end

.has_xcode_preferences_plist?Boolean

this file only exists when you edit the Xcode preferences to set custom values

Returns:


64
65
66
# File 'gym/lib/gym/detect_values.rb', line 64

def self.has_xcode_preferences_plist?
  File.exist?(xcode_preference_plist_path)
end

.keys_to_symbols(hash) ⇒ Object


162
163
164
165
166
167
168
169
# File 'gym/lib/gym/detect_values.rb', line 162

def self.keys_to_symbols(hash)
  # Convert keys to symbols
  hash = hash.each_with_object({}) do |(k, v), memo|
    memo[k.b.to_s.to_sym] = v
    memo
  end
  hash
end

.min_xcode8?Boolean

Returns:


107
108
109
# File 'gym/lib/gym/detect_values.rb', line 107

def self.min_xcode8?
  Helper.xcode_at_least?("8.0")
end

.set_additional_default_valuesObject

This is needed as these are more complex default values Returns the finished config object


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'gym/lib/gym/detect_values.rb', line 11

def self.set_additional_default_values
  config = Gym.config

  # First, try loading the Gymfile from the current directory
  config.load_configuration_file(Gym.gymfile_name)

  # Detect the project
  FastlaneCore::Project.detect_projects(config)
  Gym.project = FastlaneCore::Project.new(config)

  # Go into the project's folder, as there might be a Gymfile there
  project_path = File.expand_path("..", Gym.project.path)
  unless File.expand_path(".") == project_path
    Dir.chdir(project_path) do
      config.load_configuration_file(Gym.gymfile_name)
    end
  end

  ensure_export_options_is_hash

  detect_scheme
  detect_platform # we can only do that *after* we have the scheme
  detect_selected_provisioning_profiles # we can only do that *after* we have the platform
  detect_configuration
  detect_toolchain

  config[:output_name] ||= Gym.project.app_name

  config[:build_path] ||= archive_path_from_local_xcode_preferences

  # Make sure the output name is valid and remove a trailing `.ipa` extension
  # as it will be added by gym for free
  config[:output_name].gsub!(".ipa", "")
  config[:output_name].gsub!(File::SEPARATOR, "_")

  return config
end

.xcode_preference_plist_pathObject


68
69
70
# File 'gym/lib/gym/detect_values.rb', line 68

def self.xcode_preference_plist_path
  File.expand_path("~/Library/Preferences/com.apple.dt.Xcode.plist")
end

.xcode_preferences_dictionary(path = xcode_preference_plist_path) ⇒ Object


72
73
74
# File 'gym/lib/gym/detect_values.rb', line 72

def self.xcode_preferences_dictionary(path = xcode_preference_plist_path)
  CFPropertyList.native_types(CFPropertyList::List.new(file: path).value)
end