module Fastlane::Actions

def self.clear_lane_context

Used in tests to get a clear lane before every test
def self.clear_lane_context
  @lane_context = nil
end

def self.execute_action(step_name)

Parameters:
  • step_name (String) -- the name of the currently built code (e.g. snapshot, sigh, ...)
def self.execute_action(step_name)
  start = Time.now # before the raise block, since `start` is required in the ensure block
  raise 'No block given'.red unless block_given?
  error = nil
  exc = nil
  begin
    Helper.log_alert("Step: " + step_name) if step_name
    yield
  rescue => ex
    exc = ex
    error = caller.join("\n") + "\n\n" + ex.to_s
  end
ensure
  # This is also called, when the block has a return statement
  if step_name
    duration = Time.now - start
    executed_actions << {
      name: step_name,
      error: error,
      time: duration
    }
  end
  raise exc if exc
end

def self.executed_actions

def self.executed_actions
  @executed_actions ||= []
end

def self.get_all_official_actions

rubocop:disable Style/AccessorMethodName
returns a list of official integrations
def self.get_all_official_actions
  Dir[File.expand_path('*.rb', File.dirname(__FILE__))].collect do |file|
    File.basename(file).gsub('.rb', '').to_sym
  end
end

def self.git_author

Get the author name of the last git commit
def self.git_author
  s = `git log --name-status HEAD^..HEAD`
  s = s.match(/Author:.*<(.*)>/)[1]
  return s if s.to_s.length > 0
  return nil
rescue
  return nil
end

def self.git_branch

Returns the current git branch - can be replaced using the environment variable `GIT_BRANCH`
def self.git_branch
  return ENV['GIT_BRANCH'] if ENV['GIT_BRANCH'].to_s.length > 0 # set by Jenkins
  s = `git rev-parse --abbrev-ref HEAD`
  return s.to_s.strip if s.to_s.length > 0
  nil
end

def self.lane_context

The shared hash can be accessed by any action and contains information like the screenshots path or beta URL
def self.lane_context
  @lane_context ||= {}
end

def self.last_git_commit

def self.last_git_commit
  s = `git log -1 --pretty=%B`.strip
  return s if s.to_s.length > 0
  nil
end

def self.load_default_actions

def self.load_default_actions
  Dir[File.expand_path('*.rb', File.dirname(__FILE__))].each do |file|
    require file
  end
end

def self.load_external_actions(path)

def self.load_external_actions(path)
  raise 'You need to pass a valid path' unless File.exist?(path)
  Dir[File.expand_path('*.rb', path)].each do |file|
    require file
    file_name = File.basename(file).gsub('.rb', '')
    class_name = file_name.fastlane_class + 'Action'
    begin
      class_ref = Fastlane::Actions.const_get(class_name)
      if class_ref.respond_to?(:run)
        Helper.log.info "Successfully loaded custom action '#{file}'.".green
      else
        Helper.log.error "Could not find method 'run' in class #{class_name}.".red
        Helper.log.error 'For more information, check out the docs: https://github.com/KrauseFx/fastlane'
        raise "Plugin '#{file_name}' is damaged!"
      end
    rescue NameError
      # Action not found
      Helper.log.error "Could not find '#{class_name}' class defined.".red
      Helper.log.error 'For more information, check out the docs: https://github.com/KrauseFx/fastlane'
      raise "Plugin '#{file_name}' is damaged!"
    end
  end
end

def self.load_helpers

Import all the helpers
def self.load_helpers
  Dir[File.expand_path('../helper/*.rb', File.dirname(__FILE__))].each do |file|
    require file
  end
end

def self.print_gem_error(str)

def self.print_gem_error(str)
  Helper.log.error str.red
end

def self.sh(command, log: true)

Parameters:
  • log (boolean) -- should fastlane print out the executed command
def self.sh(command, log: true)
  sh_no_action(command, log: log)
end

def self.sh_no_action(command, log: true)

def self.sh_no_action(command, log: true)
  # Set the encoding first, the user might have set it wrong
  previous_encoding = [Encoding.default_external, Encoding.default_internal]
  Encoding.default_external = Encoding::UTF_8
  Encoding.default_internal = Encoding::UTF_8
  command = command.join(' ') if command.kind_of?(Array) # since it's an array of one element when running from the Fastfile
  Helper.log.info ['[SHELL COMMAND]', command.yellow].join(': ') if log
  result = ''
  if Helper.test?
    result << command # only for the tests
  else
    exit_status = nil
    IO.popen(command, err: [:child, :out]) do |io|
      io.each do |line|
        Helper.log.info ['[SHELL]', line.strip].join(': ')
        result << line
      end
      io.close
      exit_status = $?.exitstatus
    end
    if exit_status != 0
      # this will also append the output to the exception
      raise "Exit status of command '#{command}' was #{exit_status} instead of 0. \n#{result}"
    end
  end
  result
rescue => ex
  raise ex
ensure
  Encoding.default_external = previous_encoding.first
  Encoding.default_internal = previous_encoding.last
end

def self.verify_gem!(gem_name)

this will *not* 'require' the gem
will make sure a gem is installed. If it's not an appropriate error message is shown
def self.verify_gem!(gem_name)
  begin
    Gem::Specification.find_by_name(gem_name)
  rescue Gem::LoadError
    print_gem_error "Could not find gem '#{gem_name}'"
    print_gem_error ""
    print_gem_error "If you installed fastlane using `sudo gem install fastlane` run"
    print_gem_error "`sudo gem install #{gem_name}` to install the missing gem"
    print_gem_error ""
    print_gem_error "If you use a Gemfile add this to your Gemfile:"
    print_gem_error "gem '#{gem_name}'"
    print_gem_error "and run `bundle install`"
    raise "You have to install the `#{gem_name}`".red unless Helper.is_test?
  end
  true
end