fastlane 2.147.0 → 2.148.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +82 -82
  3. data/cert/lib/cert/commands_generator.rb +1 -0
  4. data/credentials_manager/lib/credentials_manager/cli.rb +2 -0
  5. data/deliver/lib/deliver/commands_generator.rb +1 -0
  6. data/deliver/lib/deliver/html_generator.rb +2 -2
  7. data/deliver/lib/deliver/submit_for_review.rb +5 -1
  8. data/fastlane/lib/fastlane/actions/crashlytics.rb +0 -4
  9. data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -1
  10. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +2 -2
  11. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +12 -0
  12. data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +1 -1
  14. data/fastlane/lib/fastlane/actions/swiftlint.rb +14 -0
  15. data/fastlane/lib/fastlane/actions/sync_code_signing.rb +1 -1
  16. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -1
  17. data/fastlane/lib/fastlane/actions/xcodebuild.rb +4 -4
  18. data/fastlane/lib/fastlane/cli_tools_distributor.rb +28 -6
  19. data/fastlane/lib/fastlane/commands_generator.rb +1 -1
  20. data/fastlane/lib/fastlane/lane_manager.rb +0 -10
  21. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -2
  22. data/fastlane/lib/fastlane/swift_lane_manager.rb +0 -8
  23. data/fastlane/lib/fastlane/version.rb +1 -1
  24. data/fastlane/swift/Deliverfile.swift +1 -1
  25. data/fastlane/swift/Fastlane.swift +68 -15
  26. data/fastlane/swift/Gymfile.swift +1 -1
  27. data/fastlane/swift/LaneFileProtocol.swift +5 -2
  28. data/fastlane/swift/Matchfile.swift +1 -1
  29. data/fastlane/swift/MatchfileProtocol.swift +5 -1
  30. data/fastlane/swift/Precheckfile.swift +1 -1
  31. data/fastlane/swift/Scanfile.swift +1 -1
  32. data/fastlane/swift/ScanfileProtocol.swift +9 -1
  33. data/fastlane/swift/Screengrabfile.swift +1 -1
  34. data/fastlane/swift/Snapshotfile.swift +1 -1
  35. data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
  36. data/frameit/lib/frameit/commands_generator.rb +1 -0
  37. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  38. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +4 -0
  39. data/gym/lib/gym/runner.rb +14 -0
  40. data/match/lib/match/commands_generator.rb +1 -0
  41. data/match/lib/match/generator.rb +2 -1
  42. data/match/lib/match/options.rb +18 -1
  43. data/pem/lib/pem/commands_generator.rb +1 -0
  44. data/pilot/lib/pilot/build_manager.rb +23 -7
  45. data/pilot/lib/pilot/options.rb +5 -0
  46. data/produce/lib/produce/commands_generator.rb +1 -0
  47. data/scan/lib/scan/detect_values.rb +3 -0
  48. data/scan/lib/scan/options.rb +19 -1
  49. data/scan/lib/scan/test_command_generator.rb +6 -1
  50. data/screengrab/lib/screengrab/runner.rb +10 -9
  51. data/sigh/lib/sigh/commands_generator.rb +1 -0
  52. data/sigh/lib/sigh/options.rb +7 -1
  53. data/sigh/lib/sigh/runner.rb +2 -1
  54. data/snapshot/lib/assets/SnapshotHelper.swift +12 -33
  55. data/snapshot/lib/snapshot/.options.rb.swp +0 -0
  56. data/snapshot/lib/snapshot/.test_command_generator_base.rb.swp +0 -0
  57. data/snapshot/lib/snapshot/detect_values.rb +15 -0
  58. data/snapshot/lib/snapshot/options.rb +22 -1
  59. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +3 -1
  60. data/snapshot/lib/snapshot/test_command_generator_base.rb +7 -1
  61. data/spaceship/lib/spaceship/commands_generator.rb +1 -0
  62. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
  63. data/supply/lib/supply/commands_generator.rb +1 -0
  64. data/supply/lib/supply/options.rb +9 -0
  65. data/supply/lib/supply/uploader.rb +4 -0
  66. metadata +25 -24
  67. data/supply/lib/supply/.client.rb.swp +0 -0
