fastlane 2.200.0 → 2.201.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +100 -93
  3. data/fastlane/lib/fastlane/actions/trainer.rb +49 -0
  4. data/fastlane/lib/fastlane/helper/xcodebuild_formatter_helper.rb +9 -0
  5. data/fastlane/lib/fastlane/tools.rb +2 -1
  6. data/fastlane/lib/fastlane/version.rb +1 -1
  7. data/fastlane/swift/Deliverfile.swift +1 -1
  8. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  9. data/fastlane/swift/Fastlane.swift +134 -43
  10. data/fastlane/swift/Gymfile.swift +1 -1
  11. data/fastlane/swift/GymfileProtocol.swift +10 -6
  12. data/fastlane/swift/Matchfile.swift +1 -1
  13. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  14. data/fastlane/swift/Precheckfile.swift +1 -1
  15. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  16. data/fastlane/swift/Scanfile.swift +1 -1
  17. data/fastlane/swift/ScanfileProtocol.swift +18 -6
  18. data/fastlane/swift/Screengrabfile.swift +1 -1
  19. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  20. data/fastlane/swift/Snapshotfile.swift +1 -1
  21. data/fastlane/swift/SnapshotfileProtocol.swift +9 -5
  22. data/fastlane/swift/formatting/Brewfile.lock.json +13 -13
  23. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +7 -0
  24. data/gym/lib/gym/generators/build_command_generator.rb +67 -21
  25. data/gym/lib/gym/options.rb +17 -5
  26. data/scan/lib/scan/options.rb +30 -5
  27. data/scan/lib/scan/runner.rb +121 -14
  28. data/scan/lib/scan/test_command_generator.rb +55 -5
  29. data/snapshot/lib/snapshot/options.rb +23 -7
  30. data/snapshot/lib/snapshot/test_command_generator.rb +37 -2
  31. data/trainer/lib/assets/junit.xml.erb +20 -0
  32. data/trainer/lib/trainer/commands_generator.rb +51 -0
  33. data/trainer/lib/trainer/junit_generator.rb +31 -0
  34. data/trainer/lib/trainer/module.rb +10 -0
  35. data/trainer/lib/trainer/options.rb +55 -0
  36. data/trainer/lib/trainer/test_parser.rb +376 -0
  37. data/trainer/lib/trainer/xcresult.rb +403 -0
  38. data/trainer/lib/trainer.rb +7 -0
  39. metadata +29 -18
@@ -51,11 +51,18 @@ module Scan
51
51
  end
52
52
  end
53
53
 
54
- execute(retries: Scan.config[:number_of_retries])
54
+ retries = Scan.config[:number_of_retries]
55
+ execute(retries: retries)
55
56
  end
56
57
 
57
58
  def execute(retries: 0)
58
- Scan.cache[:retry_attempt] = Scan.config[:number_of_retries] - retries
59
+ # Set retries to 0 if Xcode 13 because TestCommandGenerator will set '-retry-tests-on-failure -test-iterations'
60
+ if Helper.xcode_at_least?(13)
61
+ retries = 0
62
+ Scan.cache[:retry_attempt] = 0
63
+ else
64
+ Scan.cache[:retry_attempt] = Scan.config[:number_of_retries] - retries
65
+ end
59
66
 
60
67
  command = @test_command_generator.generate
61
68
 
@@ -135,27 +142,127 @@ module Scan
135
142
  return retryable_tests.uniq
136
143
  end
137
144
 
