Module: FastlaneCore::Helper

Defined in:
fastlane_core/lib/fastlane_core/helper.rb

Class Method Summary collapse

Class Method Details

.backticks(command, print: true) ⇒ Object

Runs a given command using backticks (`) and prints them out using the UI.command method


275
276
277
278
279
280
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 275

def self.backticks(command, print: true)
  UI.command(command) if print
  result = `#{command}`
  UI.command_output(result) if print
  return result
end

.buildlog_pathObject

Logs base directory


113
114
115
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 113

def self.buildlog_path
  return ENV["FL_BUILDLOG_PATH"] || "~/Library/Logs"
end

.bundler?boolean

Returns true if executing with bundler (like 'bundle exec fastlane [action]').

Returns:

  • (boolean)

    true if executing with bundler (like 'bundle exec fastlane [action]')


29
30
31
32
33
34
35
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 29

def self.bundler?
  # Bundler environment variable
  ['BUNDLE_BIN_PATH', 'BUNDLE_GEMFILE'].each do |current|
    return true if ENV.key?(current)
  end
  return false
end

.ci?boolean

Returns true if building in a known CI environment.

Returns:

  • (boolean)

    true if building in a known CI environment


73
74
75
76
77
78
79
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 73

def self.ci?
  # Check for Jenkins, Travis CI, ... environment variables
  ['JENKINS_HOME', 'JENKINS_URL', 'TRAVIS', 'CIRCLECI', 'CI', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION', 'GO_PIPELINE_NAME', 'bamboo_buildKey', 'GITLAB_CI', 'XCS', 'TF_BUILD', 'GITHUB_ACTION', 'GITHUB_ACTIONS'].each do |current|
    return true if ENV.key?(current)
  end
  return false
end

.colors_disabled?Boolean

Do we want to disable the colored output?

Returns:


103
104
105
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 103

def self.colors_disabled?
  FastlaneCore::Env.truthy?("FASTLANE_DISABLE_COLORS")
end

.contained_fastlane?Boolean

Do we run from a bundled fastlane, which contains Ruby and OpenSSL? Usually this means the fastlane directory is ~/.fastlane/bin/ We set this value via the environment variable `FASTLANE_SELF_CONTAINED`

Returns:


40
41
42
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 40

def self.contained_fastlane?
  ENV["FASTLANE_SELF_CONTAINED"].to_s == "true" && !self.homebrew?
end

.executable?(cmd_path) ⇒ Boolean

checks if a given path is an executable file

Returns:


356
357
358
359
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 356

def self.executable?(cmd_path)
  # no executable files on Windows, so existing is enough there
  cmd_path && !File.directory?(cmd_path) && (File.executable?(cmd_path) || (self.windows? && File.exist?(cmd_path)))
end

.fastlane_enabled?Boolean

fastlane

Returns:


15
16
17
18
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 15

def self.fastlane_enabled?
  # This is called from the root context on the first start
  @enabled ||= !FastlaneCore::FastlaneFolder.path.nil?
end

.fastlane_enabled_folder_pathObject

Checks if fastlane is enabled for this project and returns the folder where the configuration lives


21
22
23
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 21

def self.fastlane_enabled_folder_path
  fastlane_enabled? ? FastlaneCore::FastlaneFolder.path : '.'
end

.gem_path(gem_name) ⇒ Object

DEPRECATED: Use the `ROOT` constant from the appropriate tool module instead e.g. File.join(Sigh::ROOT, 'lib', 'assets', 'resign.sh')

Path to the installed gem to load resources (e.g. resign.sh)


397
398
399
400
401
402
403
404
405
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 397

def self.gem_path(gem_name)
  UI.deprecated('`Helper.gem_path` is deprecated. Use the `ROOT` constant from the appropriate tool module instead.')

  if !Helper.test? && Gem::Specification.find_all_by_name(gem_name).any?
    return Gem::Specification.find_by_name(gem_name).gem_dir
  else
    return './'
  end
end

.hide_loading_indicatorObject


346
347
348
349
350
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 346

def self.hide_loading_indicator
  if self.should_show_loading_indicator? && @require_fastlane_spinner
    @require_fastlane_spinner.success
  end
end

.homebrew?Boolean

returns true if fastlane was installed via Homebrew

Returns:


50
51
52
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 50

def self.homebrew?
  ENV["FASTLANE_INSTALLED_VIA_HOMEBREW"].to_s == "true"
end

.is_ci?Boolean

Returns:


381
382
383
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 381

def self.is_ci?
  ci?
end

.is_mac?Boolean

Returns:


385
386
387
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 385

def self.is_mac?
  self.mac?
end

.is_test?Boolean

Use Helper.test?, Helper.ci?, Helper.mac? or Helper.windows? instead (legacy calls)

Returns:


377
378
379
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 377

def self.is_test?
  self.test?
end

.is_windows?Boolean

Returns:


389
390
391
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 389

def self.is_windows?
  self.windows?
end

.itms_pathObject

Returns the full path to the iTMSTransporter executable.

Returns:

  • the full path to the iTMSTransporter executable


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 201

def self.itms_path
  return ENV["FASTLANE_ITUNES_TRANSPORTER_PATH"] if FastlaneCore::Env.truthy?("FASTLANE_ITUNES_TRANSPORTER_PATH")

  if self.mac?
    # First check for manually install iTMSTransporter
    user_local_itms_path = "/usr/local/itms"
    return user_local_itms_path if File.exist?(user_local_itms_path)

    # Then check for iTMSTransporter in the Xcode path
    [
      "../Applications/Application Loader.app/Contents/MacOS/itms",
      "../Applications/Application Loader.app/Contents/itms",
      "../SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms" # For Xcode 11
    ].each do |path|
      result = File.expand_path(File.join(self.xcode_path, path))
      return result if File.exist?(result)
    end
    UI.user_error!("Could not find transporter at #{self.xcode_path}. Please make sure you set the correct path to your Xcode installation.")
  elsif self.windows?
    [
      "C:/Program Files (x86)/itms"
    ].each do |path|
      return path if File.exist?(path)
    end
    UI.user_error!("Could not find transporter at usual locations. Please use environment variable `FASTLANE_ITUNES_TRANSPORTER_PATH` to specify your installation path.")
  else
    # not Mac or Windows
    return ''
  end
end

.json_file?(filename) ⇒ Boolean

checks if given file is a valid json file base taken from: stackoverflow.com/a/26235831/1945875

Returns:


363
364
365
366
367
368
369
370
371
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 363

def self.json_file?(filename)
  return false unless File.exist?(filename)
  begin
    JSON.parse(File.read(filename))
    return true
  rescue JSON::ParserError
    return false
  end
end

.keychain_path(keychain_name) ⇒ Object

keychain


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 235

def self.keychain_path(keychain_name)
  # Existing code expects that a keychain name will be expanded into a default path to Library/Keychains
  # in the user's home directory. However, this will not allow the user to pass an absolute path
  # for the keychain value
  #
  # So, if the passed value can't be resolved as a file in Library/Keychains, just use it as-is
  # as the keychain path.
  #
  # We need to expand each path because File.exist? won't handle directories including ~ properly
  #
  # We also try to append `-db` at the end of the file path, as with Sierra the default Keychain name
  # has changed for some users: https://github.com/fastlane/fastlane/issues/5649

  # Remove the ".keychain" at the end of the keychain name
  name = keychain_name.sub(/\.keychain$/, "")

  possible_locations = [
    File.join(Dir.home, 'Library', 'Keychains', name),
    name
  ].map { |path| File.expand_path(path) }

  # Transforms ["thing"] to ["thing-db", "thing.keychain-db", "thing", "thing.keychain"]
  keychain_paths = []
  possible_locations.each do |location|
    keychain_paths << "#{location}-db"
    keychain_paths << "#{location}.keychain-db"
    keychain_paths << location
    keychain_paths << "#{location}.keychain"
  end

  keychain_path = keychain_paths.find { |path| File.file?(path) }
  UI.user_error!("Could not locate the provided keychain. Tried:\n\t#{keychain_paths.join("\n\t")}") unless keychain_path
  keychain_path
end

.linux?Boolean

Returns:


93
94
95
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 93

def self.linux?
  (/linux/ =~ RUBY_PLATFORM) != nil
end

.logObject

This method is deprecated, use the `UI` class docs.fastlane.tools/advanced/#user-input-and-output


409
410
411
412
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 409

def self.log
  UI.deprecated("Helper.log is deprecated. Use `UI` class instead")
  UI.current.log
end

.mac?Boolean

Is the currently running computer a Mac?

Returns:


98
99
100
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 98

def self.mac?
  (/darwin/ =~ RUBY_PLATFORM) != nil
end

.mac_app?Boolean

returns true if fastlane was installed from the Fabric Mac app

Returns:


45
46
47
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 45

def self.mac_app?
  ENV["FASTLANE_SELF_CONTAINED"].to_s == "false"
end

.mac_stock_terminal?Boolean

Does the user use the Mac stock terminal

Returns:


108
109
110
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 108

def self.mac_stock_terminal?
  FastlaneCore::Env.truthy?("TERM_PROGRAM_VERSION")
end

.operating_systemObject


81
82
83
84
85
86
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 81

def self.operating_system
  return "macOS" if RUBY_PLATFORM.downcase.include?("darwin")
  return "Windows" if RUBY_PLATFORM.downcase.include?("mswin")
  return "Linux" if RUBY_PLATFORM.downcase.include?("linux")
  return "Unknown"
end

.rubygems?Boolean

returns true if fastlane was installed via RubyGems

Returns:


55
56
57
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 55

def self.rubygems?
  !self.bundler? && !self.contained_fastlane? && !self.homebrew? && !self.mac_app?
end

.sh_enabled?Boolean

Returns true if it is enabled to execute external commands.

Returns:

  • (Boolean)

    true if it is enabled to execute external commands


68
69
70
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 68

def self.sh_enabled?
  !self.test?
end

.should_show_loading_indicator?Boolean

loading indicator

Returns:


327
328
329
330
331
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 327

def self.should_show_loading_indicator?
  return false if FastlaneCore::Env.truthy?("FASTLANE_DISABLE_ANIMATION")
  return false if Helper.ci?
  return true
end

.show_loading_indicator(text = nil) ⇒ Object

Show/Hide loading indicator


334
335
336
337
338
339
340
341
342
343
344
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 334

def self.show_loading_indicator(text = nil)
  if self.should_show_loading_indicator?
    # we set the default here, instead of at the parameters
    # as we don't want to `UI.message` a rocket that's just there for the loading indicator
    text ||= "🚀"
    @require_fastlane_spinner = TTY::Spinner.new("[:spinner] #{text} ", format: :dots)
    @require_fastlane_spinner.auto_spin
  else
    UI.message(text) if text
  end
end

.strip_ansi_colors(str) ⇒ Object

removes ANSI colors from string


283
284
285
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 283

def self.strip_ansi_colors(str)
  str.gsub(/\e\[([;\d]+)?m/, '')
end

.test?Boolean

Returns true if the currently running program is a unit test.

Returns:

  • (Boolean)

    true if the currently running program is a unit test


63
64
65
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 63

def self.test?
  Object.const_defined?("SpecHelper")
end

.transporter_java_executable_pathObject

iTMSTransporter


174
175
176
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 174

def self.transporter_java_executable_path
  return File.join(self.transporter_java_path, 'bin', 'java')
end

.transporter_java_ext_dirObject


178
179
180
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 178

def self.transporter_java_ext_dir
  return File.join(self.transporter_java_path, 'lib', 'ext')
end

.transporter_java_jar_pathObject


182
183
184
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 182

def self.transporter_java_jar_path
  return File.join(self.itms_path, 'lib', 'itmstransporter-launcher.jar')
end

.transporter_java_pathObject


190
191
192
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 190

def self.transporter_java_path
  return File.join(self.itms_path, 'java')
end

.transporter_pathObject

Returns the full path to the iTMSTransporter executable.

Returns:

  • the full path to the iTMSTransporter executable


195
196
197
198
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 195

def self.transporter_path
  return File.join(self.itms_path, 'bin', 'iTMSTransporter') unless Helper.windows?
  return File.join(self.itms_path, 'iTMSTransporter')
end

.transporter_user_dirObject


186
187
188
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 186

def self.transporter_user_dir
  return File.join(self.itms_path, 'bin')
end

.windows?Boolean

Returns:


88
89
90
91
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 88

def self.windows?
  # taken from: https://stackoverflow.com/a/171011/1945875
  (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
end

.with_env_values(hash, &block) ⇒ Object

Executes the provided block after adjusting the ENV to have the provided keys and values set as defined in hash. After the block completes, restores the ENV to its previous state.


311
312
313
314
315
316
317
318
319
320
321
322
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 311

def self.with_env_values(hash, &block)
  old_vals = ENV.select { |k, v| hash.include?(k) }
  hash.each do |k, v|
    ENV[k] = hash[k]
  end
  yield
ensure
  hash.each do |k, v|
    ENV.delete(k) unless old_vals.include?(k)
    ENV[k] = old_vals[k]
  end
end

.xcode_at_least?(version) ⇒ Boolean

Returns true if Xcode version is higher than 8.3.

Returns:

  • (Boolean)

    true if Xcode version is higher than 8.3


165
166
167
168
169
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 165

def self.xcode_at_least?(version)
  FastlaneCore::UI.user_error!("Unable to locate Xcode. Please make sure to have Xcode installed on your machine") if xcode_version.nil?
  v = xcode_version
  Gem::Version.new(v) >= Gem::Version.new(version)
end

.xcode_pathObject

Returns the full path to the Xcode developer tools of the currently running system.

Returns:

  • the full path to the Xcode developer tools of the currently running system


122
123
124
125
126
127
128
129
130
131
132
133
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 122

def self.xcode_path
  return "" unless self.mac?

  if self.xcode_server?
    # Xcode server always creates a link here
    xcode_server_xcode_path = "/Library/Developer/XcodeServer/CurrentXcodeSymlink/Contents/Developer"
    UI.verbose("We're running as XcodeServer, setting path to #{xcode_server_xcode_path}")
    return xcode_server_xcode_path
  end

  return `xcode-select -p`.delete("\n") + "/"
end

.xcode_server?Boolean

Returns:


135
136
137
138
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 135

def self.xcode_server?
  # XCS is set by Xcode Server
  return ENV["XCS"].to_i == 1
end

.xcode_versionObject

Returns The version of the currently used Xcode installation (e.g. “7.0”).

Returns:

  • The version of the currently used Xcode installation (e.g. “7.0”)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 141

def self.xcode_version
  return nil unless self.mac?
  return @xcode_version if @xcode_version && @developer_dir == ENV['DEVELOPER_DIR']

  xcodebuild_path = "#{xcode_path}/usr/bin/xcodebuild"

  xcode_build_installed = File.exist?(xcodebuild_path)
  unless xcode_build_installed
    UI.verbose("Couldn't find xcodebuild at #{xcodebuild_path}, check that it exists")
    return nil
  end

  begin
    output = `DEVELOPER_DIR='' "#{xcodebuild_path}" -version`
    @xcode_version = output.split("\n").first.split(' ')[1]
    @developer_dir = ENV['DEVELOPER_DIR']
  rescue => ex
    UI.error(ex)
    UI.user_error!("Error detecting currently used Xcode installation, please ensure that you have Xcode installed and set it using `sudo xcode-select -s [path]`")
  end
  @xcode_version
end

.zip_directory(path, output_path, contents_only: false, overwrite: false, print: true) ⇒ Object

Zips directory


288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 288

def self.zip_directory(path, output_path, contents_only: false, overwrite: false, print: true)
  if overwrite
    overwrite_command = " && rm -f '#{output_path}'"
  else
    overwrite_command = ""
  end

  if contents_only
    command = "cd '#{path}'#{overwrite_command} && zip -r '#{output_path}' *"
  else
    containing_path = File.expand_path("..", path)
    contents_path = File.basename(path)

    command = "cd '#{containing_path}'#{overwrite_command} && zip -r '#{output_path}' '#{contents_path}'"
  end

  UI.command(command) unless print
  Helper.backticks(command, print: print)
end