fastlane 2.174.0 → 2.175.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +74 -74
  3. data/cert/lib/cert/options.rb +2 -2
  4. data/deliver/lib/deliver/options.rb +2 -2
  5. data/deliver/lib/deliver/upload_screenshots.rb +2 -1
  6. data/fastlane/lib/fastlane/actions/adb.rb +1 -1
  7. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +2 -2
  8. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +1 -1
  9. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  10. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
  11. data/fastlane/lib/fastlane/actions/download_dsyms.rb +5 -15
  12. data/fastlane/lib/fastlane/actions/git_commit.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -2
  14. data/fastlane/lib/fastlane/actions/register_device.rb +2 -2
  15. data/fastlane/lib/fastlane/actions/register_devices.rb +2 -2
  16. data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
  17. data/fastlane/lib/fastlane/actions/swiftlint.rb +1 -1
  18. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +1 -1
  19. data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
  20. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  21. data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
  22. data/fastlane/lib/fastlane/version.rb +1 -1
  23. data/fastlane/swift/Deliverfile.swift +1 -1
  24. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  25. data/fastlane/swift/Fastlane.swift +4 -4
  26. data/fastlane/swift/Gymfile.swift +1 -1
  27. data/fastlane/swift/GymfileProtocol.swift +1 -1
  28. data/fastlane/swift/Matchfile.swift +1 -1
  29. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  30. data/fastlane/swift/Precheckfile.swift +1 -1
  31. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  32. data/fastlane/swift/Scanfile.swift +1 -1
  33. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  34. data/fastlane/swift/Screengrabfile.swift +1 -1
  35. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  36. data/fastlane/swift/Snapshotfile.swift +1 -1
  37. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  38. data/fastlane/swift/formatting/Brewfile.lock.json +4 -2
  39. data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
  40. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +1 -1
  41. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +23 -0
  42. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +2 -4
  43. data/fastlane_core/lib/fastlane_core/helper.rb +26 -5
  44. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -1
  45. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
  46. data/match/lib/match/nuke.rb +5 -0
  47. data/match/lib/match/options.rb +2 -2
  48. data/pilot/lib/pilot/options.rb +2 -2
  49. data/precheck/lib/precheck/options.rb +2 -2
  50. data/screengrab/lib/screengrab/android_environment.rb +2 -2
  51. data/sigh/lib/sigh/options.rb +2 -2
  52. data/spaceship/README.md +2 -2
  53. data/spaceship/lib/spaceship/connect_api/token.rb +1 -1
  54. data/spaceship/lib/spaceship/playground.rb +2 -2
  55. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  56. metadata +32 -18
@@ -118,7 +118,7 @@ module Fastlane
118
118
  UI.user_error!("Could not find file '#{value}'") unless File.exist?(value)
119
119
  end),