138
- def handle_results(tests_exit_status)
139
- if Scan.config[:disable_xcpretty]
140
- unless tests_exit_status == 0
141
- UI.test_failure!("Test execution failed. Exit status: #{tests_exit_status}")
145
+ def find_filename(type)
146
+ index = Scan.config[:output_types].split(',').index(type)
147
+ return nil if index.nil?
148
+ return (Scan.config[:output_files] || "").split(',')[index]
149
+ end
150
+
151
+ def output_html?
152
+ return Scan.config[:output_types].split(',').include?('html')
153
+ end
154
+
155
+ def output_junit?
156
+ return Scan.config[:output_types].split(',').include?('junit')
157
+ end
158
+
159
+ def output_json_compilation_database?
160
+ return Scan.config[:output_types].split(',').include?('json-compilation-database')
161
+ end
162
+
163
+ def output_html_filename
164
+ return find_filename('html')
165
+ end
166
+
167
+ def output_junit_filename
168
+ return find_filename('junit')
169
+ end
170
+
171
+ def output_json_compilation_database_filename
172
+ return find_filename('json-compilation-database')
173
+ end
174
+
175
+ def trainer_test_results
176
+ require "trainer"
177
+
178
+ results = {
179
+ number_of_tests: 0,
180
+ number_of_failures: 0,
181
+ number_of_retries: 0
182
+ }
183
+
184
+ result_bundle_path = Scan.cache[:result_bundle_path]
185
+
186
+ output_path = Scan.config[:output_directory] || Dir.mktmpdir
187
+ output_path = File.absolute_path(output_path)
188
+
189
+ UI.crash!("A -resultBundlePath is needed to parse the test results. This should not have happened. Please file an issue.") unless result_bundle_path
190
+
191
+ params = {
192
+ path: result_bundle_path,
193
+ output_remove_retry_attempts: Scan.config[:output_remove_retry_attempts],
194
+ silent: !FastlaneCore::Globals.verbose?
195
+ }
196
+
197
+ formatter = Scan.config[:xcodebuild_formatter].chomp
198
+ show_output_types_tip = false
199
+ if output_html? && formatter != 'xcpretty'
200
+ UI.important("Skipping HTML... only available with `xcodebuild_formatter: 'xcpretty'` right now")
201
+ show_output_types_tip = true
202
+ end
203
+
204
+ if output_json_compilation_database? && formatter != 'xcpretty'
205
+ UI.important("Skipping JSON Compilation Database... only available with `xcodebuild_formatter: 'xcpretty'` right now")
206
+ show_output_types_tip = true
207
+ end
208
+
209
+ if show_output_types_tip
210
+ UI.important("Your 'xcodebuild_formatter' doesn't support these 'output_types'. Change your 'output_types' to prevent these warnings from showing...")
211
+ end
212
+
213
+ if output_junit?
214
+ if formatter == 'xcpretty'
215
+ UI.verbose("Generating junit report with xcpretty")
216
+ else
217
+ UI.verbose("Generating junit report with trainer")
218
+ params[:output_filename] = output_junit_filename || "report.junit"
219
+ params[:output_directory] = output_path
142
220
  end
143
- return
144
221
  end
145
222
 
146
- result = TestResultParser.new.parse_result(test_results)
147
- SlackPoster.new.run(result)
223
+ resulting_paths = Trainer::TestParser.auto_convert(params)
224
+ resulting_paths.each do |path, data|
225
+ results[:number_of_tests] += data[:number_of_tests_excluding_retries]
226
+ results[:number_of_failures] += data[:number_of_failures_excluding_retries]
227
+ results[:number_of_retries] += data[:number_of_retries]
228
+ end
229
+
230
+ return results
231
+ end
232
+
233
+ def handle_results(tests_exit_status)
234
+ return if Scan.config[:build_for_testing]
148
235
 
149
- if result[:failures] > 0
150
- failures_str = result[:failures].to_s.red
236
+ results = trainer_test_results
237
+
238
+ number_of_retries = results[:number_of_retries]
239
+ number_of_tests = results[:number_of_tests]
240
+ number_of_failures = results[:number_of_failures]
241
+
242
+ SlackPoster.new.run({
243
+ tests: number_of_tests,
244
+ failures: number_of_failures
245
+ })
246
+
247
+ if number_of_failures > 0
248
+ failures_str = number_of_failures.to_s.red
151
249
  else
152
- failures_str = result[:failures].to_s.green
250
+ failures_str = number_of_failures.to_s.green
153
251
  end
154
252
 
253
+ retries_str = case number_of_retries
254
+ when 0
255
+ ""
256
+ when 1
257
+ " (and 1 retry)"
258
+ else
259
+ " (and #{number_of_retries} retries)"
260
+ end
261
+
155
262
  puts(Terminal::Table.new({
156
263
  title: "Test Results",
157
264
  rows: [
158
- ["Number of tests", result[:tests]],
265
+ ["Number of tests", "#{number_of_tests}#{retries_str}"],
159
266
  ["Number of failures", failures_str]
160
267
  ]
161
268
  }))
@@ -165,7 +272,7 @@ module Scan
165
272
  zip_build_products
166
273
  copy_xctestrun
167
274
 
168
- if result[:failures] > 0
275
+ if number_of_failures > 0
169
276
  open_report
170
277
 
