Module: FastlaneCore::Helper

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

Class Method Summary collapse

Class Method Details

.ask_password(message: "Passphrase: ", confirm: nil, confirmation_message: "Type passphrase again: ") ⇒ Object



487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 487

def self.ask_password(message: "Passphrase: ", confirm: nil, confirmation_message: "Type passphrase again: ")
  raise "This code should only run in interactive mode" unless UI.interactive?

  loop do
    password = UI.password(message)
    if confirm
      password2 = UI.password(confirmation_message)
      if password == password2
        return password
      end
    else
      return password
    end
    UI.error("Your entries do not match. Please try again")
  end
end

.backticks(command, print: true) ⇒ Object

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



319
320
321
322
323
324
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 319

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



125
126
127
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 125

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]’)



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

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



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

def self.ci?
  return true if self.is_circle_ci?

  # Check for Jenkins, Travis CI, ... environment variables
  ['JENKINS_HOME', 'JENKINS_URL', 'TRAVIS', 'CI', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION', 'GO_PIPELINE_NAME', 'bamboo_buildKey', 'GITLAB_CI', 'XCS', 'TF_BUILD', 'GITHUB_ACTION', 'GITHUB_ACTIONS', 'BITRISE_IO', 'BUDDY', 'CODEBUILD_BUILD_ARN'].each do |current|
    return true if FastlaneCore::Env.truthy?(current)
  end
  return false
end

.colors_disabled?Boolean

Do we want to disable the colored output?

Returns:



115
116
117
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 115

def self.colors_disabled?
  FastlaneCore::Env.truthy?("FASTLANE_DISABLE_COLORS") || ENV.key?("NO_COLOR")
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:



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

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:



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

def self.executable?(cmd_path)
  if !cmd_path || File.directory?(cmd_path)
    return false
  end

  return File.exist?(get_executable_path(cmd_path))
end

.fastlane_enabled?Boolean

fastlane

Returns:



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

def self.fastlane_enabled?
  # This is called from the root context on the first start
  !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



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

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)



470
471
472
473
474
475
476
477
478
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 470

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

.get_executable_path(cmd_path) ⇒ Object

returns the path of the executable with the correct extension on Windows



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 409

def self.get_executable_path(cmd_path)
  cmd_path = localize_file_path(cmd_path)

  if self.windows?
    # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
    # e.g. ".COM;.EXE;.BAT;.CMD"
    exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []

    # no executable files on Windows, so existing is enough there
    # also check if command + ext is present
    exts.each do |ext|
      executable_path = "#{cmd_path}#{ext.downcase}"
      return executable_path if File.exist?(executable_path)
    end
  end

  return cmd_path
end

.hide_loading_indicatorObject



390
391
392
393
394
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 390

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:



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

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

.is_ci?Boolean

Returns:



454
455
456
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 454

def self.is_ci?
  ci?
end

.is_circle_ci?Boolean

Returns:



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

def self.is_circle_ci?
  return ENV.key?('CIRCLECI')
end

.is_codebuild?boolean

Returns true if environment variable CODEBUILD_BUILD_ARN is set.

Returns:

  • (boolean)

    true if environment variable CODEBUILD_BUILD_ARN is set



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

def self.is_codebuild?
  return ENV.key?('CODEBUILD_BUILD_ARN')
end

.is_mac?Boolean

Returns:



458
459
460
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 458

def self.is_mac?
  self.mac?
end

.is_test?Boolean

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

Returns:



450
451
452
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 450

def self.is_test?
  self.test?
end

.is_windows?Boolean

Returns:



462
463
464
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 462

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



233
234
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
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 233

def self.itms_path
  return self.user_defined_itms_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:



436
437
438
439
440
441
442
443
444
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 436

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



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 267

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:



105
106
107
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 105

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

.localize_file_path(path) ⇒ Object

returns the path with the platform-specific path separator (‘/` on UNIX, `` on Windows)



429
430
431
432
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 429

def self.localize_file_path(path)
  # change `/` to `\` on Windows
  return self.windows? ? path.gsub('/', '\\') : path
end

.logObject

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



482
483
484
485
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 482

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:



110
111
112
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 110

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

.mac_app?Boolean

returns true if fastlane was installed from the Fabric Mac app

Returns:



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

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:



120
121
122
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 120

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

.operating_systemObject



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

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:



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

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



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

def self.sh_enabled?
  !self.test? || ENV["FORCE_SH_DURING_TESTS"]
end

.should_show_loading_indicator?Boolean

loading indicator

Returns:



371
372
373
374
375
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 371

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



378
379
380
381
382
383
384
385
386
387
388
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 378

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



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

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

.swift_versionObject

Returns Swift version.

Returns:

  • Swift version



187
188
189
190
191
192
193
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 187

def self.swift_version
  if self.which('swift')
    output = `swift --version 2> /dev/null`
    return output.split("\n").first.match(/version ([0-9.]+)/).captures.first
  end
  return nil
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



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

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

.transporter_java_executable_pathObject

iTMSTransporter



198
199
200
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 198

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

.transporter_java_ext_dirObject



202
203
204
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 202

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

.transporter_java_jar_pathObject



206
207
208
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 206

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

.transporter_java_pathObject



214
215
216
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 214

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



219
220
221
222
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 219

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



210
211
212
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 210

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

.user_defined_itms_pathObject



228
229
230
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 228

def self.user_defined_itms_path
  return ENV["FASTLANE_ITUNES_TRANSPORTER_PATH"] if self.user_defined_itms_path?
end

.user_defined_itms_path?Boolean

Returns:



224
225
226
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 224

def self.user_defined_itms_path?
  return FastlaneCore::Env.truthy?("FASTLANE_ITUNES_TRANSPORTER_PATH")
end

.which(cmd) ⇒ Object

Cross-platform way of finding an executable in the $PATH. Returns the full path to the executable, or nil if not found. Unlike shelling out to ‘which`, this produces no output, making it suitable for CI environments.

Helper.which('ruby') #=> "/usr/bin/ruby"
Helper.which('not_real') #=> nil


313
314
315
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 313

def self.which(cmd)
  FastlaneCore::CommandExecutor.which(cmd)
end

.windows?Boolean

Returns:



100
101
102
103
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 100

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.



355
356
357
358
359
360
361
362
363
364
365
366
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 355

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 installed Xcode version is ‘greater than or equal to’ the input parameter version.

Returns:

  • (Boolean)

    true if installed Xcode version is ‘greater than or equal to’ the input parameter version



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

def self.xcode_at_least?(version)
  installed_xcode_version = xcode_version
  UI.user_error!("Unable to locate Xcode. Please make sure to have Xcode installed on your machine") if installed_xcode_version.nil?
  Gem::Version.new(installed_xcode_version) >= 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



134
135
136
137
138
139
140
141
142
143
144
145
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 134

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:



147
148
149
150
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 147

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”)



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 153

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



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'fastlane_core/lib/fastlane_core/helper.rb', line 332

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