@@ -18,4 +18,4 @@ class Gymfile: GymfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -19,6 +19,7 @@ public protocol LaneFileProtocol: class {
19
19
  static func runLane(named: String, parameters: [String : String]) -> Bool
20
20
 
21
21
  func recordLaneDescriptions()
22
+ func beforeAll(currentLane: String, parameters: [String : String])
22
23
  func beforeAll()
23
24
  func afterAll(currentLane: String)
24
25
  func onError(currentLane: String, errorInfo: String)
@@ -26,6 +27,7 @@ public protocol LaneFileProtocol: class {
26
27
 
27
28
  public extension LaneFileProtocol {
28
29
  var fastlaneVersion: String { return "" } // default "" because that means any is fine
30
+ func beforeAll(currentLane: String, parameters: [String : String]) { } // no op by default
29
31
  func beforeAll() { } // no op by default
30
32
  func afterAll(currentLane: String) { } // no op by default
31
33
  func onError(currentLane: String, errorInfo: String) {} // no op by default
@@ -37,7 +39,8 @@ public class LaneFile: NSObject, LaneFileProtocol {
37
39
  private(set) static var fastfileInstance: Fastfile?
38
40
 
39
41
  // Called before any lane is executed.
40
- private func setupAllTheThings() {
42
+ private func setupAllTheThings(lane: String, parameters: [String : String]) {
43
+ LaneFile.fastfileInstance!.beforeAll(currentLane: lane, parameters: parameters)
41
44
  LaneFile.fastfileInstance!.beforeAll()
42
45
  }
43
46
 
@@ -123,7 +126,7 @@ public class LaneFile: NSObject, LaneFileProtocol {
123
126
  }
124
127
 
125
128
  // call all methods that need to be called before we start calling lanes
126
- fastfileInstance.setupAllTheThings()
129
+ fastfileInstance.setupAllTheThings(lane: named, parameters: parameters)
127
130
 
128
131
  // We need to catch all possible errors here and display a nice message
129
132
  _ = fastfileInstance.perform(NSSelectorFromString(laneMethod), with: parameters)
@@ -18,4 +18,4 @@ class Matchfile: MatchfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -102,6 +102,9 @@ protocol MatchfileProtocol: class {
102
102
  /// A custom name for the provisioning profile. This will replace the default provisioning profile name if specified
103
103
  var profileName: String? { get }
104
104
 
105
+ /// Should the command fail if it was about to create a duplicate of an existing provisioning profile. It can happen due to issues on Apple Developer Portal, when profile to be recreated was not properly deleted first
106
+ var failOnNameTaken: Bool { get }
107
+
105
108
  /// Path in which to export certificates, key and profile
106
109
  var outputPath: String? { get }
107
110
 
@@ -144,10 +147,11 @@ extension MatchfileProtocol {
144
147
  var platform: String { return "ios" }
145
148
  var templateName: String? { return nil }
146
149
  var profileName: String? { return nil }
150
+ var failOnNameTaken: Bool { return false }
147
151
  var outputPath: String? { return nil }
148
152
  var verbose: Bool { return false }
149
153
  }
150
154
 
151
155
  // Please don't remove the lines below
152
156
  // They are used to detect outdated files
153
- // FastlaneRunnerAPIVersion [0.9.16]
157
+ // FastlaneRunnerAPIVersion [0.9.17]
@@ -18,4 +18,4 @@ class Precheckfile: PrecheckfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -18,4 +18,4 @@ class Scanfile: ScanfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -45,6 +45,12 @@ protocol ScanfileProtocol: class {
45
45
  /// The testplan associated with the scheme that should be used for testing
46
46
  var testplan: String? { get }
47
47
 
48
+ /// Array of strings matching test plan configurations to run
49
+ var onlyTestConfigurations: String? { get }
50
+
51
+ /// Array of strings matching test plan configurations to skip
52
+ var skipTestConfigurations: String? { get }
53
+
48
54
  /// Run tests using the provided `.xctestrun` file
49
55
  var xctestrun: String? { get }
50
56
 
@@ -200,6 +206,8 @@ extension ScanfileProtocol {
200
206
  var onlyTesting: String? { return nil }
201
207
  var skipTesting: String? { return nil }
202
208
  var testplan: String? { return nil }
209
+ var onlyTestConfigurations: String? { return nil }
210
+ var skipTestConfigurations: String? { return nil }
203
211
  var xctestrun: String? { return nil }
204
212
  var toolchain: String? { return nil }
205
213
  var clean: Bool { return false }
@@ -250,4 +258,4 @@ extension ScanfileProtocol {
250
258
 
251
259
  // Please don't remove the lines below
252
260
  // They are used to detect outdated files
253
- // FastlaneRunnerAPIVersion [0.9.28]
261
+ // FastlaneRunnerAPIVersion [0.9.29]
@@ -18,4 +18,4 @@ class Screengrabfile: ScreengrabfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -18,4 +18,4 @@ class Snapshotfile: SnapshotfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.147.0
21
+ // Generated with fastlane 2.148.0
@@ -113,6 +113,12 @@ protocol SnapshotfileProtocol: class {
113
113
 
114
114
  /// The testplan associated with the scheme that should be used for testing
115
115
  var testplan: String? { get }
116
+
117
+ /// Array of strings matching Test Bundle/Test Suite/Test Cases to run
118
+ var onlyTesting: String? { get }
119
+
120
+ /// Array of strings matching Test Bundle/Test Suite/Test Cases to skip
121
+ var skipTesting: String? { get }
116
122
  }
117
123
 
118
124
  extension SnapshotfileProtocol {
@@ -154,8 +160,10 @@ extension SnapshotfileProtocol {
154
160
  var disableSlideToType: Bool { return false }
155
161
  var clonedSourcePackagesPath: String? { return nil }
156
162
  var testplan: String? { return nil }
163
+ var onlyTesting: String? { return nil }
164
+ var skipTesting: String? { return nil }
157
165
  }
158
166
 
159
167
  // Please don't remove the lines below
160
168
  // They are used to detect outdated files
161
- // FastlaneRunnerAPIVersion [0.9.8]
169
+ // FastlaneRunnerAPIVersion [0.9.9]
@@ -30,6 +30,7 @@ module Frameit
30
30
  program :help_formatter, :compact
31
31
 
32
32
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
33
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
33
34
 
34
35
  default_command(:run)
35
36
 
@@ -53,6 +53,10 @@ module Gym
53
53
  generator.asset_packs_path
54
54
  end
55
55
 
56
+ def appstore_info_path
57
+ generator.appstore_info_path
58
+ end
59
+
56
60
  # The generator we need to use for the currently used Xcode version
57
61
  # Since we dropped Xcode 6 support, it's just this class, but maybe we'll have
58
62
  # new classes in the future
@@ -141,6 +141,10 @@ module Gym
141
141
  Gym.cache[:asset_packs_path] ||= File.join(temporary_output_path, "OnDemandResources")
142
142
  end
143
143
 
144
+ def appstore_info_path
145
+ Gym.cache[:appstore_info_path] ||= File.join(temporary_output_path, "AppStoreInfo.plist")
146
+ end
147
+
144
148
  private
145
149
 
146
150
  def normalize_export_options(hash)
@@ -40,6 +40,7 @@ module Gym
40
40
  move_app_thinning_size_report
41
41
  move_apps_folder
42
42
  move_asset_packs
43
+ move_appstore_info
43
44
  elsif is_mac
44
45
  path = File.expand_path(Gym.config[:output_directory])
45
46
  compress_and_move_dsym
@@ -49,6 +50,7 @@ module Gym
49
50
 
50
51
  package_app
51
52
  path = move_pkg
53
+ move_appstore_info
52
54
  return path
53
55
  end
54
56
  copy_files_from_path(File.join(BuildCommandGenerator.archive_path, "Products/usr/local/bin/*")) if Gym.project.command_line_tool?
@@ -339,6 +341,18 @@ module Gym
339
341
  end
340
342
  end
341
343
 
344
+ # Move the AppStoreInfo.plist folder to the output directory
345
+ def move_appstore_info
346
+ if File.exist?(PackageCommandGenerator.appstore_info_path)
347
+ FileUtils.mv(PackageCommandGenerator.appstore_info_path, File.expand_path(Gym.config[:output_directory]), force: true)
348
+ appstore_info_path = File.join(File.expand_path(Gym.config[:output_directory]), File.basename(PackageCommandGenerator.appstore_info_path))
349
+
350
+ UI.success("Successfully exported the AppStoreInfo.plist file:")
351
+ UI.message(appstore_info_path)
352
+ appstore_info_path
353
+ end
354
+ end
355
+
342
356
  def find_archive_path
343
357
  Dir.glob(File.join(BuildCommandGenerator.build_path, "*.ipa")).last
344
358
  end
@@ -35,6 +35,7 @@ module Match
35
35
  program :help_formatter, :compact
36
36
 
37
37
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
38
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
38
39
 
39
40
  command :run do |c|
40
41
  c.syntax = 'fastlane match'
@@ -76,7 +76,8 @@ module Match
76
76
  ignore_profiles_with_different_name: true,
77
77
  team_id: params[:team_id],
78
78
  team_name: params[:team_name],
79
- template_name: params[:template_name]
79
+ template_name: params[:template_name],
80
+ fail_on_name_taken: params[:fail_on_name_taken]
80
81
  }
81
82
 
82
83
  values[:platform] = params[:platform]
@@ -1,4 +1,5 @@
1
1
  require 'fastlane_core/configuration/config_item'
2
+ require 'fastlane/helper/lane_helper'
2
3
  require 'credentials_manager/appfile_config'
3
4
  require_relative 'module'
4
5
 
@@ -10,6 +11,15 @@ module Match
10
11
  @available_options << option
11
12
  end
12
13
 
14
+ def self.default_platform
15
+ case Fastlane::Helper::LaneHelper.current_platform.to_s
16
+ when "mac"
17
+ "macos"
18
+ else
19
+ "ios"
20
+ end
21
+ end
22
+
13
23
  def self.available_options
14
24
  user = CredentialsManager::AppfileConfig.try_fetch_value(:apple_dev_portal_id)
15
25
  user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
@@ -215,7 +225,8 @@ module Match
215
225
  short_option: '-o',
216
226
  env_name: "MATCH_PLATFORM",
217
227
  description: "Set the provisioning profile's platform to work with (i.e. ios, tvos, macos)",
218
- default_value: "ios",
228
+ default_value: default_platform,
229
+ default_value_dynamic: true,
219
230
  verify_block: proc do |value|
220
231
  value = value.to_s
221
232
  pt = %w(tvos ios macos)
@@ -231,6 +242,12 @@ module Match
231
242
  description: "A custom name for the provisioning profile. This will replace the default provisioning profile name if specified",
232
243
  optional: true,
233
244
  default_value: nil),
245
+ FastlaneCore::ConfigItem.new(key: :fail_on_name_taken,
246
+ env_name: "MATCH_FAIL_ON_NAME_TAKEN",
247
+ description: "Should the command fail if it was about to create a duplicate of an existing provisioning profile. It can happen due to issues on Apple Developer Portal, when profile to be recreated was not properly deleted first",
248
+ optional: true,
249
+ type: Boolean,
250
+ default_value: false),
234
251
  FastlaneCore::ConfigItem.new(key: :output_path,
235
252
  env_name: "MATCH_OUTPUT_PATH",
236
253
  description: "Path in which to export certificates, key and profile",
@@ -25,6 +25,7 @@ module PEM
25
25
  program :help_formatter, :compact
26
26
 
27
27
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
28
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
28
29
 
29
30
  command :renew do |c|
30
31
  c.syntax = 'fastlane pem renew'
@@ -154,13 +154,11 @@ module Pilot
154
154
 
155
155
  return if config[:skip_submission]
156
156
  if options[:reject_build_waiting_for_review]
157
- waiting_for_review_build = build.app.get_builds(filter: { "betaAppReviewSubmission.betaReviewState" => "WAITING_FOR_REVIEW" }, includes: "betaAppReviewSubmission,preReleaseVersion").first
158
- unless waiting_for_review_build.nil?
159
- UI.important("Another build is already in review. Going to remove that build and submit the new one.")
160
- UI.important("Deleting beta app review submission for build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
161
- waiting_for_review_build.beta_app_review_submission.delete!
162
- UI.success("Deleted beta app review submission for previous build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
163
- end
157
+ reject_build_waiting_for_review(build)
158
+ end
159
+
160
+ if options[:expire_previous_builds]
161
+ expire_previous_builds(build)
164
162
  end
165
163
 
166
164
  if !build.ready_for_internal_testing? && options[:skip_waiting_for_build_processing]
@@ -318,6 +316,24 @@ module Pilot
318
316
  !options[:localized_build_info].nil?
319
317
  end
320
318
 
319
+ def reject_build_waiting_for_review(build)
320
+ waiting_for_review_build = build.app.get_builds(filter: { "betaAppReviewSubmission.betaReviewState" => "WAITING_FOR_REVIEW" }, includes: "betaAppReviewSubmission,preReleaseVersion").first
321
+ unless waiting_for_review_build.nil?
322
+ UI.important("Another build is already in review. Going to remove that build and submit the new one.")
323
+ UI.important("Deleting beta app review submission for build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
324
+ waiting_for_review_build.beta_app_review_submission.delete!
325
+ UI.success("Deleted beta app review submission for previous build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
326
+ end
327
+ end
328
+
329
+ def expire_previous_builds(build)
330
+ builds_to_expire = build.app.get_builds.reject do |asc_build|
331
+ asc_build.id == build.id
332
+ end
333
+
334
+ builds_to_expire.each(&:expire!)
335
+ end
336
+
321
337
  # If itc_provider was explicitly specified, use it.
322
338
  # If there are multiple teams, infer the provider from the selected team name.
323
339
  # If there are fewer than two teams, don't infer the provider.
@@ -170,6 +170,11 @@ module Pilot
170
170
  env_name: "PILOT_BUILD_NUMBER",
171
171
  description: "The build number of the application build to distribute. If the build number is not specified, the most recent build is distributed",
172
172
  optional: true),
173
+ FastlaneCore::ConfigItem.new(key: :expire_previous_builds,
174
+ is_string: false,
175
+ env_name: "PILOT_EXPIRE_PREVIOUS_BUILDS",
176
+ description: "Should expire previous builds?",
177
+ default_value: false),
173
178
 
174
179
  # testers
175
180
  FastlaneCore::ConfigItem.new(key: :first_name,
@@ -26,6 +26,7 @@ module Produce
26
26
  program :help_formatter, :compact
27
27
 
28
28
  global_option('--verbose') { FastlaneCore::Globals.verbose = true }
29
+ global_option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
29
30
 
30
31
  command :create do |c|
31
32
  c.syntax = 'fastlane produce create'
@@ -45,6 +45,9 @@ module Scan
45
45
  coerce_to_array_of_strings(:only_testing)
46
46
  coerce_to_array_of_strings(:skip_testing)
47
47
 
48
+ coerce_to_array_of_strings(:only_test_configurations)
49
+ coerce_to_array_of_strings(:skip_test_configurations)
50
+
48
51
  return config
49
52
  end
50
53
 
@@ -123,12 +123,30 @@ module Scan
123
123
  verify_type('skip_testing', [Array, String], value)
124
124
  end),
125
125
 
126
- # other test options
126
+ # test plans to run
127
127
  FastlaneCore::ConfigItem.new(key: :testplan,
128
128
  env_name: "SCAN_TESTPLAN",
129
129
  description: "The testplan associated with the scheme that should be used for testing",
130
130
  is_string: true,
131
131
  optional: true),
132
+ FastlaneCore::ConfigItem.new(key: :only_test_configurations,
133
+ env_name: "SCAN_ONLY_TEST_CONFIGURATIONS",
134
+ description: "Array of strings matching test plan configurations to run",
135
+ optional: true,
136
+ is_string: false,
137
+ verify_block: proc do |value|
138
+ verify_type('only_test_configurations', [Array, String], value)
139
+ end),
140
+ FastlaneCore::ConfigItem.new(key: :skip_test_configurations,
141
+ env_name: "SCAN_SKIP_TEST_CONFIGURATIONS",
142
+ description: "Array of strings matching test plan configurations to skip",
143
+ optional: true,
144
+ is_string: false,
145
+ verify_block: proc do |value|
146
+ verify_type('skip_test_configurations', [Array, String], value)
147
+ end),
148
+
149
+ # other test options
132
150
  FastlaneCore::ConfigItem.new(key: :xctestrun,
133
151
  short_option: "-X",
134
152
  env_name: "SCAN_XCTESTRUN",
@@ -37,8 +37,8 @@ module Scan
37
37
  options << "-toolchain '#{config[:toolchain]}'" if config[:toolchain]
38
38
  options << "-derivedDataPath '#{config[:derived_data_path]}'" if config[:derived_data_path]
39
39
  options << "-resultBundlePath '#{result_bundle_path}'" if config[:result_bundle]
40
- options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
41
40
  if FastlaneCore::Helper.xcode_at_least?(10)
41
+ options << "-parallel-testing-worker-count #{config[:concurrent_workers]}" if config[:concurrent_workers]
42
42
  options << "-maximum-concurrent-test-simulator-destinations #{config[:max_concurrent_simulators]}" if config[:max_concurrent_simulators]
43
43
  options << "-disable-concurrent-testing" if config[:disable_concurrent_testing]
44
44
  end
@@ -47,6 +47,11 @@ module Scan
47
47
  options << "-enableThreadSanitizer #{config[:thread_sanitizer] ? 'YES' : 'NO'}" unless config[:thread_sanitizer].nil?
48
48
  if FastlaneCore::Helper.xcode_at_least?(11)
49
49
  options << "-testPlan '#{config[:testplan]}'" if config[:testplan]
50
+
51
+ # detect_values will ensure that these values are present as Arrays if
52
+ # they are present at all
53
+ options += config[:only_test_configurations].map { |name| "-only-test-configuration '#{name}'" } if config[:only_test_configurations]
54
+ options += config[:skip_test_configurations].map { |name| "-skip-test-configuration '#{name}'" } if config[:skip_test_configurations]
50
55
  end
51
56
  options << "-xctestrun '#{config[:xctestrun]}'" if config[:xctestrun]
52
57
  options << config[:xcargs] if config[:xcargs]
@@ -57,7 +57,7 @@ module Screengrab
57
57
  device_serial = select_device
58
58
 
59
59
  device_screenshots_paths = [
60
- determine_external_screenshots_path(device_serial),
60
+ determine_external_screenshots_path(device_serial, @config[:locales]),
61
61
  determine_internal_screenshots_paths(@config[:app_package_name], @config[:locales])
62
62
  ].flatten
63
63
 
@@ -130,7 +130,7 @@ module Screengrab
130
130
  Dir.glob(File.join(output_directory, '**', device_type, '*.png'), File::FNM_CASEFOLD)
131
131
  end
132
132
 
133
- def determine_external_screenshots_path(device_serial)
133
+ def determine_external_screenshots_path(device_serial, locales)
134
134
  # macOS evaluates $foo in `echo $foo` before executing the command,
135
135
  # Windows doesn't - hence the double backslash vs. single backslash
136
136
  command = Helper.windows? ? "shell echo \$EXTERNAL_STORAGE " : "shell echo \\$EXTERNAL_STORAGE"
@@ -138,22 +138,23 @@ module Screengrab
138
138
  print_all: true,
139
139
  print_command: true)
140
140
  device_ext_storage = device_ext_storage.strip
141
- File.join(device_ext_storage, @config[:app_package_name], 'screengrab')
141
+ return locales.map do |locale|
142
+ File.join(device_ext_storage, @config[:app_package_name], 'screengrab', locale, "images", "screenshots")
143
+ end.flatten
142
144
  end
143
145
 
144
146
  def determine_internal_screenshots_paths(app_package_name, locales)
145
- locale_paths = locales.map do |locale|
147
+ return locales.map do |locale|
146
148
  [
147
149
  "/data/user/0/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots",
148
150
 
149
151
  # https://github.com/fastlane/fastlane/issues/15653#issuecomment-578541663
150
- "/data/data/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots"
152
+ "/data/data/#{app_package_name}/files/#{app_package_name}/screengrab/#{locale}/images/screenshots",
153
+
154
+ "/data/data/#{app_package_name}/app_screengrab/#{locale}/images/screenshots",
155
+ "/data/data/#{app_package_name}/screengrab/#{locale}/images/screenshots"
151
156
  ]
152
157
  end.flatten
153
-
154
- return ["/data/data/#{app_package_name}/app_screengrab"] +
155
- ["/data/data/#{app_package_name}/screengrab"] +
156
- locale_paths
157
158
  end
158
159
 
159
160
  def clear_device_previous_screenshots(device_serial, device_screenshots_paths)