171
278
  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}'" if config[:result_bundle]
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,56 @@ 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 formatter == ''
123
+ UI.verbose("Not using an xcodebuild formatter")
124
+ elsif !options.empty?
125
+ UI.important("Detected legacy xcpretty being used so formatting wth xcpretty")
126
+ UI.important("Option(s) used: #{options.join(', ')}")
127
+ pipe << pipe_xcpretty
128
+ elsif formatter == 'xcpretty'
129
+ pipe << pipe_xcpretty
130
+ elsif formatter == 'xcbeautify'
131
+ pipe << pipe_xcbeautify
132
+ else
133
+ pipe << "| #{formatter}"
134
+ end
135
+
136
+ return pipe
137
+ end
138
+
139
+ def pipe_xcbeautify
140
+ formatter = ['| xcbeautify']
141
+
142
+ if FastlaneCore::Helper.colors_disabled?
143
+ formatter << '--disable-colored-output'
144
+ end
145
+
146
+ return formatter.join(' ')
147
+ end
148
+
149
+ def legacy_xcpretty_options
150
+ options = []
151
+
152
+ options << "formatter" if Scan.config[:formatter]
153
+ options << "xcpretty_formatter" if Scan.config[:xcpretty_formatter]
154
+ options << "output_style" if Scan.config[:output_style]
155
+ options << "output_types" if (Scan.config[:output_types] || "").include?("json-compilation-database")
156
+ options << "custom_report_file_name" if Scan.config[:custom_report_file_name]
157
+
158
+ return options
159
+ end
160
+
161
+ def pipe_xcpretty
114
162
  formatter = []
115
- if (custom_formatter = Scan.config[:formatter])
163
+ if (custom_formatter = Scan.config[:xcpretty_formatter] || Scan.config[:formatter])
116
164
  if custom_formatter.end_with?(".rb")
117
165
  formatter << "-f '#{custom_formatter}'"
118
166
  else
@@ -143,7 +191,7 @@ module Scan
143
191
  Scan.config[:xcpretty_args])
144
192
  reporter_options = @reporter_options_generator.generate_reporter_options
145
193
  reporter_xcpretty_args = @reporter_options_generator.generate_xcpretty_args_options
146
- return pipe << "| xcpretty #{formatter.join(' ')} #{reporter_options.join(' ')} #{reporter_xcpretty_args}"
194
+ return "| xcpretty #{formatter.join(' ')} #{reporter_options.join(' ')} #{reporter_xcpretty_args}"
147
195
  end
148
196
 
149
197
  # Store the raw file
@@ -183,11 +231,13 @@ module Scan
183
231
  end
184
232
 
185
233
  # The path to the result bundle
186
- def result_bundle_path
234
+ def result_bundle_path(use_output_directory)
235
+ root_dir = use_output_directory ? Scan.config[:output_directory] : Dir.mktmpdir
236
+
187
237
  retry_count = Scan.cache[:retry_attempt] || 0
188
238
  attempt = retry_count > 0 ? "-#{retry_count}" : ""
189
239
  ext = FastlaneCore::Helper.xcode_version.to_i >= 11 ? '.xcresult' : '.test_result'
190
- path = File.join(Scan.config[:output_directory], Scan.config[:scheme]) + attempt + ext
240
+ path = File.join([root_dir, Scan.config[:scheme]].compact) + attempt + ext
191
241
 
192
242
  Scan.cache[:result_bundle_path] = path
193
243
 