120
120
  FastlaneCore::ConfigItem.new(key: :api_key_path,
121
- env_name: "FL_REGISTER_DEVICES_API_KEY_PATH",
121
+ env_names: ["FL_REGISTER_DEVICES_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
122
122
  description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
123
123
  optional: true,
124
124
  conflicting_options: [:api_key],
@@ -126,7 +126,7 @@ module Fastlane
126
126
  UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
127
127
  end),
128
128
  FastlaneCore::ConfigItem.new(key: :api_key,
129
- env_name: "FL_REGISTER_DEVICES_API_KEY",
129
+ env_names: ["FL_REGISTER_DEVICES_API_KEY", "APP_STORE_CONNECT_API_KEY"],
130
130
  description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
131
131
  type: Hash,
132
132
  optional: true,
@@ -111,7 +111,7 @@ module Fastlane
111
111
 
112
112
  [
113
113
  FastlaneCore::ConfigItem.new(key: :api_key_path,
114
- env_name: "FL_SET_CHANGELOG_API_KEY_PATH",
114
+ env_names: ["FL_SET_CHANGELOG_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
115
115
  description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
116
116
  optional: true,
117
117
  conflicting_options: [:api_key],
@@ -119,7 +119,7 @@ module Fastlane
119
119
  UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
120
120
  end),
121
121
  FastlaneCore::ConfigItem.new(key: :api_key,
122
- env_name: "FL_SET_CHANGELOG_API_KEY",
122
+ env_names: ["FL_SET_CHANGELOG_API_KEY", "APP_STORE_CONNECT_API_KEY"],
123
123
  description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
124
124
  type: Hash,
125
125
  optional: true,
@@ -145,7 +145,7 @@ module Fastlane
145
145
  optional: true,
146
146
  verify_block: proc do |value|
147
147
  available = ['xcode', 'json', 'csv', 'checkstyle', 'codeclimate', 'junit', 'html', 'emoji', 'sonarqube', 'markdown', 'github-actions-logging']
148
- UI.warning("Known 'reporter' values are '#{available.join("', '")}'. If you're receiving errors from swiftlint related to the reporter, make sure the reporter identifier you're using is correct and it's supported by your version of swiftlint.") unless available.include?(value)
148
+ UI.important("Known 'reporter' values are '#{available.join("', '")}'. If you're receiving errors from swiftlint related to the reporter, make sure the reporter identifier you're using is correct and it's supported by your version of swiftlint.") unless available.include?(value)
149
149
  end),
150
150
  FastlaneCore::ConfigItem.new(key: :quiet,
151
151
  env_name: "FL_SWIFTLINT_QUIET",
@@ -140,7 +140,7 @@ module Fastlane
140
140
  env_name: "FL_PROJECT_SIGNING_BUILD_CONFIGURATIONS",
141
141
  optional: true,
142
142
  type: Array,
143
- description: "Specify build_configurations you want to toggle the signing mech. (default to all targets)",
143
+ description: "Specify build_configurations you want to toggle the signing mech. (default to all configurations)",
144
144
  is_string: false),
145
145
  FastlaneCore::ConfigItem.new(key: :code_sign_identity,
146
146
  env_name: "FL_CODE_SIGN_IDENTITY",
@@ -135,7 +135,7 @@ module Fastlane
135
135
  if options
136
136
  puts(Terminal::Table.new(
137
137
  title: "#{name} Options".green,
138
- headings: ['Key', 'Description', 'Env Var', 'Default'],
138
+ headings: ['Key', 'Description', 'Env Var(s)', 'Default'],
139
139
  rows: FastlaneCore::PrintTable.transform_output(options)
140
140
  ))
141
141
  else
@@ -197,7 +197,7 @@ module Fastlane
197
197
  if options.kind_of?(Array)
198
198
  options.each do |current|
199
199
  if current.kind_of?(FastlaneCore::ConfigItem)
200
- rows << [current.key.to_s.yellow, current.deprecated ? current.description.red : current.description, current.env_name, current.help_default_value]
200
+ rows << [current.key.to_s.yellow, current.deprecated ? current.description.red : current.description, current.env_names.join(", "), current.help_default_value]
201
201
  elsif current.kind_of?(Array)
202
202
  # Legacy actions that don't use the new config manager
203
203
  UI.user_error!("Invalid number of elements in this row: #{current}. Must be 2 or 3") unless [2, 3].include?(current.count)
@@ -24,7 +24,7 @@ module Fastlane
24
24
  adb_path = File.join(android_home, "platform-tools", "adb")
25
25
  end
26
26
 
27
- self.adb_path = File.expand_path(adb_path)
27
+ self.adb_path = Helper.get_executable_path(File.expand_path(adb_path))
28
28
  self.adb_host = adb_host
29
29
  end
30
30
 
@@ -10,8 +10,8 @@ module Fastlane
10
10
  rescue Gem::LoadError
11
11
  UI.error("Could not find gem '#{gem_name}'")
12
12
  UI.error("")
13
- UI.error("If you installed fastlane using `sudo gem install fastlane` run")
14
- UI.command("sudo gem install #{gem_name}")
13
+ UI.error("If you installed fastlane using `gem install fastlane` run")
14
+ UI.command("gem install #{gem_name}")
15
15
  UI.error("to install the missing gem")
16
16
  UI.error("")
17
17
  UI.error("If you use a Gemfile add this to your Gemfile:")
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.174.0'.freeze
2
+ VERSION = '2.175.0'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  RUBOCOP_REQUIREMENT = '0.49.1'.freeze
@@ -17,4 +17,4 @@ public class Deliverfile: DeliverfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -256,4 +256,4 @@ public extension DeliverfileProtocol {
256
256
 
257
257
  // Please don't remove the lines below
258
258
  // They are used to detect outdated files
259
- // FastlaneRunnerAPIVersion [0.9.57]
259
+ // FastlaneRunnerAPIVersion [0.9.58]
@@ -8,7 +8,7 @@ import Foundation
8
8
  - parameters:
9
9
  - serial: Android serial of the device to use for this command
10
10
  - command: All commands you want to pass to the adb command, e.g. `kill-server`
11
- - adbPath: The path to your `adb` binary (can be left blank if the ANDROID_SDK_ROOT environment variable is set)
11
+ - adbPath: The path to your `adb` binary (can be left blank if the ANDROID_SDK_ROOT, ANDROID_HOME or ANDROID_SDK environment variable is set)
12
12
 
13
13
  - returns: The output of the adb command
14
14
 
@@ -3845,7 +3845,7 @@ public func gitAdd(path: Any? = nil,
3845
3845
  Directly commit the given file with the given message
3846
3846
 
3847
3847
  - parameters:
3848
- - path: The file you want to commit
3848
+ - path: The file(s) or directory(ies) you want to commit. You can pass an array of multiple file-paths or fileglobs "*.txt" to commit all matching files. The files already staged but not specified and untracked files won't be committed
3849
3849
  - message: The commit message that should be used
3850
3850
  - skipGitHooks: Set to true to pass --no-verify to git
3851
3851
  - allowNothingToCommit: Set to true to allow commit without any git changes in the files you want to commit
@@ -8338,7 +8338,7 @@ public func updateAppIdentifier(xcodeproj: String,
8338
8338
  - useAutomaticSigning: Defines if project should use automatic signing
8339
8339
  - teamId: Team ID, is used when upgrading project
8340
8340
  - targets: Specify targets you want to toggle the signing mech. (default to all targets)
8341
- - buildConfigurations: Specify build_configurations you want to toggle the signing mech. (default to all targets)
8341
+ - buildConfigurations: Specify build_configurations you want to toggle the signing mech. (default to all configurations)
8342
8342
  - codeSignIdentity: Code signing identity type (iPhone Developer, iPhone Distribution)
8343
8343
  - profileName: Provisioning profile name to use for code signing
8344
8344
  - profileUuid: Provisioning profile UUID to use for code signing
@@ -9645,4 +9645,4 @@ public let snapshotfile = Snapshotfile()
9645
9645
 
9646
9646
  // Please don't remove the lines below
9647
9647
  // They are used to detect outdated files
9648
- // FastlaneRunnerAPIVersion [0.9.110]
9648
+ // FastlaneRunnerAPIVersion [0.9.111]
@@ -17,4 +17,4 @@ public class Gymfile: GymfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -196,4 +196,4 @@ public extension GymfileProtocol {
196
196
 
197
197
  // Please don't remove the lines below
198
198
  // They are used to detect outdated files
199
- // FastlaneRunnerAPIVersion [0.9.60]
199
+ // FastlaneRunnerAPIVersion [0.9.61]
@@ -17,4 +17,4 @@ public class Matchfile: MatchfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -184,4 +184,4 @@ public extension MatchfileProtocol {
184
184
 
185
185
  // Please don't remove the lines below
186
186
  // They are used to detect outdated files
187
- // FastlaneRunnerAPIVersion [0.9.54]
187
+ // FastlaneRunnerAPIVersion [0.9.55]
@@ -17,4 +17,4 @@ public class Precheckfile: PrecheckfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -52,4 +52,4 @@ public extension PrecheckfileProtocol {
52
52
 
53
53
  // Please don't remove the lines below
54
54
  // They are used to detect outdated files
55
- // FastlaneRunnerAPIVersion [0.9.53]
55
+ // FastlaneRunnerAPIVersion [0.9.54]
@@ -17,4 +17,4 @@ public class Scanfile: ScanfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -280,4 +280,4 @@ public extension ScanfileProtocol {
280
280
 
281
281
  // Please don't remove the lines below
282
282
  // They are used to detect outdated files
283
- // FastlaneRunnerAPIVersion [0.9.65]
283
+ // FastlaneRunnerAPIVersion [0.9.66]
@@ -17,4 +17,4 @@ public class Screengrabfile: ScreengrabfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -96,4 +96,4 @@ public extension ScreengrabfileProtocol {
96
96
 
97
97
  // Please don't remove the lines below
98
98
  // They are used to detect outdated files
99
- // FastlaneRunnerAPIVersion [0.9.55]
99
+ // FastlaneRunnerAPIVersion [0.9.56]
@@ -17,4 +17,4 @@ public class Snapshotfile: SnapshotfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.174.0
20
+ // Generated with fastlane 2.175.0
@@ -196,4 +196,4 @@ public extension SnapshotfileProtocol {
196
196
 
197
197
  // Please don't remove the lines below
198
198
  // They are used to detect outdated files
199
- // FastlaneRunnerAPIVersion [0.9.49]
199
+ // FastlaneRunnerAPIVersion [0.9.50]
@@ -4,8 +4,10 @@
4
4
  "swiftformat": {
5
5
  "version": "0.47.11",
6
6
  "bottle": {
7
+ "rebuild": 0,
7
8
  "cellar": ":any_skip_relocation",
8
9
  "prefix": "/usr/local",
10
+ "root_url": "https://homebrew.bintray.com/bottles",
9
11
  "files": {
10
12
  "arm64_big_sur": {
11
13
  "url": "https://homebrew.bintray.com/bottles/swiftformat-0.47.11.arm64_big_sur.bottle.tar.gz",
@@ -31,9 +33,9 @@
31
33
  "system": {
32
34
  "macos": {
33
35
  "catalina": {
34
- "HOMEBREW_VERSION": "3.0.0-57-g59dd425",
36
+ "HOMEBREW_VERSION": "3.0.1-93-g53d840c",
35
37
  "HOMEBREW_PREFIX": "/usr/local",
36
- "Homebrew/homebrew-core": "637196b33ecd885dc057c16fc5cb652a4561f632",
38
+ "Homebrew/homebrew-core": "703451fe242d959d029d867909ffd92f0d522ffd",
37
39
  "CLT": "11.0.33.12",
38
40
  "Xcode": "12.2",
39
41
  "macOS": "10.15.7"
@@ -13,16 +13,10 @@ module FastlaneCore
13
13
  #
14
14
  # Derived from https://stackoverflow.com/a/5471032/3005
15
15
  def which(cmd)
16
- # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
17
- # e.g. ".COM;.EXE;.BAT;.CMD"
18
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
19
- exts << '' # Always have an empty string (= no file extension)
20
-
21
16
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
22
- exts.each do |ext|
23
- cmd_path = File.join(path, "#{cmd}#{ext}")
24
- return cmd_path if Helper.executable?(cmd_path)
25
- end
17
+ cmd_path = File.join(path, cmd)
18
+ executable_path = Helper.get_executable_path(cmd_path)
19
+ return executable_path if Helper.executable?(executable_path)
26
20
  end
27
21
 
28
22
  return nil
@@ -67,7 +67,7 @@ module FastlaneCore
67
67
  long_switch = "--#{option.key} #{value_appendix}"
68
68
 
69
69
  description = option.description
70
- description += " (#{option.env_name})" unless option.env_name.to_s.empty?
70
+ description += " (#{option.env_names.join(', ')})" unless option.env_names.empty?
71
71
 
72
72
  # We compact this array here to remove the short_switch variable if it is nil.
73
73
  # Passing a nil value to global_option has been shown to create problems with
@@ -12,6 +12,9 @@ module FastlaneCore
12
12
  # [String] the name of the environment variable, which is only used if no other values were found
13
13
  attr_accessor :env_name
14
14
 
15
+ # [Array] the names of the environment variables, which is only used if no other values were found
16
+ attr_accessor :env_names
17
+
15
18
  # [String] A description shown to the user
16
19
  attr_accessor :description
17
20
 
@@ -71,6 +74,7 @@ module FastlaneCore
71
74
  # Creates a new option
72
75
  # @param key (Symbol) the key which is used as command parameters or key in the fastlane tools
73
76
  # @param env_name (String) the name of the environment variable, which is only used if no other values were found
77
+ # @param env_names (Array) the names of the environment variables, which is only used if no other values were found
74
78
  # @param description (String) A description shown to the user
75
79
  # @param short_option (String) A string of length 1 which is used for the command parameters (e.g. -f)
76
80
  # @param default_value the value which is used if there was no given values and no environment values
@@ -88,8 +92,10 @@ module FastlaneCore
88
92
  # @param sensitive (Boolean) Set if the variable is sensitive, such as a password or API token, to prevent echoing when prompted for the parameter
89
93
  # @param display_in_shell (Boolean) Set if the variable can be used from shell
90
94
  # rubocop:disable Metrics/ParameterLists
95
+ # rubocop:disable Metrics/PerceivedComplexity
91
96
  def initialize(key: nil,
92
97
  env_name: nil,
98
+ env_names: nil,
93
99
  description: nil,
94
100
  short_option: nil,
95
101
  default_value: nil,
@@ -109,6 +115,11 @@ module FastlaneCore
109
115
  UI.user_error!("key must be a symbol") unless key.kind_of?(Symbol)
110
116
  UI.user_error!("env_name must be a String") unless (env_name || '').kind_of?(String)
111
117
 
118
+ UI.user_error!("env_names must be an Array") unless (env_names || []).kind_of?(Array)
119
+ (env_names || []).each do |name|
120
+ UI.user_error!("env_names must only contain String") unless (name || '').kind_of?(String)
121
+ end
122
+
112
123
  if short_option
113
124
  UI.user_error!("short_option for key :#{key} must of type String") unless short_option.kind_of?(String)
114
125
  UI.user_error!("short_option for key :#{key} must be a string of length 1") unless short_option.delete('-').length == 1
@@ -138,6 +149,7 @@ module FastlaneCore
138
149
 
139
150
  @key = key
140
151
  @env_name = env_name
152
+ @env_names = [env_name].compact + (env_names || [])
141
153
  @description = description
142
154
  @short_option = short_option
143
155
  @default_value = default_value
@@ -160,6 +172,7 @@ module FastlaneCore
160
172
 
161
173
  update_code_gen_default_value_if_able!
162
174
  end
175
+ # rubocop:enable Metrics/PerceivedComplexity
163
176
  # rubocop:enable Metrics/ParameterLists
164
177
 
165
178
  # if code_gen_default_value is nil, use the default value if it isn't a `code_gen_sensitive` value
@@ -228,6 +241,16 @@ module FastlaneCore
228
241
  true
229
242
  end
230
243
 
244
+ def fetch_env_value
245
+ env_names.each do |name|
246
+ next if ENV[name].nil?
247
+ # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
248
+ return ENV[name].dup if verify!(auto_convert_value(ENV[name]))
249
+ end
250
+
251
+ return nil
252
+ end
253
+
231
254
  # rubocop:disable Metrics/PerceivedComplexity
232
255
  # Returns an updated value type (if necessary)
233
256
  def auto_convert_value(value)
@@ -209,7 +209,6 @@ module FastlaneCore
209
209
 
210
210
  # Returns the value for a certain key. fastlane_core tries to fetch the value from different sources
211
211
  # if 'ask' is true and the value is not present, the user will be prompted to provide a value
212
- # rubocop:disable Metrics/PerceivedComplexity
213
212
  def fetch(key, ask: true)
214
213
  UI.crash!("Key '#{key}' must be a symbol. Example :app_id.") unless key.kind_of?(Symbol)
215
214
 
@@ -218,9 +217,8 @@ module FastlaneCore
218
217
  # Same order as https://docs.fastlane.tools/advanced/#priorities-of-parameters-and-options
219
218
  value = if @values.key?(key) && !@values[key].nil?
220
219
  @values[key]
221
- elsif option.env_name && !ENV[option.env_name].nil?
222
- # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
223
- ENV[option.env_name].dup if option.verify!(option.auto_convert_value(ENV[option.env_name]))
220
+ elsif (env_value = option.fetch_env_value)
221
+ env_value
224
222
  elsif self.config_file_options.key?(key)
225
223
  self.config_file_options[key]
226
224
  else
@@ -368,8 +368,29 @@ module FastlaneCore
368
368
 
369
369
  # checks if a given path is an executable file
370
370
  def self.executable?(cmd_path)
371
- # no executable files on Windows, so existing is enough there
372
- cmd_path && !File.directory?(cmd_path) && (File.executable?(cmd_path) || (self.windows? && File.exist?(cmd_path)))
371
+ if !cmd_path || File.directory?(cmd_path)
372
+ return false
373
+ end
374
+
375
+ return File.exist?(get_executable_path(cmd_path))
376
+ end
377
+
378
+ # returns the path of the executable with the correct extension on Windows
379
+ def self.get_executable_path(cmd_path)
380
+ if self.windows?
381
+ # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
382
+ # e.g. ".COM;.EXE;.BAT;.CMD"
383
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
384
+
385
+ # no executable files on Windows, so existing is enough there
386
+ # also check if command + ext is present
387
+ exts.each do |ext|
388
+ executable_path = "#{cmd_path}#{ext.downcase}"
389
+ return executable_path if File.exist?(executable_path)
390
+ end
391
+ end
392
+
393
+ return cmd_path
373
394
  end
374
395
 
375
396
  # checks if given file is a valid json file
@@ -425,20 +446,20 @@ module FastlaneCore
425
446
  UI.current.log
426
447
  end
427
448
 
428
- def self.ask_password(message: "Passphrase: ", confirm: nil)
449
+ def self.ask_password(message: "Passphrase: ", confirm: nil, confirmation_message: "Type passphrase again: ")
429
450
  raise "This code should only run in interactive mode" unless UI.interactive?
430
451
 
431
452
  loop do
432
453
  password = UI.password(message)
433
454
  if confirm
434
- password2 = UI.password("Type passphrase again: ")
455
+ password2 = UI.password(confirmation_message)
435
456
  if password == password2
436
457
  return password
437
458
  end
438
459
  else
439
460
  return password
440
461
  end
441
- UI.error("Passphrases differ. Try again")
462
+ UI.error("Your entries do not match. Please try again")
442
463
  end
443
464
  end
444
465
  end
@@ -99,7 +99,7 @@ module FastlaneCore
99
99
  UI.important("Enter the password for #{keychain_path}")
100
100
  UI.important("This passphrase will be stored in your local keychain with the name #{server} and used in future runs")
101
101
  UI.important("This prompt can be avoided by specifying the 'keychain_password' option or 'MATCH_KEYCHAIN_PASSWORD' environment variable")
102
- keychain_password = FastlaneCore::Helper.ask_password(message: "Password for #{keychain_name} keychain: ", confirm: true)
102
+ keychain_password = FastlaneCore::Helper.ask_password(message: "Password for #{keychain_name} keychain: ", confirm: true, confirmation_message: "Type password for #{keychain_name} keychain again: ")
103
103
  Security::InternetPassword.add(server, "", keychain_password)
104
104
  else
105
105
  UI.important("Keychain password for #{keychain_path} was not specified and not found in your keychain. Specify the 'keychain_password' option to prevent the UI permission popup when code signing")