nanci.drew
nanci.drew

Reputation: 145

Is there currently a way to extract the output of a fastlane action within the fastlane actions?

I am using a third party fastlane plugin and it contains an action that will display vital information I need to capture, such as a link.

I am trying to find an elegant way to capture these logs within the fastlane actions, I am trying to avoid using a shell command but if it's the only way, then I suppose I have no choice.

I need this link as it is a unique and random link that contains resources I'd like to download.

I have tried redirecting stdout to no avail since fastlane uses their own logger (usually UI.message) and was about to submit a feature request to fastlane but figured perhaps someone else has ran into this and managed to get past it.

Is there anyway to redirect this type of log and capture it?

Here is the fastlane source code around UI: https://github.com/fastlane/fastlane/tree/master/fastlane_core/lib/fastlane_core/ui

And here is one of the ways I tried redirecting output: Capturing logger output inside a method

Any help / advice / resources would be appreciated!

Upvotes: 7

Views: 13135

Answers (4)

KrauseFx
KrauseFx

Reputation: 11751

The way fastlane is built allows you to replace the UI layer with your own layer. You can find a sample implementation on the fastlane.ci GitHub repo https://github.com/fastlane/ci/blob/master/app/features/build_runner/fastlane_build_runner_helpers/fastlane_ci_output.rb

The way you would then set this up is the following

ci_output = FastlaneCI::FastlaneCIOutput.new(
  each_line_block: proc do |raw_row|
    puts "new line here, access raw_row"
  end
)

FastlaneCore::UI.ui_object = ci_output

Upvotes: 1

Gravitoid
Gravitoid

Reputation: 1392

I am not sure if this is exactly the answer the OP wanted but there does seem to be a way to get the result of the action as a json string. I'm adding this here because I found this question while searching for my issue, and it wasn't readily apparent in the fastlane docs that this is possible.

Inside my Fastlane file I used these actions:

  packageName = "com.example.mine"

  versionName = google_play_track_release_names(
    package_name: packageName,
    track: "production"
  )

  versionCode = google_play_track_version_codes(
    package_name: packageName,
    track: "production"
  )

  UI.message "Package Info: #{packageName}, #{versionName} #{versionCode}"

The output looked like this

Package Info: com.example.mine, ["4.2.0"] [2027]

I also suppressed all the screen output by piping the command through grep to get just the line I wanted. (I couldn't find a parameter or option to do that either.)

fastlane android get_version | grep "Package Info

Hopefully this helps another noobie like me!

Upvotes: 8

nanci.drew
nanci.drew

Reputation: 145

I forgot to update this, but in the end I solved it as such:

module Fastlane
  module Helper
    class UtilHelper
      # Redirects standard output and standard error to a file
      # (currently only way we know how to capture fastlane ui messages)
      def self.redirect_stdout_to_file(filename)
        original_stdout = $stdout.clone
        original_stderr = $stderr.clone
        $stderr.reopen File.new(filename, 'w')
        $stdout.reopen File.new(filename, 'w')
        yield
      ensure
        $stdout.reopen original_stdout
        $stderr.reopen original_stderr
      end

    end
  end
end

and I utilized it like this:

temp_file = 'testlab.log'
UtilHelper.redirect_stdout_to_file(temp_file) { upload_xctestrun() }

What upload_xctrestrun does is irrelevant, just know that it is a function from a fastlane plugin which outputs messages using the fastlane UI object like so:

UI.message("Some fastlane decorated message here")

Hope this helps anyone :)

Upvotes: 3

Brad Pitcher
Brad Pitcher

Reputation: 1785

I don't know if this will help you, but I managed to capture fastlane stdout to a variable to get what I wanted (in my case to obtain the common name of the iPhone development certificate) using this simple method

def with_captured_stdout
  original_stdout = $stdout
  $stdout = StringIO.new
  yield
  $stdout.string
ensure
  $stdout = original_stdout
end

lane :test do |options|
  match_dev = with_captured_stdout { match(type: 'development') }
  puts match_dev
  @dev_index = match_dev.index('iPhone Developer')
  ENV['DEV_CODE_SIGN_ID'] = match_dev[@dev_index..match_dev.index(')', @dev_index)]
  # ENV['DEV_CODE_SIGN_ID'] = "iPhone Developer: Test Name (XXXXXXXX)"
end

From https://stackoverflow.com/a/22777806/1034194

Upvotes: 2

Related Questions