fastlane 2.200.0 → 2.201.0.rc1
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/actions/trainer.rb +49 -0
- data/fastlane/lib/fastlane/helper/xcodebuild_formatter_helper.rb +9 -0
- data/fastlane/lib/fastlane/tools.rb +2 -1
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/gym/lib/gym/generators/build_command_generator.rb +67 -21
- data/gym/lib/gym/options.rb +17 -5
- data/scan/lib/scan/options.rb +25 -5
- data/scan/lib/scan/runner.rb +57 -14
- data/scan/lib/scan/test_command_generator.rb +54 -5
- data/snapshot/lib/snapshot/options.rb +23 -7
- data/snapshot/lib/snapshot/test_command_generator.rb +37 -2
- data/trainer/lib/assets/junit.xml.erb +20 -0
- data/trainer/lib/trainer/commands_generator.rb +51 -0
- data/trainer/lib/trainer/junit_generator.rb +31 -0
- data/trainer/lib/trainer/module.rb +10 -0
- data/trainer/lib/trainer/options.rb +55 -0
- data/trainer/lib/trainer/test_parser.rb +335 -0
- data/trainer/lib/trainer/xcresult.rb +403 -0
- data/trainer/lib/trainer.rb +7 -0
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0748d7414d5df9609fbffecf573937a1b74cbdebc81f9ee203e1197b58ecc5b1'
|
4
|
+
data.tar.gz: 6f07f231bb899663f8d4e46561b6c2fe982aad07cc531a9796ec285b0495d8bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79d8d561694712d172f2fcb925abfab4ce52a5be9d5af2e5645dd88813e0a65581e192c4ee21b792571685293a615d839442e156322f0cea7d6ef0303487747b
|
7
|
+
data.tar.gz: 8f5abd82eed5601477648a67bef8275c7ce4a48926550f409220f91fd54626ba375fef8827c5625ea6bf7d2ab833fbf8cdb49aa15ff9f02b51b93cde806cb144
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class TrainerAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
require "trainer"
|
6
|
+
|
7
|
+
params[:path] = Actions.lane_context[Actions::SharedValues::SCAN_GENERATED_PLIST_FILE] if Actions.lane_context[Actions::SharedValues::SCAN_GENERATED_PLIST_FILE]
|
8
|
+
params[:path] ||= Actions.lane_context[Actions::SharedValues::SCAN_DERIVED_DATA_PATH] if Actions.lane_context[Actions::SharedValues::SCAN_DERIVED_DATA_PATH]
|
9
|
+
|
10
|
+
fail_build = params[:fail_build]
|
11
|
+
resulting_paths = Trainer::TestParser.auto_convert(params)
|
12
|
+
resulting_paths.each do |path, test_successful|
|
13
|
+
UI.test_failure!("Unit tests failed") if fail_build && !test_successful
|
14
|
+
end
|
15
|
+
|
16
|
+
return resulting_paths
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.description
|
20
|
+
"Convert the Xcode plist log to a JUnit report"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.detail
|
24
|
+
"Convert the Xcode plist log to a JUnit report. This will raise an exception if the tests failed"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.authors
|
28
|
+
["KrauseFx"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.return_value
|
32
|
+
"A hash with the key being the path of the generated file, the value being if the tests were successful"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.available_options
|
36
|
+
require 'trainer'
|
37
|
+
FastlaneCore::CommanderGenerator.new.generate(Trainer::Options.available_options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.is_supported?(platform)
|
41
|
+
%i[ios mac].include?(platform)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.category
|
45
|
+
:testing
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -72,32 +72,78 @@ module Gym
|
|
72
72
|
def pipe
|
73
73
|
pipe = []
|
74
74
|
pipe << "| tee #{xcodebuild_log_path.shellescape}"
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
pipe << report_output_html.shellescape
|
92
|
-
elsif report_output_json
|
93
|
-
pipe << " --report json-compilation-database --output "
|
94
|
-
pipe << report_output_json.shellescape
|
95
|
-
end
|
75
|
+
|
76
|
+
formatter = Gym.config[:xcodebuild_formatter].chomp
|
77
|
+
options = legacy_xcpretty_options
|
78
|
+
|
79
|
+
if Gym.config[:disable_xcpretty] || formatter == ''
|
80
|
+
UI.verbose("Not using an xcodebuild formatter")
|
81
|
+
elsif !options.empty?
|
82
|
+
UI.important("Detected legacy xcpretty being used so formatting wth xcpretty")
|
83
|
+
UI.important("Option(s) used: #{options.join(', ')}")
|
84
|
+
pipe += pipe_xcpretty
|
85
|
+
elsif formatter == 'xcpretty'
|
86
|
+
pipe += pipe_xcpretty
|
87
|
+
elsif formatter == 'xcbeautify'
|
88
|
+
pipe += pipe_xcbeautify
|
89
|
+
else
|
90
|
+
pipe << "| #{formatter}"
|
96
91
|
end
|
92
|
+
|
97
93
|
pipe << "> /dev/null" if Gym.config[:suppress_xcode_output]
|
98
94
|
pipe
|
99
95
|
end
|
100
96
|
|
97
|
+
def pipe_xcbeautify
|
98
|
+
pipe = ['| xcbeautify']
|
99
|
+
|
100
|
+
if FastlaneCore::Helper.colors_disabled?
|
101
|
+
pipe << '--disable-colored-output'
|
102
|
+
end
|
103
|
+
|
104
|
+
return pipe
|
105
|
+
end
|
106
|
+
|
107
|
+
def legacy_xcpretty_options
|
108
|
+
options = []
|
109
|
+
|
110
|
+
options << "xcpretty_test_format" if Gym.config[:xcpretty_test_format]
|
111
|
+
options << "xcpretty_formatter" if Gym.config[:xcpretty_formatter]
|
112
|
+
options << "xcpretty_report_junit" if Gym.config[:xcpretty_report_junit]
|
113
|
+
options << "xcpretty_report_html" if Gym.config[:xcpretty_report_html]
|
114
|
+
options << "xcpretty_report_json" if Gym.config[:xcpretty_report_json]
|
115
|
+
options << "xcpretty_utf" if Gym.config[:xcpretty_utf]
|
116
|
+
|
117
|
+
return options
|
118
|
+
end
|
119
|
+
|
120
|
+
def pipe_xcpretty
|
121
|
+
pipe = []
|
122
|
+
|
123
|
+
formatter = Gym.config[:xcpretty_formatter]
|
124
|
+
pipe << "| xcpretty"
|
125
|
+
pipe << " --test" if Gym.config[:xcpretty_test_format]
|
126
|
+
pipe << " --no-color" if Helper.colors_disabled?
|
127
|
+
pipe << " --formatter " if formatter
|
128
|
+
pipe << formatter if formatter
|
129
|
+
pipe << "--utf" if Gym.config[:xcpretty_utf]
|
130
|
+
report_output_junit = Gym.config[:xcpretty_report_junit]
|
131
|
+
report_output_html = Gym.config[:xcpretty_report_html]
|
132
|
+
report_output_json = Gym.config[:xcpretty_report_json]
|
133
|
+
if report_output_junit
|
134
|
+
pipe << " --report junit --output "
|
135
|
+
pipe << report_output_junit.shellescape
|
136
|
+
elsif report_output_html
|
137
|
+
pipe << " --report html --output "
|
138
|
+
pipe << report_output_html.shellescape
|
139
|
+
elsif report_output_json
|
140
|
+
pipe << " --report json-compilation-database --output "
|
141
|
+
pipe << report_output_json.shellescape
|
142
|
+
end
|
143
|
+
|
144
|
+
pipe
|
145
|
+
end
|
146
|
+
|
101
147
|
def post_build
|
102
148
|
commands = []
|
103
149
|
commands << %{grep -E '^[0-9.]+ms' #{xcodebuild_log_path.shellescape} | grep -vE '^0\.[0-9]' | sort -nr > culprits.txt} if Gym.config[:analyze_build_time]
|
data/gym/lib/gym/options.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fastlane_core/configuration/config_item'
|
2
|
+
require 'fastlane/helper/xcodebuild_formatter_helper'
|
2
3
|
require 'credentials_manager/appfile_config'
|
3
4
|
require_relative 'module'
|
4
5
|
|
@@ -230,8 +231,18 @@ module Gym
|
|
230
231
|
description: "Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path",
|
231
232
|
optional: true,
|
232
233
|
type: Boolean),
|
234
|
+
|
235
|
+
FastlaneCore::ConfigItem.new(key: :xcodebuild_formatter,
|
236
|
+
env_names: ["GYM_XCODEBUILD_FORMATTER", "FASTLANE_XCODEBUILD_FORMATTER"],
|
237
|
+
description: "xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test')",
|
238
|
+
type: String,
|
239
|
+
default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
|
240
|
+
default_value_dynamic: true),
|
241
|
+
|
242
|
+
# xcpretty
|
233
243
|
FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
|
234
244
|
env_name: "DISABLE_XCPRETTY",
|
245
|
+
deprecated: "Use `xcodebuild_formatter: ''` instead",
|
235
246
|
description: "Disable xcpretty formatting of build output",
|
236
247
|
optional: true,
|
237
248
|
type: Boolean),
|
@@ -259,16 +270,17 @@ module Gym
|
|
259
270
|
env_name: "XCPRETTY_REPORT_JSON",
|
260
271
|
description: "Have xcpretty create a JSON compilation database at the provided path",
|
261
272
|
optional: true),
|
262
|
-
FastlaneCore::ConfigItem.new(key: :analyze_build_time,
|
263
|
-
env_name: "GYM_ANALYZE_BUILD_TIME",
|
264
|
-
description: "Analyze the project build time and store the output in 'culprits.txt' file",
|
265
|
-
optional: true,
|
266
|
-
type: Boolean),
|
267
273
|
FastlaneCore::ConfigItem.new(key: :xcpretty_utf,
|
268
274
|
env_name: "XCPRETTY_UTF",
|
269
275
|
description: "Have xcpretty use unicode encoding when reporting builds",
|
270
276
|
optional: true,
|
271
277
|
type: Boolean),
|
278
|
+
|
279
|
+
FastlaneCore::ConfigItem.new(key: :analyze_build_time,
|
280
|
+
env_name: "GYM_ANALYZE_BUILD_TIME",
|
281
|
+
description: "Analyze the project build time and store the output in 'culprits.txt' file",
|
282
|
+
optional: true,
|
283
|
+
type: Boolean),
|
272
284
|
FastlaneCore::ConfigItem.new(key: :skip_profile_detection,
|
273
285
|
env_name: "GYM_SKIP_PROFILE_DETECTION",
|
274
286
|
description: "Do not try to build a profile mapping from the xcodeproj. Match or a manually provided mapping should be used",
|
data/scan/lib/scan/options.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fastlane_core/configuration/config_item'
|
2
|
+
require 'fastlane/helper/xcodebuild_formatter_helper'
|
2
3
|
require 'credentials_manager/appfile_config'
|
3
4
|
require_relative 'module'
|
4
5
|
|
@@ -214,11 +215,7 @@ module Scan
|
|
214
215
|
description: "Should the HTML report be opened when tests are completed?",
|
215
216
|
is_string: false,
|
216
217
|
default_value: false),
|
217
|
-
|
218
|
-
env_name: "SCAN_DISABLE_XCPRETTY",
|
219
|
-
description: "Disable xcpretty formatting of build, similar to `output_style='raw'` but this will also skip the test results table",
|
220
|
-
type: Boolean,
|
221
|
-
optional: true),
|
218
|
+
|
222
219
|
FastlaneCore::ConfigItem.new(key: :output_directory,
|
223
220
|
short_option: "-o",
|
224
221
|
env_name: "SCAN_OUTPUT_DIRECTORY",
|
@@ -227,6 +224,7 @@ module Scan
|
|
227
224
|
code_gen_default_value: "./test_output",
|
228
225
|
default_value: File.join(containing, "test_output"),
|
229
226
|
default_value_dynamic: true),
|
227
|
+
|
230
228
|
FastlaneCore::ConfigItem.new(key: :output_style,
|
231
229
|
short_option: "-b",
|
232
230
|
env_name: "SCAN_OUTPUT_STYLE",
|
@@ -263,9 +261,30 @@ module Scan
|
|
263
261
|
description: "Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path",
|
264
262
|
optional: true,
|
265
263
|
type: Boolean),
|
264
|
+
|
265
|
+
FastlaneCore::ConfigItem.new(key: :xcodebuild_formatter,
|
266
|
+
env_names: ["SCAN_XCODEBUILD_FORMATTER", "FASTLANE_XCODEBUILD_FORMATTER"],
|
267
|
+
description: "xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test')",
|
268
|
+
type: String,
|
269
|
+
default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
|
270
|
+
default_value_dynamic: true),
|
271
|
+
|
272
|
+
# xcpretty
|
273
|
+
FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
|
274
|
+
env_name: "SCAN_DISABLE_XCPRETTY",
|
275
|
+
deprecated: "Use `output_style: 'raw'` instead",
|
276
|
+
description: "Disable xcpretty formatting of build, similar to `output_style='raw'` but this will also skip the test results table",
|
277
|
+
type: Boolean,
|
278
|
+
optional: true),
|
266
279
|
FastlaneCore::ConfigItem.new(key: :formatter,
|
267
280
|
short_option: "-n",
|
268
281
|
env_name: "SCAN_FORMATTER",
|
282
|
+
deprecated: "Use 'xcpretty_formatter' instead",
|
283
|
+
description: "A custom xcpretty formatter to use",
|
284
|
+
optional: true),
|
285
|
+
FastlaneCore::ConfigItem.new(key: :xcpretty_formatter,
|
286
|
+
short_option: "-N",
|
287
|
+
env_name: "SCAN_XCPRETTY_FORMATTER",
|
269
288
|
description: "A custom xcpretty formatter to use",
|
270
289
|
optional: true),
|
271
290
|
FastlaneCore::ConfigItem.new(key: :xcpretty_args,
|
@@ -273,6 +292,7 @@ module Scan
|
|
273
292
|
description: "Pass in xcpretty additional command line arguments (e.g. '--test --no-color' or '--tap --no-utf')",
|
274
293
|
type: String,
|
275
294
|
optional: true),
|
295
|
+
|
276
296
|
FastlaneCore::ConfigItem.new(key: :derived_data_path,
|
277
297
|
short_option: "-j",
|
278
298
|
env_name: "SCAN_DERIVED_DATA_PATH",
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -51,7 +51,9 @@ module Scan
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
# Set retries to 0 if Xcode 13 because TestCommandGenerator will set '-retry-tests-on-failure -test-iterations'
|
55
|
+
retries = Helper.xcode_at_least?(13) ? 0 : Scan.config[:number_of_retries]
|
56
|
+
execute(retries: retries)
|
55
57
|
end
|
56
58
|
|
57
59
|
def execute(retries: 0)
|
@@ -135,27 +137,68 @@ module Scan
|
|
135
137
|
return retryable_tests.uniq
|
136
138
|
end
|
137
139
|
|
138
|
-
def
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
def trainer_test_results
|
141
|
+
require "trainer"
|
142
|
+
|
143
|
+
results = {
|
144
|
+
number_of_tests: 0,
|
145
|
+
number_of_failures: 0,
|
146
|
+
number_of_retries: 0
|
147
|
+
}
|
148
|
+
|
149
|
+
result_bundle_path = Scan.cache[:result_bundle_path]
|
150
|
+
output_path = Scan.config[:output_directory] || Dir.mktmpdir
|
151
|
+
|
152
|
+
UI.crash!("A -resultBundlePath is needed to parse the test results. This should not have happened. Please file an issue.") unless result_bundle_path
|
153
|
+
|
154
|
+
params = {
|
155
|
+
path: result_bundle_path,
|
156
|
+
output_path: output_path,
|
157
|
+
silent: true,
|
158
|
+
extension: "xml"
|
159
|
+
}
|
160
|
+
|
161
|
+
resulting_paths = Trainer::TestParser.auto_convert(params)
|
162
|
+
resulting_paths.each do |path, data|
|
163
|
+
results[:number_of_tests] += data[:number_of_tests_excluding_retries]
|
164
|
+
results[:number_of_failures] += data[:number_of_failures_excluding_retries]
|
165
|
+
results[:number_of_retries] += data[:number_of_retries]
|
144
166
|
end
|
145
167
|
|
146
|
-
|
147
|
-
|
168
|
+
return results
|
169
|
+
end
|
170
|
+
|
171
|
+
def handle_results(tests_exit_status)
|
172
|
+
results = trainer_test_results
|
148
173
|
|
149
|
-
|
150
|
-
|
174
|
+
number_of_retries = results[:number_of_retries]
|
175
|
+
number_of_tests = results[:number_of_tests]
|
176
|
+
number_of_failures = results[:number_of_failures]
|
177
|
+
|
178
|
+
SlackPoster.new.run({
|
179
|
+
tests: number_of_tests,
|
180
|
+
failures: number_of_failures
|
181
|
+
})
|
182
|
+
|
183
|
+
if number_of_failures > 0
|
184
|
+
failures_str = number_of_failures.to_s.red
|
151
185
|
else
|
152
|
-
failures_str =
|
186
|
+
failures_str = number_of_failures.to_s.green
|
153
187
|
end
|
154
188
|
|
189
|
+
retries_str = case number_of_retries
|
190
|
+
when 0
|
191
|
+
""
|
192
|
+
when 1
|
193
|
+
" (and 1 retry)"
|
194
|
+
else
|
195
|
+
" (and #{number_of_retries} retries)"
|
196
|
+
end
|
197
|
+
|
155
198
|
puts(Terminal::Table.new({
|
156
199
|
title: "Test Results",
|
157
200
|
rows: [
|
158
|
-
["Number of tests",
|
201
|
+
["Number of tests", "#{number_of_tests}#{retries_str}"],
|
159
202
|
["Number of failures", failures_str]
|
160
203
|
]
|
161
204
|
}))
|
@@ -165,7 +208,7 @@ module Scan
|
|
165
208
|
zip_build_products
|
166
209
|
copy_xctestrun
|
167
210
|
|
168
|
-
if
|
211
|
+
if number_of_failures > 0
|
169
212
|
open_report
|
170
213
|
|
171
214
|
UI.test_failure!("Tests have failed")
|
@@ -53,7 +53,7 @@ module Scan
|
|
53
53
|
if config[:use_system_scm] && !options.include?("-scmProvider system")
|
54
54
|
options << "-scmProvider system"
|
55
55
|
end
|
56
|
-
options << "-resultBundlePath '#{result_bundle_path
|
56
|
+
options << "-resultBundlePath '#{result_bundle_path(config[:result_bundle])}'"
|
57
57
|
if FastlaneCore::Helper.xcode_at_least?(10)
|
58
58
|
options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
|
59
59
|
options << "-maximum-concurrent-test-simulator-destinations #{config[:max_concurrent_simulators]}" if config[:max_concurrent_simulators]
|
@@ -72,6 +72,10 @@ module Scan
|
|
72
72
|
end
|
73
73
|
options << "-xctestrun '#{config[:xctestrun]}'" if config[:xctestrun]
|
74
74
|
options << config[:xcargs] if config[:xcargs]
|
75
|
+
if config[:number_of_retries] >= 1 && FastlaneCore::Helper.xcode_at_least?(13)
|
76
|
+
options << "-retry-tests-on-failure"
|
77
|
+
options << "-test-iterations #{config[:number_of_retries]}"
|
78
|
+
end
|
75
79
|
|
76
80
|
# detect_values will ensure that these values are present as Arrays if
|
77
81
|
# they are present at all
|
@@ -107,12 +111,55 @@ module Scan
|
|
107
111
|
def pipe
|
108
112
|
pipe = ["| tee '#{xcodebuild_log_path}'"]
|
109
113
|
|
114
|
+
# disable_xcpretty is now deprecated and directs to use output_style of raw
|
110
115
|
if Scan.config[:disable_xcpretty] || Scan.config[:output_style] == 'raw'
|
111
116
|
return pipe
|
112
117
|
end
|
113
118
|
|
119
|
+
formatter = Scan.config[:xcodebuild_formatter].chomp
|
120
|
+
options = legacy_xcpretty_options
|
121
|
+
|
122
|
+
if !options.empty?
|
123
|
+
UI.important("Detected legacy xcpretty being used so formatting wth xcpretty")
|
124
|
+
UI.important("Option(s) used: #{options.join(', ')}")
|
125
|
+
pipe << pipe_xcpretty
|
126
|
+
elsif formatter == 'xcpretty'
|
127
|
+
pipe << pipe_xcpretty
|
128
|
+
elsif formatter == 'xcbeautify'
|
129
|
+
pipe << pipe_xcbeautify
|
130
|
+
else
|
131
|
+
pipe << "| #{formatter}"
|
132
|
+
end
|
133
|
+
|
134
|
+
return pipe
|
135
|
+
end
|
136
|
+
|
137
|
+
def pipe_xcbeautify
|
138
|
+
formatter = ['| xcbeautify']
|
139
|
+
|
140
|
+
if FastlaneCore::Helper.colors_disabled?
|
141
|
+
formatter << '--disable-colored-output'
|
142
|
+
end
|
143
|
+
|
144
|
+
return formatter.join(' ')
|
145
|
+
end
|
146
|
+
|
147
|
+
def legacy_xcpretty_options
|
148
|
+
options = []
|
149
|
+
|
150
|
+
options << "formatter" if Scan.config[:formatter]
|
151
|
+
options << "xcpretty_formatter" if Scan.config[:xcpretty_formatter]
|
152
|
+
options << "output_style" if Scan.config[:output_style]
|
153
|
+
options << "output_files" if Scan.config[:output_files]
|
154
|
+
options << "output_types" if (Scan.config[:output_types] || "").include?("json-compilation-database")
|
155
|
+
options << "custom_report_file_name" if Scan.config[:custom_report_file_name]
|
156
|
+
|
157
|
+
return options
|
158
|
+
end
|
159
|
+
|
160
|
+
def pipe_xcpretty
|
114
161
|
formatter = []
|
115
|
-
if (custom_formatter = Scan.config[:formatter])
|
162
|
+
if (custom_formatter = Scan.config[:xcpretty_formatter] || Scan.config[:formatter])
|
116
163
|
if custom_formatter.end_with?(".rb")
|
117
164
|
formatter << "-f '#{custom_formatter}'"
|
118
165
|
else
|
@@ -143,7 +190,7 @@ module Scan
|
|
143
190
|
Scan.config[:xcpretty_args])
|
144
191
|
reporter_options = @reporter_options_generator.generate_reporter_options
|
145
192
|
reporter_xcpretty_args = @reporter_options_generator.generate_xcpretty_args_options
|
146
|
-
return
|
193
|
+
return "| xcpretty #{formatter.join(' ')} #{reporter_options.join(' ')} #{reporter_xcpretty_args}"
|
147
194
|
end
|
148
195
|
|
149
196
|
# Store the raw file
|
@@ -183,11 +230,13 @@ module Scan
|
|
183
230
|
end
|
184
231
|
|
185
232
|
# The path to the result bundle
|
186
|
-
def result_bundle_path
|
233
|
+
def result_bundle_path(use_output_directory)
|
234
|
+
root_dir = use_output_directory ? Scan.config[:output_directory] : Dir.mktmpdir
|
235
|
+
|
187
236
|
retry_count = Scan.cache[:retry_attempt] || 0
|
188
237
|
attempt = retry_count > 0 ? "-#{retry_count}" : ""
|
189
238
|
ext = FastlaneCore::Helper.xcode_version.to_i >= 11 ? '.xcresult' : '.test_result'
|
190
|
-
path = File.join(
|
239
|
+
path = File.join([root_dir, Scan.config[:scheme]].compact) + attempt + ext
|
191
240
|
|
192
241
|
Scan.cache[:result_bundle_path] = path
|
193
242
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'fastlane_core/configuration/config_item'
|
2
2
|
require 'fastlane_core/device_manager'
|
3
|
+
require 'fastlane/helper/xcodebuild_formatter_helper'
|
3
4
|
require 'credentials_manager/appfile_config'
|
4
5
|
require_relative 'module'
|
5
6
|
|
@@ -11,9 +12,13 @@ module Snapshot
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def self.available_options
|
15
|
+
@options ||= plain_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.plain_options
|
14
19
|
output_directory = (File.directory?("fastlane") ? "fastlane/screenshots" : "screenshots")
|
15
20
|
|
16
|
-
|
21
|
+
[
|
17
22
|
FastlaneCore::ConfigItem.new(key: :workspace,
|
18
23
|
short_option: "-w",
|
19
24
|
env_name: "SNAPSHOT_WORKSPACE",
|
@@ -194,12 +199,6 @@ module Snapshot
|
|
194
199
|
description: "The configuration to use when building the app. Defaults to 'Release'",
|
195
200
|
default_value_dynamic: true,
|
196
201
|
optional: true),
|
197
|
-
FastlaneCore::ConfigItem.new(key: :xcpretty_args,
|
198
|
-
short_option: "-x",
|
199
|
-
env_name: "SNAPSHOT_XCPRETTY_ARGS",
|
200
|
-
description: "Additional xcpretty arguments",
|
201
|
-
is_string: true,
|
202
|
-
optional: true),
|
203
202
|
FastlaneCore::ConfigItem.new(key: :sdk,
|
204
203
|
short_option: "-k",
|
205
204
|
env_name: "SNAPSHOT_SDK",
|
@@ -289,11 +288,28 @@ module Snapshot
|
|
289
288
|
verify_block: proc do |value|
|
290
289
|
verify_type('skip_testing', [Array, String], value)
|
291
290
|
end),
|
291
|
+
|
292
|
+
FastlaneCore::ConfigItem.new(key: :xcodebuild_formatter,
|
293
|
+
env_names: ["SNAPSHOT_XCODEBUILD_FORMATTER", "FASTLANE_XCODEBUILD_FORMATTER"],
|
294
|
+
description: "xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test')",
|
295
|
+
type: String,
|
296
|
+
default_value: Fastlane::Helper::XcodebuildFormatterHelper.xcbeautify_installed? ? 'xcbeautify' : 'xcpretty',
|
297
|
+
default_value_dynamic: true),
|
298
|
+
|
299
|
+
# xcpretty
|
300
|
+
FastlaneCore::ConfigItem.new(key: :xcpretty_args,
|
301
|
+
short_option: "-x",
|
302
|
+
env_name: "SNAPSHOT_XCPRETTY_ARGS",
|
303
|
+
deprecated: "Use `xcodebuild_formatter: ''` instead",
|
304
|
+
description: "Additional xcpretty arguments",
|
305
|
+
is_string: true,
|
306
|
+
optional: true),
|
292
307
|
FastlaneCore::ConfigItem.new(key: :disable_xcpretty,
|
293
308
|
env_name: "SNAPSHOT_DISABLE_XCPRETTY",
|
294
309
|
description: "Disable xcpretty formatting of build",
|
295
310
|
type: Boolean,
|
296
311
|
optional: true),
|
312
|
+
|
297
313
|
FastlaneCore::ConfigItem.new(key: :suppress_xcode_output,
|
298
314
|
env_name: "SNAPSHOT_SUPPRESS_XCODE_OUTPUT",
|
299
315
|
description: "Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path",
|
@@ -27,10 +27,45 @@ module Snapshot
|
|
27
27
|
tee_command << log_path.shellescape if log_path
|
28
28
|
|
29
29
|
pipe = ["| #{tee_command.join(' ')}"]
|
30
|
-
|
31
|
-
|
30
|
+
|
31
|
+
formatter = Snapshot.config[:xcodebuild_formatter].chomp
|
32
|
+
options = legacy_xcpretty_options
|
33
|
+
|
34
|
+
if Snapshot.config[:disable_xcpretty] || formatter == ''
|
35
|
+
UI.verbose("Not using an xcodebuild formatter")
|
36
|
+
elsif !options.empty?
|
37
|
+
UI.important("Detected legacy xcpretty being used so formatting wth xcpretty")
|
38
|
+
UI.important("Option(s) used: #{options.join(', ')}")
|
39
|
+
pipe += pipe_xcpretty
|
40
|
+
elsif formatter == 'xcpretty'
|
41
|
+
pipe += pipe_xcpretty
|
42
|
+
elsif formatter == 'xcbeautify'
|
43
|
+
pipe += pipe_xcbeautify
|
44
|
+
else
|
45
|
+
pipe << "| #{formatter}"
|
46
|
+
end
|
47
|
+
|
48
|
+
pipe
|
49
|
+
end
|
50
|
+
|
51
|
+
def pipe_xcbeautify
|
52
|
+
pipe = ['| xcbeautify']
|
53
|
+
|
54
|
+
if FastlaneCore::Helper.colors_disabled?
|
55
|
+
pipe << '--disable-colored-output'
|
32
56
|
end
|
33
57
|
|
58
|
+
return pipe
|
59
|
+
end
|
60
|
+
|
61
|
+
def legacy_xcpretty_options
|
62
|
+
options = []
|
63
|
+
options << "xcpretty_args" if Snapshot.config[:xcpretty_args]
|
64
|
+
return options
|
65
|
+
end
|
66
|
+
|
67
|
+
def pipe_xcpretty
|
68
|
+
pipe = []
|
34
69
|
xcpretty = "xcpretty #{Snapshot.config[:xcpretty_args]}"
|
35
70
|
xcpretty << "--no-color" if Helper.colors_disabled?
|
36
71
|
pipe << "| #{xcpretty}"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<% number_of_tests = 0 %>
|
3
|
+
<% number_of_failures = 0 %>
|
4
|
+
<% @results.each { |a| number_of_tests += a[:number_of_tests] } %>
|
5
|
+
<% @results.each { |a| number_of_failures += a[:number_of_failures] } %>
|
6
|
+
|
7
|
+
<testsuites tests="<%= number_of_tests %>" failures="<%= number_of_failures %>">
|
8
|
+
<% @results.each do |testsuite| %>
|
9
|
+
<testsuite name=<%= (testsuite[:target_name].nil? ? testsuite[:test_name] : testsuite[:target_name]).encode(:xml => :attr) %> tests="<%= testsuite[:number_of_tests] %>" failures="<%= testsuite[:number_of_failures] %>" time="<%= testsuite[:duration] %>">
|
10
|
+
<% testsuite[:tests].each do |test| %>
|
11
|
+
<testcase classname=<%= test[:test_group].encode(:xml => :attr) %> name=<%= test[:name].encode(:xml => :attr) %> time="<%= test[:duration] %>">
|
12
|
+
<% (test[:failures] || []).each do |failure| %>
|
13
|
+
<failure message=<%= failure[:failure_message].encode(:xml => :attr) %>>
|
14
|
+
</failure>
|
15
|
+
<% end %>
|
16
|
+
</testcase>
|
17
|
+
<% end %>
|
18
|
+
</testsuite>
|
19
|
+
<% end %>
|
20
|
+
</testsuites>
|