class FastlaneCore::UpdateChecker
Verifies, the user runs the latest version of this gem
Constants
- UPDATE_URL
This web service is fully open source: github.com/fastlane/refresher
Public Class Methods
(optional) Returns the app identifier for the current tool supply and screengrab use different param names and env variable patterns so we have to special case here example:
supply --skip_upload_screenshots -a beta -p com.test.app should return com.test.app screengrab -a com.test.app should return com.test.app
# File lib/fastlane_core/update_checker/update_checker.rb, line 144 def self.android_app_identifier(args, gem_name) app_identifier = nil # args example: ["-a", "com.krausefx.app"] args.each_with_index do |current, index| if android_app_identifier_arg?(gem_name, current) app_identifier = args[index + 1] if args.count > index break end end app_identifier ||= ENV["SUPPLY_PACKAGE_NAME"] if FastlaneCore::Env.truthy?("SUPPLY_PACKAGE_NAME") app_identifier ||= ENV["SCREENGRAB_APP_PACKAGE_NAME"] if FastlaneCore::Env.truthy?("SCREENGRAB_APP_PACKAGE_NAME") app_identifier ||= CredentialsManager::AppfileConfig.try_fetch_value(:package_name) # Add Android prefix to prevent collisions if there is an iOS app with the same identifier app_identifier ? "android_project_#{app_identifier}" : nil rescue nil # we don't want this method to cause a crash end
# File lib/fastlane_core/update_checker/update_checker.rb, line 164 def self.android_app_identifier_arg?(gem_name, arg) return arg == "--package_name" || arg == "--app_package_name" || (arg == '-p' && gem_name == 'supply') || (arg == '-a' && gem_name == 'screengrab') end
# File lib/fastlane_core/update_checker/update_checker.rb, line 101 def self.fetch_latest(url) JSON.parse(Excon.post(url).body).fetch("version", nil) end
# File lib/fastlane_core/update_checker/update_checker.rb, line 105 def self.finished_running(gem_name) return if ENV["FASTLANE_OPT_OUT_USAGE"] time = (Time.now - @start_time).to_i url = UPDATE_URL + "time/#{gem_name}" url += "?time=#{time}" url += "&ci=1" if Helper.ci? url += "&gem=1" if Helper.rubygems? url += "&bundler=1" if Helper.bundler? url += "&mac_app=1" if Helper.mac_app? url += "&standalone=1" if Helper.contained_fastlane? url += "&homebrew=1" if Helper.homebrew? Excon.post(url) end
Generate the URL on the main thread (since we're switching directory)
# File lib/fastlane_core/update_checker/update_checker.rb, line 88 def self.generate_fetch_url(gem_name) url = UPDATE_URL + gem_name params = {} params["ci"] = "1" if Helper.is_ci? project_hash = p_hash(ARGV, gem_name) params["p_hash"] = project_hash if project_hash params["platform"] = @platform if @platform # this has to be called after `p_hash` url += "?" + URI.encode_www_form(params) if params.count > 0 return url end
(optional) Returns the app identifier for the current tool
# File lib/fastlane_core/update_checker/update_checker.rb, line 122 def self.ios_app_identifier(args) # args example: ["-a", "com.krausefx.app", "--team_id", "5AA97AAHK2"] args.each_with_index do |current, index| if current == "-a" || current == "--app_identifier" return args[index + 1] if args.count > index end end ["FASTLANE", "DELIVER", "PILOT", "PRODUCE", "PEM", "SIGH", "SNAPSHOT", "MATCH"].each do |current| return ENV["#{current}_APP_IDENTIFIER"] if FastlaneCore::Env.truthy?("#{current}_APP_IDENTIFIER") end return CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue nil # we don't want this method to cause a crash end
To not count the same projects multiple time for the number of launches More information: github.com/fastlane/refresher Use the `FASTLANE_OPT_OUT_USAGE` variable to opt out The resulting value is e.g. ce12f8371df11ef6097a83bdf2303e4357d6f5040acc4f76019489fa5deeae0d
# File lib/fastlane_core/update_checker/update_checker.rb, line 175 def self.p_hash(args, gem_name) return nil if FastlaneCore::Env.truthy?("FASTLANE_OPT_OUT_USAGE") require 'credentials_manager' # check if this is an android project first because some of the same params exist for iOS and Android tools app_identifier = android_app_identifier(args, gem_name) @platform = nil # since have a state in-between runs if app_identifier @platform = :android else app_identifier = ios_app_identifier(args) @platform = :ios if app_identifier end if app_identifier return Digest::SHA256.hexdigest("p#{app_identifier}fastlan3_SAlt") # hashed + salted the bundle identifier end return nil rescue return nil end
# File lib/fastlane_core/update_checker/update_checker.rb, line 27 def self.server_results @results ||= {} end
Show a message to the user to update to a new version of fastlane (or a sub-gem) Use this method, as this will detect the current Ruby environment and show an appropriate message to the user
# File lib/fastlane_core/update_checker/update_checker.rb, line 53 def self.show_update_message(gem_name, current_version) available = server_results[gem_name] puts "" puts '#######################################################################'.green if available puts "# #{gem_name} #{available} is available. You are on #{current_version}.".green else puts "# An update for #{gem_name} is available. You are on #{current_version}.".green end puts "# It is recommended to use the latest version.".green puts "# Please update using `#{self.update_command(gem_name: gem_name)}`.".green puts "# To see what's new, open https://github.com/fastlane/#{gem_name}/releases.".green if FastlaneCore::Env.truthy?("FASTLANE_HIDE_CHANGELOG") if !Helper.bundler? && !Helper.contained_fastlane? && Random.rand(5) == 1 # We want to show this message from time to time, if the user doesn't use bundler, nor bundled fastlane puts '#######################################################################'.green puts "# Run `sudo gem cleanup` from time to time to speed up fastlane".green end puts '#######################################################################'.green Changelog.show_changes(gem_name, current_version) unless FastlaneCore::Env.truthy?("FASTLANE_HIDE_CHANGELOG") end
# File lib/fastlane_core/update_checker/update_checker.rb, line 36 def self.show_update_status(gem_name, current_version) fork do begin finished_running(gem_name) rescue # we don't want to show a stack trace if something goes wrong end end if update_available?(gem_name, current_version) show_update_message(gem_name, current_version) end end
# File lib/fastlane_core/update_checker/update_checker.rb, line 12 def self.start_looking_for_update(gem_name) return if Helper.is_test? return if FastlaneCore::Env.truthy?("FASTLANE_SKIP_UPDATE_CHECK") @start_time = Time.now url = generate_fetch_url(gem_name) Thread.new do begin server_results[gem_name] = fetch_latest(url) rescue end end end
# File lib/fastlane_core/update_checker/update_checker.rb, line 31 def self.update_available?(gem_name, current_version) latest = server_results[gem_name] return (latest and Gem::Version.new(latest) > Gem::Version.new(current_version)) end
The command that the user should use to update their mac
# File lib/fastlane_core/update_checker/update_checker.rb, line 77 def self.update_command(gem_name: "fastlane") if Helper.bundler? "bundle update #{gem_name.downcase}" elsif Helper.contained_fastlane? "fastlane update_fastlane" else "sudo gem update #{gem_name.downcase}" end end