@@ -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
- @options ||= [
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'). Use empty string (ex: '') to disable any formatter (More information: https://docs.fastlane.tools/best-practices/xcodebuild-formatters/)",
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
- if Snapshot.config[:disable_xcpretty]
31
- return pipe
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_excluding_retries] } %>
5
+ <% @results.each { |a| number_of_failures += a[:number_of_failures_excluding_retries] } %>
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_excluding_retries] %>" failures="<%= testsuite[:number_of_failures_excluding_retries] %>" 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>
@@ -0,0 +1,51 @@
1
+ require 'commander'
2
+
3
+ require 'fastlane_core/configuration/configuration'
4
+ require 'fastlane_core/ui/help_formatter'
5
+
6
+ require_relative 'options'
7
+ require_relative 'test_parser'
8
+
9
+ require_relative 'module'
10
+
11
+ HighLine.track_eof = false
12
+
13
+ module Trainer
14
+ class CommandsGenerator
15
+ include Commander::Methods
16
+
17
+ def self.start
18
+ self.new.run
19
+ end
20
+
21
+ def run
22
+ program :version, Fastlane::VERSION
23
+ program :description, Trainer::DESCRIPTION
24
+ program :help, 'Author', 'Felix Krause <trainer@krausefx.com>'
25
+ program :help, 'Website', 'https://fastlane.tools'
26
+ program :help, 'GitHub', 'https://github.com/KrauseFx/trainer'
27
+ program :help_formatter, :compact
28
+
29
+ global_option('--verbose', 'Shows a more verbose output') { $verbose = true }
30
+
31
+ always_trace!
32
+
33
+ FastlaneCore::CommanderGenerator.new.generate(Trainer::Options.available_options)
34
+
35
+ command :run do |c|
36
+ c.syntax = 'trainer'
37
+ c.description = Trainer::DESCRIPTION
38
+
39
+ c.action do |args, options|
40
+ options = FastlaneCore::Configuration.create(Trainer::Options.available_options, options.__hash__)
41
+ FastlaneCore::PrintTable.print_values(config: options, title: "Summary for trainer #{Fastlane::VERSION}") if $verbose
42
+ Trainer::TestParser.auto_convert(options)
43
+ end
44
+ end
45
+
46
+ default_command(:run)
47
+
48
+ run!
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'module'
2
+
3
+ module Trainer
4
+ class JunitGenerator
5
+ attr_accessor :results
6
+
7
+ def initialize(results)
8
+ self.results = results
9
+ end
10
+
11
+ def generate
12
+ # JUnit file documentation: http://llg.cubic.org/docs/junit/
13
+ # And http://nelsonwells.net/2012/09/how-jenkins-ci-parses-and-displays-junit-output/
14
+ # And http://windyroad.com.au/dl/Open%20Source/JUnit.xsd
15
+
16
+ lib_path = Trainer::ROOT
17
+ xml_path = File.join(lib_path, "lib/assets/junit.xml.erb")
18
+ xml = ERB.new(File.read(xml_path), nil, '<>').result(binding) # http://www.rrn.dk/rubys-erb-templating-system
19
+
20
+ xml = xml.gsub('system_', 'system-').delete("\e") # Jenkins can not parse 'ESC' symbol
21
+
22
+ # We have to manuall clear empty lines
23
+ # They may contain white spaces
24
+ clean_xml = []
25
+ xml.each_line do |row|
26
+ clean_xml << row.delete("\n") if row.strip.to_s.length > 0
27
+ end
28
+ return clean_xml.join("\n")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,10 @@
1
+ require 'fastlane_core/helper'
2
+ require 'fastlane/boolean'
3
+
4
+ module Trainer
5
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
6
+ UI = FastlaneCore::UI
7
+ Boolean = Fastlane::Boolean
8
+ ROOT = Pathname.new(File.expand_path('../../..', __FILE__))
9
+ DESCRIPTION = "Convert xcodebuild plist and xcresult files to JUnit reports"
10
+ end
@@ -0,0 +1,55 @@
1
+ require 'fastlane_core/configuration/config_item'
2
+
3
+ require_relative 'module'
4
+
5
+ module Trainer
6
+ class Options
7
+ def self.available_options
8
+ @options ||= [
9
+ FastlaneCore::ConfigItem.new(key: :path,
10
+ short_option: "-p",
11
+ env_name: "TRAINER_PATH",
12
+ default_value: ".",
13
+ description: "Path to the directory that should be converted",
14
+ verify_block: proc do |value|
15
+ v = File.expand_path(value.to_s)
16
+ if v.end_with?(".plist")
17
+ UI.user_error!("Can't find file at path #{v}") unless File.exist?(v)
18
+ else
19
+ UI.user_error!("Path '#{v}' is not a directory or can't be found") unless File.directory?(v)
20
+ end
21
+ end),
22
+ FastlaneCore::ConfigItem.new(key: :extension,
23
+ short_option: "-e",
24
+ env_name: "TRAINER_EXTENSION",
25
+ default_value: ".xml",
26
+ description: "The extension for the newly created file. Usually .xml or .junit",
27
+ verify_block: proc do |value|
28
+ UI.user_error!("extension must contain a `.`") unless value.include?(".")
29
+ end),
30
+ FastlaneCore::ConfigItem.new(key: :output_directory,
31
+ short_option: "-o",
32
+ env_name: "TRAINER_OUTPUT_DIRECTORY",
33
+ default_value: nil,
34
+ optional: true,
35
+ description: "Directoy in which the xml files should be written to. Same directory as source by default"),
36
+ FastlaneCore::ConfigItem.new(key: :fail_build,
37
+ env_name: "TRAINER_FAIL_BUILD",
38
+ description: "Should this step stop the build if the tests fail? Set this to false if you're handling this with a test reporter",
39
+ is_string: false,
40
+ default_value: true),
41
+ FastlaneCore::ConfigItem.new(key: :xcpretty_naming,
42
+ short_option: "-x",
43
+ env_name: "TRAINER_XCPRETTY_NAMING",
44
+ description: "Produces class name and test name identical to xcpretty naming in junit file",
45
+ is_string: false,
46
+ default_value: false),
47
+ FastlaneCore::ConfigItem.new(key: :silent,
48
+ env_name: "TRAINER_SILENT",
49
+ description: "Silences all output",
50
+ is_string: false,
51
+ default_value: false)
52
+ ]
53
+ end
54
+ end
55
+ end