fastlane 2.62.0.beta.20171016010004 → 2.62.0.beta.20171017010003
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/fastlane/lib/fastlane/fast_file.rb +32 -12
- data/fastlane/lib/fastlane/lane_manager.rb +2 -2
- data/fastlane/lib/fastlane/runner.rb +22 -15
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane_core/lib/fastlane_core.rb +18 -0
- data/fastlane_core/lib/fastlane_core/analytics/action_completion_context.rb +29 -0
- data/fastlane_core/lib/fastlane_core/analytics/action_launch_context.rb +34 -0
- data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +50 -0
- data/fastlane_core/lib/fastlane_core/analytics/analytics_ingester_client.rb +45 -0
- data/fastlane_core/lib/fastlane_core/analytics/analytics_session.rb +201 -0
- data/fastlane_core/lib/fastlane_core/analytics/app_identifier_guesser.rb +64 -0
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +20 -7
- data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +3 -57
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f14604abb941543613b3505e11bf099dccccf4ab
|
4
|
+
data.tar.gz: f62ef3b052d856ec84948d52521321455fedb5be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03f1513c1a01cc9a51aeb3642907bc93c868f8e1764cee102046f1b4dee88489e6a86ea0e076d8203794d916bc612a31b2198ddd5ffca9a0d88710df27742481
|
7
|
+
data.tar.gz: 0318818369814716e8b1f4403276ce4b4d7673e49a2b6ae2aaddda43638ddf89a35d5a61cab5b1656e6e118ebbe1d9e3a8c320d2e830eee39eff0141f4118a00
|
@@ -150,10 +150,6 @@ module Fastlane
|
|
150
150
|
# @!group Other things
|
151
151
|
#####################################################
|
152
152
|
|
153
|
-
def collector
|
154
|
-
runner.collector
|
155
|
-
end
|
156
|
-
|
157
153
|
# Is the given key a platform block or a lane?
|
158
154
|
def is_platform_block?(key)
|
159
155
|
UI.crash!('No key given') unless key
|
@@ -217,8 +213,13 @@ module Fastlane
|
|
217
213
|
actions_path = File.join(File.expand_path("..", path), 'actions')
|
218
214
|
Fastlane::Actions.load_external_actions(actions_path) if File.directory?(actions_path)
|
219
215
|
|
220
|
-
|
221
|
-
|
216
|
+
action_launched('import')
|
217
|
+
|
218
|
+
return_value = parse(File.read(path), path)
|
219
|
+
|
220
|
+
action_completed('import', status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
221
|
+
|
222
|
+
return return_value
|
222
223
|
end
|
223
224
|
|
224
225
|
# @param url [String] The git URL to clone the repository from
|
@@ -230,7 +231,7 @@ module Fastlane
|
|
230
231
|
Actions.execute_action('import_from_git') do
|
231
232
|
require 'tmpdir'
|
232
233
|
|
233
|
-
|
234
|
+
action_launched('import_from_git')
|
234
235
|
|
235
236
|
# Checkout the repo
|
236
237
|
repo_name = url.split("/").last
|
@@ -258,7 +259,11 @@ module Fastlane
|
|
258
259
|
# We don't care about a failure here, as local actions are optional
|
259
260
|
end
|
260
261
|
|
261
|
-
import(File.join(clone_folder, path))
|
262
|
+
return_value = import(File.join(clone_folder, path))
|
263
|
+
|
264
|
+
action_completed('import_from_git', status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
265
|
+
|
266
|
+
return return_value
|
262
267
|
end
|
263
268
|
end
|
264
269
|
end
|
@@ -272,21 +277,36 @@ module Fastlane
|
|
272
277
|
# Overwrite this, since there is already a 'say' method defined in the Ruby standard library
|
273
278
|
value ||= yield
|
274
279
|
Actions.execute_action('say') do
|
275
|
-
|
276
|
-
Fastlane::Actions::SayAction.run([value])
|
280
|
+
action_launched('say')
|
281
|
+
return_value = Fastlane::Actions::SayAction.run([value])
|
282
|
+
action_completed('say', status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
283
|
+
return return_value
|
277
284
|
end
|
278
285
|
end
|
279
286
|
|
280
287
|
def puts(value)
|
281
288
|
# Overwrite this, since there is already a 'puts' method defined in the Ruby standard library
|
282
289
|
value ||= yield if block_given?
|
283
|
-
|
284
|
-
|
290
|
+
|
291
|
+
action_launched('puts')
|
292
|
+
return_value = Fastlane::Actions::PutsAction.run([value])
|
293
|
+
action_completed('puts', status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
294
|
+
return return_value
|
285
295
|
end
|
286
296
|
|
287
297
|
def test(params = {})
|
288
298
|
# Overwrite this, since there is already a 'test' method defined in the Ruby standard library
|
289
299
|
self.runner.try_switch_to_lane(:test, [params])
|
290
300
|
end
|
301
|
+
|
302
|
+
def action_launched(action_name)
|
303
|
+
action_launch_context = FastlaneCore::ActionLaunchContext.context_for_action_name(action_name, args: ARGV)
|
304
|
+
FastlaneCore.session.action_launched(launch_context: action_launch_context)
|
305
|
+
end
|
306
|
+
|
307
|
+
def action_completed(action_name, status: nil)
|
308
|
+
completion_context = FastlaneCore::ActionCompletionContext.context_for_action_name(action_name, args: ARGV, status: status)
|
309
|
+
FastlaneCore.session.action_completed(completion_context: completion_context)
|
310
|
+
end
|
291
311
|
end
|
292
312
|
end
|
@@ -38,6 +38,8 @@ module Fastlane
|
|
38
38
|
|
39
39
|
platform, lane = choose_lane(ff, platform) unless lane
|
40
40
|
|
41
|
+
FastlaneCore.session.is_fastfile = true
|
42
|
+
|
41
43
|
# xcodeproj has a bug in certain versions that causes it to change directories
|
42
44
|
# and not return to the original working directory
|
43
45
|
# https://github.com/CocoaPods/Xcodeproj/issues/426
|
@@ -76,8 +78,6 @@ module Fastlane
|
|
76
78
|
|
77
79
|
# All the finishing up that needs to be done
|
78
80
|
def self.finish_fastlane(ff, duration, error)
|
79
|
-
ff.runner.did_finish
|
80
|
-
|
81
81
|
# Finished with all the lanes
|
82
82
|
Fastlane::JUnitGenerator.generate(Fastlane::Actions.executed_actions)
|
83
83
|
print_table(Fastlane::Actions.executed_actions)
|
@@ -197,7 +197,10 @@ module Fastlane
|
|
197
197
|
|
198
198
|
# Actually switch lane now
|
199
199
|
self.current_lane = new_lane
|
200
|
-
|
200
|
+
|
201
|
+
launch_context = FastlaneCore::ActionLaunchContext.context_for_action_name('lane_switch', args: ARGV)
|
202
|
+
FastlaneCore.session.action_launched(launch_context: launch_context)
|
203
|
+
|
201
204
|
result = block.call(parameters.first || {}) # to always pass a hash
|
202
205
|
self.current_lane = original_lane
|
203
206
|
|
@@ -218,11 +221,12 @@ module Fastlane
|
|
218
221
|
custom_dir ||= ".."
|
219
222
|
end
|
220
223
|
|
221
|
-
collector.did_launch_action(method_sym)
|
222
|
-
|
223
224
|
verify_supported_os(method_sym, class_ref)
|
224
225
|
|
225
226
|
begin
|
227
|
+
launch_context = FastlaneCore::ActionLaunchContext.context_for_action_name(method_sym.to_s, args: ARGV)
|
228
|
+
FastlaneCore.session.action_launched(launch_context: launch_context)
|
229
|
+
|
226
230
|
Dir.chdir(custom_dir) do # go up from the fastlane folder, to the project folder
|
227
231
|
# If another action is calling this action, we shouldn't show it in the summary
|
228
232
|
# (see https://github.com/fastlane/fastlane/issues/4546)
|
@@ -249,7 +253,11 @@ module Fastlane
|
|
249
253
|
end
|
250
254
|
|
251
255
|
class_ref.runner = self # needed to call another action form an action
|
252
|
-
class_ref.run(arguments)
|
256
|
+
return_value = class_ref.run(arguments)
|
257
|
+
|
258
|
+
action_completed(method_sym.to_s, status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
259
|
+
|
260
|
+
return return_value
|
253
261
|
end
|
254
262
|
end
|
255
263
|
rescue Interrupt => e
|
@@ -258,17 +266,25 @@ module Fastlane
|
|
258
266
|
raise e
|
259
267
|
rescue FastlaneCore::Interface::FastlaneError => e # user_error!
|
260
268
|
FastlaneCore::CrashReporter.report_crash(exception: e)
|
261
|
-
|
269
|
+
action_completed(method_sym.to_s, status: FastlaneCore::ActionCompletionStatus::USER_ERROR, exception: e)
|
262
270
|
raise e
|
263
271
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
264
272
|
# high chance this is actually FastlaneCore::Interface::FastlaneCrash, but can be anything else
|
265
273
|
# Catches all exceptions, since some plugins might use system exits to get out
|
266
274
|
FastlaneCore::CrashReporter.report_crash(exception: e)
|
267
|
-
|
275
|
+
|
276
|
+
action_completed(method_sym.to_s, status: FastlaneCore::ActionCompletionStatus::FAILED, exception: e)
|
268
277
|
raise e
|
269
278
|
end
|
270
279
|
end
|
271
280
|
|
281
|
+
def action_completed(action_name, status: nil, exception: nil)
|
282
|
+
if exception.nil? || exception.fastlane_should_report_metrics?
|
283
|
+
action_completion_context = FastlaneCore::ActionCompletionContext.context_for_action_name(action_name, args: ARGV, status: status)
|
284
|
+
FastlaneCore.session.action_completed(completion_context: action_completion_context)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
272
288
|
def execute_flow_block(block, current_platform, lane, parameters)
|
273
289
|
# Call the platform specific block and default back to the general one
|
274
290
|
block[current_platform].call(lane, parameters) if block[current_platform] && current_platform
|
@@ -287,15 +303,6 @@ module Fastlane
|
|
287
303
|
end
|
288
304
|
end
|
289
305
|
|
290
|
-
def collector
|
291
|
-
@collector ||= ActionCollector.new
|
292
|
-
end
|
293
|
-
|
294
|
-
# Fastfile was finished executing
|
295
|
-
def did_finish
|
296
|
-
collector.did_finish
|
297
|
-
end
|
298
|
-
|
299
306
|
# Called internally to setup the runner object
|
300
307
|
#
|
301
308
|
|
@@ -40,6 +40,11 @@ require 'fastlane_core/ui/errors/fastlane_crash'
|
|
40
40
|
require 'fastlane_core/ui/errors/fastlane_shell_error'
|
41
41
|
require 'fastlane_core/ui/errors/fastlane_common_error'
|
42
42
|
require 'fastlane_core/test_parser'
|
43
|
+
require 'fastlane_core/analytics/action_completion_context'
|
44
|
+
require 'fastlane_core/analytics/action_launch_context'
|
45
|
+
require 'fastlane_core/analytics/analytics_event_builder'
|
46
|
+
require 'fastlane_core/analytics/analytics_ingester_client'
|
47
|
+
require 'fastlane_core/analytics/analytics_session'
|
43
48
|
|
44
49
|
# Third Party code
|
45
50
|
require 'colored'
|
@@ -51,6 +56,19 @@ require 'fastlane_core/ui/fastlane_runner' # monkey patch
|
|
51
56
|
module FastlaneCore
|
52
57
|
ROOT = Pathname.new(File.expand_path('../..', __FILE__))
|
53
58
|
|
59
|
+
# Session is used to report usage metrics.
|
60
|
+
# If you opt out, we will not send anything.
|
61
|
+
# You can confirm this by observing how we use the environment variable: FASTLANE_OPT_OUT_USAGE
|
62
|
+
# Specifically, in AnalyticsSession.finalize_session
|
63
|
+
# Learn more at https://github.com/fastlane/fastlane#metrics
|
64
|
+
def self.session
|
65
|
+
@session ||= AnalyticsSession.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.reset_session
|
69
|
+
@session = nil
|
70
|
+
end
|
71
|
+
|
54
72
|
# A directory that's being used to user-wide fastlane configs
|
55
73
|
# This directory is also used for the bundled fastlane
|
56
74
|
# Since we don't want to access FastlaneCore from spaceship
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module FastlaneCore
|
2
|
+
class ActionCompletionStatus
|
3
|
+
SUCCESS = 'success'
|
4
|
+
FAILED = 'failed' # fastlane crashes unrelated to user_error!
|
5
|
+
USER_ERROR = 'user_error' # Anytime a user_error! is triggered
|
6
|
+
INTERRUPTED = 'interrupted'
|
7
|
+
end
|
8
|
+
|
9
|
+
class ActionCompletionContext
|
10
|
+
attr_accessor :p_hash
|
11
|
+
attr_accessor :action_name
|
12
|
+
attr_accessor :status
|
13
|
+
|
14
|
+
def initialize(p_hash: nil, action_name: nil, status: nil)
|
15
|
+
@p_hash = p_hash
|
16
|
+
@action_name = action_name
|
17
|
+
@status = status
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.context_for_action_name(action_name, args: nil, status: nil)
|
21
|
+
app_id_guesser = FastlaneCore::AppIdentifierGuesser.new(args: args)
|
22
|
+
return self.new(
|
23
|
+
action_name: action_name,
|
24
|
+
p_hash: app_id_guesser.p_hash,
|
25
|
+
status: status
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'fastlane_core/helper'
|
2
|
+
|
3
|
+
module FastlaneCore
|
4
|
+
class ActionLaunchContext
|
5
|
+
UNKNOWN_P_HASH = 'unknown'
|
6
|
+
|
7
|
+
attr_accessor :action_name
|
8
|
+
attr_accessor :p_hash
|
9
|
+
attr_accessor :platform
|
10
|
+
|
11
|
+
def initialize(action_name: nil, p_hash: UNKNOWN_P_HASH, platform: nil)
|
12
|
+
@action_name = action_name
|
13
|
+
@p_hash = p_hash
|
14
|
+
@platform = platform
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.context_for_action_name(action_name, args: nil)
|
18
|
+
app_id_guesser = FastlaneCore::AppIdentifierGuesser.new(args: args)
|
19
|
+
return self.new(
|
20
|
+
action_name: action_name,
|
21
|
+
p_hash: app_id_guesser.p_hash,
|
22
|
+
platform: app_id_guesser.platform
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_tool_version
|
27
|
+
if platform == :android
|
28
|
+
return 'android'
|
29
|
+
else
|
30
|
+
return "Xcode #{Helper.xcode_version}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module FastlaneCore
|
2
|
+
class AnalyticsEventBuilder
|
3
|
+
attr_accessor :base_hash
|
4
|
+
attr_accessor :action_name
|
5
|
+
|
6
|
+
def initialize(oauth_app_name: nil, p_hash: nil, session_id: nil, action_name: nil, timestamp_millis: (Time.now.to_f * 1000).to_i)
|
7
|
+
@action_name = action_name
|
8
|
+
@base_hash = {
|
9
|
+
event_source: {
|
10
|
+
oauth_app_name: oauth_app_name,
|
11
|
+
product: 'fastlane'
|
12
|
+
},
|
13
|
+
actor: {
|
14
|
+
name: p_hash,
|
15
|
+
detail: session_id
|
16
|
+
},
|
17
|
+
millis_since_epoch: timestamp_millis,
|
18
|
+
version: 1
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def launched_event(primary_target_hash: nil, secondary_target_hash: nil)
|
23
|
+
return new_event(
|
24
|
+
stage: 'launched',
|
25
|
+
primary_target_hash: primary_target_hash,
|
26
|
+
secondary_target_hash: secondary_target_hash
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def completed_event(primary_target_hash: nil, secondary_target_hash: nil)
|
31
|
+
return new_event(
|
32
|
+
stage: 'completed',
|
33
|
+
primary_target_hash: primary_target_hash,
|
34
|
+
secondary_target_hash: secondary_target_hash
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def new_event(stage: nil, primary_target_hash: nil, secondary_target_hash: nil)
|
39
|
+
raise 'Need at least a primary_target_hash' if primary_target_hash.nil?
|
40
|
+
event = base_hash.dup
|
41
|
+
event[:action] = {
|
42
|
+
name: stage,
|
43
|
+
detail: action_name
|
44
|
+
}
|
45
|
+
event[:primary_target] = primary_target_hash
|
46
|
+
event[:secondary_target] = secondary_target_hash unless secondary_target_hash.nil?
|
47
|
+
return event
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module FastlaneCore
|
2
|
+
class AnalyticsIngesterClient
|
3
|
+
def post_events(events)
|
4
|
+
unless Helper.test?
|
5
|
+
fork do
|
6
|
+
send_request(json: { analytics: events }.to_json)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
return true
|
10
|
+
end
|
11
|
+
|
12
|
+
def send_request(json: nil, retries: 2)
|
13
|
+
post_request(body: json)
|
14
|
+
rescue
|
15
|
+
retries -= 1
|
16
|
+
retry if retries >= 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def post_request(body: nil)
|
20
|
+
if ENV['METRICS_DEBUG']
|
21
|
+
write_json(body)
|
22
|
+
end
|
23
|
+
url = ENV["FASTLANE_METRICS_URL"] || "https://fastlane-metrics.fabric.io"
|
24
|
+
|
25
|
+
require 'faraday'
|
26
|
+
connection = Faraday.new(url) do |conn|
|
27
|
+
conn.adapter Faraday.default_adapter
|
28
|
+
if ENV['METRICS_DEBUG']
|
29
|
+
conn.proxy = "https://127.0.0.1:8888"
|
30
|
+
conn.ssl[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
31
|
+
end
|
32
|
+
end
|
33
|
+
connection.post do |req|
|
34
|
+
req.url '/public'
|
35
|
+
req.headers['Content-Type'] = 'application/json'
|
36
|
+
req.body = body
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# This method is only for debugging purposes
|
41
|
+
def write_json(body)
|
42
|
+
File.write("#{ENV['HOME']}/Desktop/mock_analytics-#{Time.now.to_i}.json", body)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'fastlane_core/analytics/analytics_ingester_client'
|
2
|
+
|
3
|
+
module FastlaneCore
|
4
|
+
class AnalyticsSession
|
5
|
+
attr_accessor :session_id
|
6
|
+
attr_accessor :client
|
7
|
+
attr_accessor :events
|
8
|
+
attr_accessor :fastfile_id
|
9
|
+
attr_accessor :is_fastfile
|
10
|
+
alias fastfile? is_fastfile
|
11
|
+
|
12
|
+
# make this a method so that we can override it in monkey patches
|
13
|
+
def oauth_app_name
|
14
|
+
return 'fastlane_v2'
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(analytics_ingester_client: AnalyticsIngesterClient.new)
|
18
|
+
require 'securerandom'
|
19
|
+
@session_id = SecureRandom.uuid
|
20
|
+
@client = analytics_ingester_client
|
21
|
+
@events = []
|
22
|
+
@is_fastfile = false
|
23
|
+
end
|
24
|
+
|
25
|
+
def backfill_p_hashes(p_hash: nil)
|
26
|
+
return if p_hash.nil? || p_hash == ActionLaunchContext::UNKNOWN_P_HASH || @events.count == 0
|
27
|
+
@events.reverse_each do |event|
|
28
|
+
# event[:actor][:name] is the field in which we store the p_hash
|
29
|
+
# to be sent to analytics ingester.
|
30
|
+
# If they are nil, we want to fill them in until we reach
|
31
|
+
# an event that already has a p_hash.
|
32
|
+
if event[:actor][:name].nil? || event[:actor][:name] == ActionLaunchContext::UNKNOWN_P_HASH
|
33
|
+
event[:actor][:name] = p_hash
|
34
|
+
else
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def action_launched(launch_context: nil)
|
41
|
+
backfill_p_hashes(p_hash: launch_context.p_hash)
|
42
|
+
|
43
|
+
builder = AnalyticsEventBuilder.new(
|
44
|
+
oauth_app_name: oauth_app_name,
|
45
|
+
p_hash: launch_context.p_hash,
|
46
|
+
session_id: session_id,
|
47
|
+
action_name: launch_context.action_name
|
48
|
+
)
|
49
|
+
|
50
|
+
@events << builder.launched_event(
|
51
|
+
primary_target_hash: {
|
52
|
+
name: 'fastlane_version',
|
53
|
+
detail: fastlane_version
|
54
|
+
}
|
55
|
+
)
|
56
|
+
|
57
|
+
@events << builder.launched_event(
|
58
|
+
primary_target_hash: {
|
59
|
+
name: 'install_method',
|
60
|
+
detail: install_method
|
61
|
+
}
|
62
|
+
)
|
63
|
+
|
64
|
+
@events << builder.launched_event(
|
65
|
+
primary_target_hash: {
|
66
|
+
name: 'operating_system',
|
67
|
+
detail: operating_system
|
68
|
+
},
|
69
|
+
secondary_target_hash: {
|
70
|
+
name: 'version',
|
71
|
+
detail: operating_system_version
|
72
|
+
}
|
73
|
+
)
|
74
|
+
|
75
|
+
@events << builder.launched_event(
|
76
|
+
primary_target_hash: {
|
77
|
+
name: 'build_tool_version',
|
78
|
+
detail: launch_context.build_tool_version
|
79
|
+
}
|
80
|
+
)
|
81
|
+
|
82
|
+
@events << builder.launched_event(
|
83
|
+
primary_target_hash: {
|
84
|
+
name: 'ci',
|
85
|
+
detail: ci?.to_s
|
86
|
+
}
|
87
|
+
)
|
88
|
+
|
89
|
+
@events << builder.launched_event(
|
90
|
+
primary_target_hash: {
|
91
|
+
name: 'fastfile',
|
92
|
+
detail: fastfile?.to_s
|
93
|
+
},
|
94
|
+
secondary_target_hash: {
|
95
|
+
name: 'fastfile_id',
|
96
|
+
detail: fastfile_id.to_s
|
97
|
+
}
|
98
|
+
)
|
99
|
+
|
100
|
+
@events << builder.launched_event(
|
101
|
+
primary_target_hash: {
|
102
|
+
name: 'platform',
|
103
|
+
detail: launch_context.platform.to_s
|
104
|
+
}
|
105
|
+
)
|
106
|
+
|
107
|
+
@events << builder.launched_event(
|
108
|
+
primary_target_hash: {
|
109
|
+
name: 'ruby_version',
|
110
|
+
detail: ruby_version
|
111
|
+
}
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
def is_fastfile=(value)
|
116
|
+
if value
|
117
|
+
# If true, update all of the events to reflect
|
118
|
+
# that the execution is running within a Fastfile context.
|
119
|
+
# We don't want to update if this is false because once we
|
120
|
+
# detect a true value, that is the one to be trusted
|
121
|
+
@events.reverse_each do |event|
|
122
|
+
event[:primary_target][:name] == 'fastfile' ? event[:primary_target][:detail] = value.to_s : next
|
123
|
+
end
|
124
|
+
end
|
125
|
+
@is_fastfile = value
|
126
|
+
end
|
127
|
+
|
128
|
+
def action_completed(completion_context: nil)
|
129
|
+
backfill_p_hashes(p_hash: completion_context.p_hash)
|
130
|
+
|
131
|
+
builder = AnalyticsEventBuilder.new(
|
132
|
+
oauth_app_name: oauth_app_name,
|
133
|
+
p_hash: completion_context.p_hash,
|
134
|
+
session_id: session_id,
|
135
|
+
action_name: completion_context.action_name
|
136
|
+
)
|
137
|
+
|
138
|
+
@events << builder.completed_event(
|
139
|
+
primary_target_hash: {
|
140
|
+
name: 'status',
|
141
|
+
detail: completion_context.status
|
142
|
+
}
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
def finalize_session
|
147
|
+
# If our users want to opt out of usage metrics, don't post the events.
|
148
|
+
# Learn more at https://github.com/fastlane/fastlane#metrics
|
149
|
+
return if FastlaneCore::Env.truthy?("FASTLANE_OPT_OUT_USAGE")
|
150
|
+
|
151
|
+
client.post_events(@events)
|
152
|
+
end
|
153
|
+
|
154
|
+
def fastlane_version
|
155
|
+
return Fastlane::VERSION
|
156
|
+
end
|
157
|
+
|
158
|
+
def ruby_version
|
159
|
+
patch_level = RUBY_PATCHLEVEL == 0 ? nil : "p#{RUBY_PATCHLEVEL}"
|
160
|
+
return "#{RUBY_VERSION}#{patch_level}"
|
161
|
+
end
|
162
|
+
|
163
|
+
def operating_system
|
164
|
+
return "macOS" if RUBY_PLATFORM.downcase.include?("darwin")
|
165
|
+
return "Windows" if RUBY_PLATFORM.downcase.include?("mswin")
|
166
|
+
return "Linux" if RUBY_PLATFORM.downcase.include?("linux")
|
167
|
+
return "Unknown"
|
168
|
+
end
|
169
|
+
|
170
|
+
def install_method
|
171
|
+
if Helper.rubygems?
|
172
|
+
return 'gem'
|
173
|
+
elsif Helper.bundler?
|
174
|
+
return 'bundler'
|
175
|
+
elsif Helper.mac_app?
|
176
|
+
return 'mac_app'
|
177
|
+
elsif Helper.contained_fastlane?
|
178
|
+
return 'standalone'
|
179
|
+
elsif Helper.homebrew?
|
180
|
+
return 'homebrew'
|
181
|
+
else
|
182
|
+
return 'unknown'
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def ci?
|
187
|
+
return Helper.is_ci?
|
188
|
+
end
|
189
|
+
|
190
|
+
def operating_system_version
|
191
|
+
os = self.operating_system
|
192
|
+
case os
|
193
|
+
when "macOS"
|
194
|
+
return `SW_VERS -productVersion`.strip
|
195
|
+
else
|
196
|
+
# Need to test in Windows and Linux... not sure this is enough
|
197
|
+
return Gem::Platform.local.version
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fastlane_core/android_package_name_guesser'
|
2
|
+
require 'fastlane_core/ios_app_identifier_guesser'
|
3
|
+
|
4
|
+
module FastlaneCore
|
5
|
+
class AppIdentifierGuesser
|
6
|
+
attr_accessor :args
|
7
|
+
attr_accessor :gem_name
|
8
|
+
attr_accessor :platform
|
9
|
+
attr_accessor :p_hash
|
10
|
+
attr_accessor :app_id
|
11
|
+
|
12
|
+
def initialize(args: nil, gem_name: 'fastlane')
|
13
|
+
@args = args
|
14
|
+
@gem_name = gem_name
|
15
|
+
|
16
|
+
@app_id = android_app_identifier(args, gem_name)
|
17
|
+
@platform = nil # since have a state in-between runs
|
18
|
+
if @app_id
|
19
|
+
@platform = :android
|
20
|
+
else
|
21
|
+
@app_id = ios_app_identifier(args)
|
22
|
+
@platform = :ios if @app_id
|
23
|
+
end
|
24
|
+
|
25
|
+
@p_hash = generate_p_hash(@app_id)
|
26
|
+
end
|
27
|
+
|
28
|
+
# To not count the same projects multiple time for the number of launches
|
29
|
+
# Learn more at https://github.com/fastlane/fastlane#metrics
|
30
|
+
# Use the `FASTLANE_OPT_OUT_USAGE` variable to opt out
|
31
|
+
# The resulting value is e.g. ce12f8371df11ef6097a83bdf2303e4357d6f5040acc4f76019489fa5deeae0d
|
32
|
+
def generate_p_hash(app_id)
|
33
|
+
unless !FastlaneCore::Env.truthy?("FASTLANE_OPT_OUT_USAGE") && !app_id.nil?
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'credentials_manager'
|
38
|
+
return Digest::SHA256.hexdigest("p#{app_id}fastlan3_SAlt") # hashed + salted the bundle identifier
|
39
|
+
rescue
|
40
|
+
return nil # we don't want this method to cause a crash
|
41
|
+
end
|
42
|
+
|
43
|
+
# (optional) Returns the app identifier for the current tool
|
44
|
+
def ios_app_identifier(args)
|
45
|
+
return FastlaneCore::IOSAppIdentifierGuesser.guess_app_identifier(args)
|
46
|
+
rescue
|
47
|
+
nil # we don't want this method to cause a crash
|
48
|
+
end
|
49
|
+
|
50
|
+
# (optional) Returns the app identifier for the current tool
|
51
|
+
# supply and screengrab use different param names and env variable patterns so we have to special case here
|
52
|
+
# example:
|
53
|
+
# fastlane supply --skip_upload_screenshots -a beta -p com.test.app should return com.test.app
|
54
|
+
# screengrab -a com.test.app should return com.test.app
|
55
|
+
def android_app_identifier(args, gem_name)
|
56
|
+
app_identifier = FastlaneCore::AndroidPackageNameGuesser.guess_package_name(gem_name, args)
|
57
|
+
|
58
|
+
# Add Android prefix to prevent collisions if there is an iOS app with the same identifier
|
59
|
+
app_identifier ? "android_project_#{app_identifier}" : nil
|
60
|
+
rescue
|
61
|
+
nil # we don't want this method to cause a crash
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -60,8 +60,13 @@ module Commander
|
|
60
60
|
FastlaneCore::UI.user_error!("fastlane requires a minimum version of Xcode #{Fastlane::MINIMUM_XCODE_RELEASE}, please upgrade and make sure to use `sudo xcode-select -s /Applications/Xcode.app`")
|
61
61
|
end
|
62
62
|
|
63
|
-
|
64
|
-
|
63
|
+
action_launch_context = FastlaneCore::ActionLaunchContext.context_for_action_name(@program[:name], args: ARGV)
|
64
|
+
FastlaneCore.session.action_launched(launch_context: action_launch_context)
|
65
|
+
|
66
|
+
return_value = run_active_command
|
67
|
+
|
68
|
+
action_completed(@program[:name], status: FastlaneCore::ActionCompletionStatus::SUCCESS)
|
69
|
+
return return_value
|
65
70
|
rescue InvalidCommandError => e
|
66
71
|
# calling `abort` makes it likely that tests stop without failing, so
|
67
72
|
# we'll disable that during tests.
|
@@ -76,6 +81,7 @@ module Commander
|
|
76
81
|
if FastlaneCore::Globals.verbose?
|
77
82
|
raise e
|
78
83
|
else
|
84
|
+
action_completed(@program[:name], status: FastlaneCore::ActionCompletionStatus::INTERRUPTED, exception: e)
|
79
85
|
puts "\nCancelled... use --verbose to show the stack trace"
|
80
86
|
end
|
81
87
|
rescue \
|
@@ -116,12 +122,15 @@ module Commander
|
|
116
122
|
rescue => e # high chance this is actually FastlaneCore::Interface::FastlaneCrash, but can be anything else
|
117
123
|
rescue_unknown_error(e)
|
118
124
|
ensure
|
119
|
-
|
125
|
+
FastlaneCore.session.finalize_session
|
120
126
|
end
|
121
127
|
end
|
122
128
|
|
123
|
-
def
|
124
|
-
|
129
|
+
def action_completed(action_name, status: nil, exception: nil)
|
130
|
+
if exception.nil? || exception.fastlane_should_report_metrics?
|
131
|
+
action_completion_context = FastlaneCore::ActionCompletionContext.context_for_action_name(action_name, args: ARGV, status: status)
|
132
|
+
FastlaneCore.session.action_completed(completion_context: action_completion_context)
|
133
|
+
end
|
125
134
|
end
|
126
135
|
|
127
136
|
def rescue_file_error(e)
|
@@ -145,12 +154,15 @@ module Commander
|
|
145
154
|
|
146
155
|
def rescue_unknown_error(e)
|
147
156
|
FastlaneCore::CrashReporter.report_crash(exception: e)
|
148
|
-
|
157
|
+
|
158
|
+
action_completed(@program[:name], status: FastlaneCore::ActionCompletionStatus::FAILED, exception: e)
|
159
|
+
|
149
160
|
handle_unknown_error!(e)
|
150
161
|
end
|
151
162
|
|
152
163
|
def rescue_fastlane_error(e)
|
153
|
-
|
164
|
+
action_completed(@program[:name], status: FastlaneCore::ActionCompletionStatus::USER_ERROR, exception: e)
|
165
|
+
|
154
166
|
show_github_issues(e.message) if e.show_github_issues
|
155
167
|
FastlaneCore::CrashReporter.report_crash(exception: e)
|
156
168
|
display_user_error!(e, e.message)
|
@@ -247,6 +259,7 @@ module Commander
|
|
247
259
|
reraise_formatted!(e, message)
|
248
260
|
else
|
249
261
|
# without stack trace
|
262
|
+
action_completed(@program[:name], status: FastlaneCore::ActionCompletionStatus::USER_ERROR, exception: e)
|
250
263
|
abort "\n[!] #{message}".red
|
251
264
|
end
|
252
265
|
end
|
@@ -2,8 +2,7 @@ require 'excon'
|
|
2
2
|
require 'digest'
|
3
3
|
|
4
4
|
require 'fastlane_core/update_checker/changelog'
|
5
|
-
require 'fastlane_core/
|
6
|
-
require 'fastlane_core/android_package_name_guesser'
|
5
|
+
require 'fastlane_core/analytics/app_identifier_guesser'
|
7
6
|
|
8
7
|
module FastlaneCore
|
9
8
|
# Verifies, the user runs the latest version of this gem
|
@@ -121,64 +120,11 @@ module FastlaneCore
|
|
121
120
|
"https://rubygems.org/api/v1/gems/#{gem_name}.json"
|
122
121
|
end
|
123
122
|
|
124
|
-
# (optional) Returns the app identifier for the current tool
|
125
|
-
def self.ios_app_identifier(args)
|
126
|
-
return FastlaneCore::IOSAppIdentifierGuesser.guess_app_identifier(args)
|
127
|
-
rescue
|
128
|
-
nil # we don't want this method to cause a crash
|
129
|
-
end
|
130
|
-
|
131
|
-
# (optional) Returns the app identifier for the current tool
|
132
|
-
# supply and screengrab use different param names and env variable patterns so we have to special case here
|
133
|
-
# example:
|
134
|
-
# fastlane supply --skip_upload_screenshots -a beta -p com.test.app should return com.test.app
|
135
|
-
# screengrab -a com.test.app should return com.test.app
|
136
|
-
def self.android_app_identifier(args, gem_name)
|
137
|
-
app_identifier = FastlaneCore::AndroidPackageNameGuesser.guess_package_name(gem_name, args)
|
138
|
-
|
139
|
-
# Add Android prefix to prevent collisions if there is an iOS app with the same identifier
|
140
|
-
app_identifier ? "android_project_#{app_identifier}" : nil
|
141
|
-
rescue
|
142
|
-
nil # we don't want this method to cause a crash
|
143
|
-
end
|
144
|
-
|
145
|
-
# To not count the same projects multiple time for the number of launches
|
146
|
-
# Learn more at https://github.com/fastlane/fastlane#metrics
|
147
|
-
# Use the `FASTLANE_OPT_OUT_USAGE` variable to opt out
|
148
|
-
# The resulting value is e.g. ce12f8371df11ef6097a83bdf2303e4357d6f5040acc4f76019489fa5deeae0d
|
149
|
-
def self.p_hash(args, gem_name)
|
150
|
-
return nil if FastlaneCore::Env.truthy?("FASTLANE_OPT_OUT_USAGE")
|
151
|
-
require 'credentials_manager'
|
152
|
-
|
153
|
-
app_identifier = app_id(args, gem_name)
|
154
|
-
|
155
|
-
if app_identifier
|
156
|
-
return Digest::SHA256.hexdigest("p#{app_identifier}fastlan3_SAlt") # hashed + salted the bundle identifier
|
157
|
-
end
|
158
|
-
|
159
|
-
return nil
|
160
|
-
rescue
|
161
|
-
return nil
|
162
|
-
end
|
163
|
-
|
164
|
-
def self.app_id(args, gem_name)
|
165
|
-
# check if this is an android project first because some of the same params exist for iOS and Android tools
|
166
|
-
app_identifier = android_app_identifier(args, gem_name)
|
167
|
-
@platform = nil # since have a state in-between runs
|
168
|
-
if app_identifier
|
169
|
-
@platform = :android
|
170
|
-
else
|
171
|
-
app_identifier = ios_app_identifier(args)
|
172
|
-
@platform = :ios if app_identifier
|
173
|
-
end
|
174
|
-
return app_identifier
|
175
|
-
end
|
176
|
-
|
177
123
|
def self.send_launch_analytic_events_for(gem_name)
|
178
124
|
return if FastlaneCore::Env.truthy?("FASTLANE_OPT_OUT_USAGE")
|
179
|
-
|
180
125
|
ci = Helper.is_ci?.to_s
|
181
|
-
|
126
|
+
app_id_guesser = FastlaneCore::AppIdentifierGuesser.new(args: ARGV, gem_name: gem_name)
|
127
|
+
project_hash = app_id_guesser.p_hash
|
182
128
|
p_hash = project_hash if project_hash
|
183
129
|
platform = @platform if @platform # this has to be called after `p_hash`
|
184
130
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.62.0.beta.
|
4
|
+
version: 2.62.0.beta.20171017010003
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2017-10-
|
18
|
+
date: 2017-10-17 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: slack-notifier
|
@@ -1171,6 +1171,12 @@ files:
|
|
1171
1171
|
- fastlane_core/README.md
|
1172
1172
|
- fastlane_core/lib/assets/XMLTemplate.xml.erb
|
1173
1173
|
- fastlane_core/lib/fastlane_core.rb
|
1174
|
+
- fastlane_core/lib/fastlane_core/analytics/action_completion_context.rb
|
1175
|
+
- fastlane_core/lib/fastlane_core/analytics/action_launch_context.rb
|
1176
|
+
- fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb
|
1177
|
+
- fastlane_core/lib/fastlane_core/analytics/analytics_ingester_client.rb
|
1178
|
+
- fastlane_core/lib/fastlane_core/analytics/analytics_session.rb
|
1179
|
+
- fastlane_core/lib/fastlane_core/analytics/app_identifier_guesser.rb
|
1174
1180
|
- fastlane_core/lib/fastlane_core/android_package_name_guesser.rb
|
1175
1181
|
- fastlane_core/lib/fastlane_core/build_watcher.rb
|
1176
1182
|
- fastlane_core/lib/fastlane_core/cert_checker.rb
|