fastlane 2.69.0.beta.20171212010004 → 2.69.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/deliver/lib/assets/DeliverfileDefault.swift +13 -0
  3. data/deliver/lib/deliver/commands_generator.rb +2 -1
  4. data/deliver/lib/deliver/options.rb +8 -3
  5. data/deliver/lib/deliver/setup.rb +19 -3
  6. data/fastlane/lib/assets/AppfileTemplate.swift +8 -0
  7. data/fastlane/lib/assets/DefaultFastfileTemplate.swift +72 -0
  8. data/fastlane/lib/fastlane.rb +6 -0
  9. data/fastlane/lib/fastlane/.DS_Store +0 -0
  10. data/fastlane/lib/fastlane/action.rb +13 -0
  11. data/fastlane/lib/fastlane/actions/adb.rb +4 -0
  12. data/fastlane/lib/fastlane/actions/appium.rb +2 -0
  13. data/fastlane/lib/fastlane/actions/bundle_install.rb +2 -0
  14. data/fastlane/lib/fastlane/actions/carthage.rb +12 -24
  15. data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +5 -0
  16. data/fastlane/lib/fastlane/actions/cocoapods.rb +2 -1
  17. data/fastlane/lib/fastlane/actions/commit_github_file.rb +4 -0
  18. data/fastlane/lib/fastlane/actions/environment_variable.rb +73 -0
  19. data/fastlane/lib/fastlane/actions/get_version_number.rb +4 -4
  20. data/fastlane/lib/fastlane/actions/increment_build_number.rb +4 -0
  21. data/fastlane/lib/fastlane/actions/increment_version_number.rb +4 -0
  22. data/fastlane/lib/fastlane/actions/is_ci.rb +4 -0
  23. data/fastlane/lib/fastlane/actions/last_git_commit.rb +4 -0
  24. data/fastlane/lib/fastlane/actions/last_git_tag.rb +4 -0
  25. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +4 -0
  26. data/fastlane/lib/fastlane/actions/modify_services.rb +1 -0
  27. data/fastlane/lib/fastlane/actions/number_of_commits.rb +4 -0
  28. data/fastlane/lib/fastlane/actions/podio_item.rb +1 -0
  29. data/fastlane/lib/fastlane/actions/prompt.rb +4 -0
  30. data/fastlane/lib/fastlane/actions/read_podspec.rb +4 -0
  31. data/fastlane/lib/fastlane/actions/register_device.rb +4 -0
  32. data/fastlane/lib/fastlane/actions/register_devices.rb +1 -0
  33. data/fastlane/lib/fastlane/actions/rocket.rb +4 -0
  34. data/fastlane/lib/fastlane/actions/set_github_release.rb +4 -0
  35. data/fastlane/lib/fastlane/actions/sh.rb +5 -0
  36. data/fastlane/lib/fastlane/actions/slather.rb +14 -0
  37. data/fastlane/lib/fastlane/actions/update_urban_airship_configuration.rb +1 -0
  38. data/fastlane/lib/fastlane/actions/xcode_install.rb +4 -0
  39. data/fastlane/lib/fastlane/actions/xcode_server_get_assets.rb +4 -0
  40. data/fastlane/lib/fastlane/actions/zip.rb +4 -0
  41. data/fastlane/lib/fastlane/boolean.rb +5 -0
  42. data/fastlane/lib/fastlane/command_line_handler.rb +6 -1
  43. data/fastlane/lib/fastlane/commands_generator.rb +40 -1
  44. data/fastlane/lib/fastlane/fast_file.rb +5 -1
  45. data/fastlane/lib/fastlane/lane_list.rb +67 -4
  46. data/fastlane/lib/fastlane/lane_manager.rb +3 -69
  47. data/fastlane/lib/fastlane/lane_manager_base.rb +124 -0
  48. data/fastlane/lib/fastlane/runner.rb +2 -2
  49. data/fastlane/lib/fastlane/server/command.rb +70 -0
  50. data/fastlane/lib/fastlane/server/command_executor.rb +9 -0
  51. data/fastlane/lib/fastlane/server/socket_server.rb +212 -0
  52. data/fastlane/lib/fastlane/server/socket_server_action_command_executor.rb +100 -0
  53. data/fastlane/lib/fastlane/setup/setup.rb +7 -2
  54. data/fastlane/lib/fastlane/setup/setup_ios.rb +72 -15
  55. data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +265 -0
  56. data/fastlane/lib/fastlane/swift_fastlane_function.rb +342 -0
  57. data/fastlane/lib/fastlane/swift_lane_manager.rb +246 -0
  58. data/fastlane/lib/fastlane/tools.rb +13 -0
  59. data/fastlane/lib/fastlane/version.rb +1 -1
  60. data/fastlane_core/lib/fastlane_core.rb +3 -0
  61. data/fastlane_core/lib/fastlane_core/analytics/action_launch_context.rb +6 -3
  62. data/fastlane_core/lib/fastlane_core/analytics/analytics_session.rb +7 -0
  63. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +13 -0
  64. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +33 -2
  65. data/fastlane_core/lib/fastlane_core/fastlane_folder.rb +32 -0
  66. data/gym/lib/assets/GymfileTemplate.swift +13 -0
  67. data/gym/lib/gym/commands_generator.rb +14 -2
  68. data/gym/lib/gym/generators/build_command_generator.rb +2 -2
  69. data/gym/lib/gym/options.rb +11 -0
  70. data/match/lib/assets/MatchfileTemplate.swift +9 -0
  71. data/match/lib/match/commands_generator.rb +9 -3
  72. data/match/lib/match/options.rb +1 -0
  73. data/match/lib/match/setup.rb +6 -2
  74. data/precheck/lib/.DS_Store +0 -0
  75. data/precheck/lib/assets/PrecheckfileTemplate +1 -1
  76. data/precheck/lib/assets/PrecheckfileTemplate.swift +19 -0
  77. data/precheck/lib/precheck/commands_generator.rb +13 -2
  78. data/scan/lib/assets/ScanfileTemplate.swift +13 -0
  79. data/scan/lib/scan/commands_generator.rb +14 -2
  80. data/scan/lib/scan/options.rb +6 -0
  81. data/screengrab/lib/assets/ScreengrabfileTemplate.swift +15 -0
  82. data/screengrab/lib/screengrab/commands_generator.rb +2 -1
  83. data/screengrab/lib/screengrab/setup.rb +9 -3
  84. data/snapshot/lib/assets/SnapfileTemplate.swift +41 -0
  85. data/snapshot/lib/snapshot/commands_generator.rb +2 -1
  86. data/snapshot/lib/snapshot/setup.rb +9 -3
  87. data/spaceship/lib/spaceship/client.rb +4 -1
  88. metadata +38 -16
@@ -0,0 +1,100 @@
1
+ require 'fastlane/server/command.rb'
2
+ require 'fastlane/server/command_executor.rb'
3
+
4
+ module Fastlane
5
+ # Handles receiving commands from the socket server, finding the Action to be invoked,
6
+ # invoking it, and returning any return values
7
+ class SocketServerActionCommandExecutor < CommandExecutor
8
+ attr_accessor :runner
9
+ attr_accessor :actions_requiring_special_handling
10
+
11
+ def initialize
12
+ Fastlane.load_actions
13
+ @runner = Runner.new
14
+ @actions_requiring_special_handling = ["sh"].to_set
15
+ end
16
+
17
+ def execute(command: nil, target_object: nil)
18
+ action_name = command.method_name
19
+ action_class_ref = class_ref_for_action(named: action_name)
20
+ parameter_map = {}
21
+ closure_argument_value = nil
22
+
23
+ command.args.each do |arg|
24
+ arg_value = arg.value
25
+ if arg.value_type.to_s.to_sym == :string_closure
26
+ closure = proc { |string_value| closure_argument_value = string_value }
27
+ arg_value = closure
28
+ end
29
+ parameter_map[arg.name.to_sym] = arg_value
30
+ end
31
+
32
+ if @actions_requiring_special_handling.include?(action_name)
33
+ command_return = run_action_requiring_special_handling(
34
+ command: command,
35
+ parameter_map: parameter_map,
36
+ action_return_type: action_class_ref.return_type
37
+ )
38
+ return command_return
39
+ end
40
+
41
+ action_return = run(
42
+ action_named: action_name,
43
+ action_class_ref: action_class_ref,
44
+ parameter_map: parameter_map
45
+ )
46
+
47
+ command_return = CommandReturn.new(
48
+ return_value: action_return,
49
+ return_value_type: action_class_ref.return_type,
50
+ closure_argument_value: closure_argument_value
51
+ )
52
+ return command_return
53
+ end
54
+
55
+ def class_ref_for_action(named: nil)
56
+ class_ref = Actions.action_class_ref(named)
57
+ unless class_ref
58
+ if Fastlane::Actions.formerly_bundled_actions.include?(action)
59
+ # This was a formerly bundled action which is now a plugin.
60
+ UI.verbose(caller.join("\n"))
61
+ UI.user_error!("The action '#{action}' is no longer bundled with fastlane. You can install it using `fastlane add_plugin #{action}`")
62
+ else
63
+ Fastlane::ActionsList.print_suggestions(action)
64
+ UI.user_error!("Action '#{action}' not available, run `fastlane actions` to get a full list")
65
+ end
66
+ end
67
+
68
+ return class_ref
69
+ end
70
+
71
+ def run(action_named: nil, action_class_ref: nil, parameter_map: nil)
72
+ action_return = runner.execute_action(action_named, action_class_ref, [parameter_map], custom_dir: '.', configuration_language: "swift")
73
+ return action_return
74
+ end
75
+
76
+ # Some actions have special handling in fast_file.rb, that means we can't directly call the action
77
+ # but we have to use the same logic that is in fast_file.rb instead.
78
+ # That's where this switch statement comes into play
79
+ def run_action_requiring_special_handling(command: nil, parameter_map: nil, action_return_type: nil)
80
+ action_return = nil
81
+ closure_argument_value = nil # only used if the action uses it
82
+
83
+ case command.method_name
84
+ when "sh"
85
+ error_callback = proc { |string_value| closure_argument_value = string_value }
86
+ command_param = parameter_map[:command]
87
+ log_param = parameter_map[:log]
88
+ action_return = Fastlane::FastFile.sh(command_param, log: log_param, error_callback: error_callback)
89
+ end
90
+
91
+ command_return = CommandReturn.new(
92
+ return_value: action_return,
93
+ return_value_type: action_return_type,
94
+ closure_argument_value: closure_argument_value
95
+ )
96
+
97
+ return command_return
98
+ end
99
+ end
100
+ end
@@ -1,7 +1,7 @@
1
1
  module Fastlane
2
2
  class Setup
3
3
  # Start the setup process
4
- def run(user: nil)
4
+ def run(user: nil, is_swift_fastfile: false)
5
5
  if FastlaneCore::FastlaneFolder.setup? and !Helper.is_test?
6
6
  UI.important("fastlane is already set up at path #{FastlaneCore::FastlaneFolder.path}")
7
7
  return
@@ -26,12 +26,17 @@ module Fastlane
26
26
  end
27
27
 
28
28
  if platform == :ios
29
- SetupIos.new.run(user: user)
29
+ SetupIos.new.run(user: user, is_swift_fastfile: is_swift_fastfile)
30
30
  elsif platform == :android
31
31
  SetupAndroid.new.run
32
32
  else
33
33
  UI.user_error!("Couldn't find platform '#{platform}'")
34
34
  end
35
+
36
+ # Now that we've setup all the things, if we're using Swift, do the first time setup
37
+ if is_swift_fastfile
38
+ Fastlane::SwiftLaneManager.first_time_setup
39
+ end
35
40
  end
36
41
 
37
42
  def is_ios?
@@ -16,7 +16,10 @@ module Fastlane
16
16
  attr_accessor :app_identifier
17
17
  attr_accessor :app_name
18
18
 
19
- def run(user: nil)
19
+ attr_accessor :is_swift_fastfile
20
+
21
+ def run(user: nil, is_swift_fastfile: false)
22
+ self.is_swift_fastfile = is_swift_fastfile
20
23
  self.apple_id = user
21
24
  show_infos
22
25
 
@@ -110,6 +113,11 @@ module Fastlane
110
113
  end
111
114
  enable_deliver
112
115
  generate_fastfile(manually: false)
116
+
117
+ if self.is_swift_fastfile
118
+ update_swift_runner
119
+ end
120
+
113
121
  show_analytics
114
122
  end
115
123
 
@@ -119,6 +127,11 @@ module Fastlane
119
127
  detect_installed_tools # after copying the existing files
120
128
  ask_to_enable_other_tools
121
129
  generate_fastfile(manually: true)
130
+
131
+ if self.is_swift_fastfile
132
+ update_swift_runner
133
+ end
134
+
122
135
  show_analytics
123
136
  end
124
137
 
@@ -141,7 +154,6 @@ module Fastlane
141
154
  FastlaneCore::Project.detect_projects(config)
142
155
  self.project = FastlaneCore::Project.new(config)
143
156
  self.project.select_scheme(preferred_to_include: self.project.project_name)
144
-
145
157
  self.app_identifier = self.project.default_app_identifier # These two vars need to be accessed in order to be set
146
158
  self.app_name = self.project.default_app_name # They are set as a side effect, this could/should be changed down the road
147
159
  end
@@ -197,21 +209,25 @@ module Fastlane
197
209
  end
198
210
 
199
211
  def generate_appfile(manually: false)
200
- template = File.read("#{Fastlane::ROOT}/lib/assets/AppfileTemplate")
212
+ template = File.read(appfile_template_path)
201
213
  if manually
202
214
  ask_for_app_identifier
203
215
  ask_for_apple_id
204
216
  end
205
217
 
206
218
  template.gsub!('[[DEV_PORTAL_TEAM_ID]]', self.dev_portal_team) if self.dev_portal_team
207
-
208
- itc_team = self.itc_team ? "itc_team_id \"#{self.itc_team}\" # iTunes Connect Team ID\n" : ""
209
- template.gsub!('[[ITC_TEAM]]', itc_team)
210
-
211
219
  template.gsub!('[[APP_IDENTIFIER]]', self.app_identifier)
212
220
  template.gsub!('[[APPLE_ID]]', self.apple_id)
213
221
 
214
- path = File.join(folder, 'Appfile')
222
+ if self.is_swift_fastfile
223
+ itc_team = self.itc_team ? "\"#{self.itc_team}\"" : "nil"
224
+ path = File.join(folder, 'Appfile.swift')
225
+ else
226
+ itc_team = self.itc_team ? "itc_team_id \"#{self.itc_team}\" # iTunes Connect Team ID\n" : ""
227
+ path = File.join(folder, 'Appfile')
228
+ end
229
+ template.gsub!('[[ITC_TEAM]]', itc_team)
230
+
215
231
  File.write(path, template)
216
232
  UI.success("Created new file '#{path}'. Edit it to manage your preferred app metadata information.")
217
233
  end
@@ -255,6 +271,7 @@ module Fastlane
255
271
  def detect_installed_tools
256
272
  self.tools = {}
257
273
  self.tools[:snapshot] = File.exist?(File.join(folder, 'Snapfile'))
274
+ self.tools[:snapshot] ||= File.exist?(File.join(folder, 'Snapfile.swift'))
258
275
  self.tools[:cocoapods] = File.exist?(File.join(File.expand_path('..', folder), 'Podfile'))
259
276
  self.tools[:carthage] = File.exist?(File.join(File.expand_path('..', folder), 'Cartfile'))
260
277
  end
@@ -263,36 +280,51 @@ module Fastlane
263
280
  UI.message("Loading up 'deliver', this might take a few seconds")
264
281
  require 'deliver'
265
282
  require 'deliver/setup'
283
+
266
284
  options = FastlaneCore::Configuration.create(Deliver::Options.available_options, {})
267
285
  options[:run_precheck_before_submit] = false # precheck doesn't need to run during init
286
+ options[:username] = self.apple_id if self.apple_id
287
+ options[:app_identifier] = self.app_identifier if self.app_identifier
268
288
 
269
289
  Deliver::Runner.new(options) # to login...
270
- Deliver::Setup.new.run(options)
290
+ Deliver::Setup.new.run(options, is_swift: self.is_swift_fastfile)
271
291
  end
272
292
 
273
293
  def generate_fastfile(manually: false)
274
294
  scheme = self.project.schemes.first unless manually
275
295
 
276
- template = File.read("#{Fastlane::ROOT}/lib/assets/DefaultFastfileTemplate")
296
+ template = File.read(fastfile_template_path)
277
297
 
278
298
  scheme = UI.input("Optional: The scheme name of your app (If you don't need one, just hit Enter): ") unless scheme
279
299
  if scheme.length > 0
280
- template.gsub!('[[SCHEME]]', "(scheme: \"#{scheme}\")")
300
+ if self.is_swift_fastfile
301
+ template.gsub!('[[SCHEME]]', "scheme: \"#{scheme}\"")
302
+ else
303
+ template.gsub!('[[SCHEME]]', "(scheme: \"#{scheme}\")")
304
+ end
281
305
  else
282
306
  template.gsub!('[[SCHEME]]', "")
283
307
  end
284
308
 
285
- template.gsub!('snapshot', '# snapshot') unless self.tools[:snapshot]
286
- template.gsub!('cocoapods', '# cocoapods') unless self.tools[:cocoapods]
287
- template.gsub!('carthage', '# carthage') unless self.tools[:carthage]
288
309
  template.gsub!('[[FASTLANE_VERSION]]', Fastlane::VERSION)
289
310
 
311
+ if self.is_swift_fastfile
312
+ template.gsub!('snapshot()', '// snapshot') unless self.tools[:snapshot]
313
+ template.gsub!('cocoapods()', '// cocoapods()') unless self.tools[:cocoapods]
314
+ template.gsub!('carthage()', '// carthage()') unless self.tools[:carthage]
315
+ path = File.join(folder, 'Fastfile.swift')
316
+ else
317
+ template.gsub!('snapshot', '# snapshot') unless self.tools[:snapshot]
318
+ template.gsub!('cocoapods', '# cocoapods') unless self.tools[:cocoapods]
319
+ template.gsub!('carthage', '# cocoapods') unless self.tools[:carthage]
320
+ path = File.join(folder, 'Fastfile')
321
+ end
322
+
290
323
  self.tools.each do |key, value|
291
324
  UI.message("'#{key}' enabled.".magenta) if value
292
325
  UI.important("'#{key}' not enabled.") unless value
293
326
  end
294
327
 
295
- path = File.join(folder, 'Fastfile')
296
328
  File.write(path, template)
297
329
  UI.success("Created new file '#{path}'. Edit it to manage your own deployment lanes.")
298
330
  end
@@ -301,6 +333,31 @@ module Fastlane
301
333
  FastlaneCore::FastlaneFolder.path
302
334
  end
303
335
 
336
+ def appfile_template_path
337
+ if self.is_swift_fastfile
338
+ return "#{Fastlane::ROOT}/lib/assets/AppfileTemplate.swift"
339
+ else
340
+ return "#{Fastlane::ROOT}/lib/assets/AppfileTemplate"
341
+ end
342
+ end
343
+
344
+ def fastfile_template_path
345
+ if self.is_swift_fastfile
346
+ return "#{Fastlane::ROOT}/lib/assets/DefaultFastfileTemplate.swift"
347
+ else
348
+ return "#{Fastlane::ROOT}/lib/assets/DefaultFastfileTemplate"
349
+ end
350
+ end
351
+
352
+ def update_swift_runner
353
+ runner_source_resources = "#{Fastlane::ROOT}/swift/."
354
+
355
+ destination_path = File.expand_path('swift', FastlaneCore::FastlaneFolder.path)
356
+ FileUtils.cp_r(runner_source_resources, destination_path)
357
+
358
+ UI.success("Copied Swift fastlane runner project to '#{destination_path}'.")
359
+ end
360
+
304
361
  def restore_previous_state
305
362
  # Move all moved files back
306
363
  files_to_copy.each do |current|
@@ -0,0 +1,265 @@
1
+ require 'fastlane/swift_fastlane_function.rb'
2
+
3
+ module Fastlane
4
+ class SwiftToolDetail
5
+ attr_accessor :swift_class
6
+ attr_accessor :swift_protocol
7
+ attr_accessor :command_line_tool_name
8
+
9
+ def initialize(command_line_tool_name: nil, swift_class: nil, swift_protocol: nil)
10
+ self.command_line_tool_name = command_line_tool_name
11
+ self.swift_class = swift_class
12
+ self.swift_protocol = swift_protocol
13
+ end
14
+ end
15
+
16
+ class SwiftFastlaneAPIGenerator
17
+ attr_accessor :tools_option_files
18
+ attr_accessor :actions_not_supported
19
+ attr_accessor :action_options_to_ignore
20
+ attr_accessor :target_output_path
21
+
22
+ def initialize(target_output_path: "swift")
23
+ @target_output_path = File.expand_path(target_output_path)
24
+ require 'fastlane'
25
+ require 'fastlane/documentation/actions_list'
26
+ Fastlane.load_actions
27
+ # Tools that can be used with <Toolname>file, like Deliverfile, Screengrabfile
28
+ # this is important because we need to generate the proper api for these by creating a protocol
29
+ # with default implementation we can use in the Fastlane.swift API if people want to use
30
+ # <Toolname>file.swift files.
31
+ self.tools_option_files = TOOL_CONFIG_FILES.map { |config_file| config_file.downcase.chomp("file") }.to_set
32
+
33
+ self.actions_not_supported = ["import", "import_from_git"].to_set
34
+
35
+ self.action_options_to_ignore = {
36
+
37
+ "precheck" => [
38
+ "negative_apple_sentiment",
39
+ "placeholder_text",
40
+ "other_platforms",
41
+ "future_functionality",
42
+ "test_words",
43
+ "curse_words",
44
+ "custom_text",
45
+ "copyright_date",
46
+ "unreachable_urls"
47
+ ].to_set
48
+ }
49
+ end
50
+
51
+ def generate_swift
52
+ file_content = []
53
+ file_content << "import Foundation"
54
+
55
+ tool_details = []
56
+ ActionsList.all_actions do |action|
57
+ next if self.actions_not_supported.include?(action.action_name)
58
+
59
+ swift_function = process_action(action: action)
60
+ if defined?(swift_function.class_name)
61
+ tool_details << SwiftToolDetail.new(
62
+ command_line_tool_name: action.action_name,
63
+ swift_class: swift_function.class_name,
64
+ swift_protocol: swift_function.protocol_name
65
+ )
66
+ end
67
+ unless swift_function
68
+ next
69
+ end
70
+
71
+ file_content << swift_function.swift_code
72
+ end
73
+ file_content << "" # newline because we're adding an extension
74
+ file_content << "// These are all the parsing functions needed to transform our data into the expected types"
75
+ file_content << generate_lanefile_parsing_functions
76
+
77
+ tool_objects = generate_lanefile_tool_objects(classes: tool_details.map(&:swift_class))
78
+ file_content << tool_objects
79
+ file_content += autogen_version_warning_text_array
80
+
81
+ file_content = file_content.join("\n")
82
+ target_path = File.join(@target_output_path, "Fastlane.swift")
83
+ File.write(target_path, file_content)
84
+ UI.success(target_path)
85
+
86
+ generate_default_implementation_opening(tool_details: tool_details)
87
+ end
88
+
89
+ def write_lanefile(lanefile_implementation_opening: nil, class_name: nil, tool_name: nil)
90
+ disclaimer = []
91
+ disclaimer << "// This class is automatically included in FastlaneRunner during build"
92
+ disclaimer << ""
93
+ disclaimer << "// This autogenerated file will be overwritten or replaced during build time, or when you initialize `#{tool_name}`"
94
+ disclaimer << lanefile_implementation_opening
95
+ disclaimer << "// If you want to enable `#{tool_name}`, run `fastlane #{tool_name} init`"
96
+ disclaimer << "// After, this file will be replaced with a custom implementation that contains values you supplied"
97
+ disclaimer << "// during the `init` process, and you won't see this message"
98
+ disclaimer << "}"
99
+ disclaimer << ""
100
+ disclaimer << ""
101
+ disclaimer << ""
102
+ disclaimer << ""
103
+ disclaimer << ""
104
+ disclaimer << "// Generated with fastlane #{Fastlane::VERSION}"
105
+
106
+ file_content = disclaimer.join("\n")
107
+
108
+ target_path = File.join(@target_output_path, "#{class_name}.swift")
109
+ File.write(target_path, file_content)
110
+ UI.success(target_path)
111
+ end
112
+
113
+ def generate_default_implementation_opening(tool_details: nil)
114
+ tool_details.each do |tool_detail|
115
+ lanefile_implementation_opening = "class #{tool_detail.swift_class}: #{tool_detail.swift_protocol} {"
116
+ write_lanefile(
117
+ lanefile_implementation_opening: lanefile_implementation_opening,
118
+ class_name: tool_detail.swift_class,
119
+ tool_name: tool_detail.command_line_tool_name
120
+ )
121
+ end
122
+ end
123
+
124
+ def generate_lanefile_parsing_functions
125
+ parsing_functions = 'func parseArray(fromString: String, function: String = #function) -> [String] {
126
+ verbose(message: "parsing an Array from data: \(fromString), from function: \(function)")
127
+ let potentialArray: String
128
+ if fromString.count < 2 {
129
+ potentialArray = "[\(fromString)]"
130
+ } else {
131
+ potentialArray = fromString
132
+ }
133
+ let array: [String] = try! JSONSerialization.jsonObject(with: potentialArray.data(using: .utf8)!, options: []) as! [String]
134
+ return array
135
+ }
136
+
137
+ func parseDictionary(fromString: String, function: String = #function) -> [String : String] {
138
+ verbose(message: "parsing an Array from data: \(fromString), from function: \(function)")
139
+ let potentialDictionary: String
140
+ if fromString.count < 2 {
141
+ verbose(message: "Dictionary value too small: \(fromString), from function: \(function)")
142
+ potentialDictionary = "{}"
143
+ } else {
144
+ potentialDictionary = fromString
145
+ }
146
+ let dictionary: [String : String] = try! JSONSerialization.jsonObject(with: potentialDictionary.data(using: .utf8)!, options: []) as! [String : String]
147
+ return dictionary
148
+ }
149
+
150
+ func parseBool(fromString: String, function: String = #function) -> Bool {
151
+ verbose(message: "parsing a Bool from data: \(fromString), from function: \(function)")
152
+ return NSString(string: fromString).boolValue
153
+ }
154
+
155
+ func parseInt(fromString: String, function: String = #function) -> Int {
156
+ verbose(message: "parsing a Bool from data: \(fromString), from function: \(function)")
157
+ return NSString(string: fromString).integerValue
158
+ }
159
+ '
160
+ return parsing_functions
161
+ end
162
+
163
+ def generate_lanefile_tool_objects(classes: nil)
164
+ objects = classes.map do |filename|
165
+ "let #{filename.downcase}: #{filename} = #{filename}()"
166
+ end
167
+ return objects
168
+ end
169
+
170
+ def autogen_version_warning_text_array
171
+ warning_text_array = []
172
+ warning_text_array << ""
173
+ warning_text_array << "// Please don't remove the lines below"
174
+ warning_text_array << "// They are used to detect outdated files"
175
+ warning_text_array << "// FastlaneRunnerAPIVersion [0.9.1]"
176
+ warning_text_array << ""
177
+ return warning_text_array
178
+ end
179
+
180
+ def generate_tool_protocol(tool_swift_function: nil)
181
+ protocol_content_array = []
182
+ protocol_name = tool_swift_function.protocol_name
183
+
184
+ protocol_content_array << "protocol #{protocol_name}: class {"
185
+ protocol_content_array += tool_swift_function.swift_vars
186
+ protocol_content_array << "}"
187
+ protocol_content_array << ""
188
+
189
+ protocol_content_array << "extension #{protocol_name} {"
190
+ protocol_content_array += tool_swift_function.swift_default_implementations
191
+ protocol_content_array << "}"
192
+ protocol_content_array << ""
193
+ protocol_content_array += autogen_version_warning_text_array
194
+
195
+ target_path = File.join(@target_output_path, "#{protocol_name}.swift")
196
+ file_content = protocol_content_array.join("\n")
197
+ File.write(target_path, file_content)
198
+ UI.success(target_path)
199
+ end
200
+
201
+ def ignore_param?(function_name: nil, param_name: nil)
202
+ option_set = @action_options_to_ignore[function_name.to_s]
203
+ unless option_set
204
+ return false
205
+ end
206
+
207
+ return option_set.include?(param_name.to_s)
208
+ end
209
+
210
+ def process_action(action: nil)
211
+ unless action.available_options
212
+ return nil
213
+ end
214
+ options = action.available_options
215
+
216
+ action_name = action.action_name
217
+ keys = []
218
+ key_descriptions = []
219
+ key_default_values = []
220
+ key_optionality_values = []
221
+ key_type_overrides = []
222
+
223
+ if options.kind_of? Array
224
+ options.each do |current|
225
+ next unless current.kind_of? FastlaneCore::ConfigItem
226
+
227
+ if ignore_param?(function_name: action_name, param_name: current.key)
228
+ next
229
+ end
230
+
231
+ keys << current.key.to_s
232
+ key_descriptions << current.description
233
+ key_default_values << current.default_value
234
+ key_optionality_values << current.optional
235
+ key_type_overrides << current.data_type
236
+ end
237
+ end
238
+ action_return_type = action.return_type
239
+
240
+ if self.tools_option_files.include?(action_name.to_s.downcase)
241
+ tool_swift_function = ToolSwiftFunction.new(
242
+ action_name: action_name,
243
+ keys: keys,
244
+ key_descriptions: key_descriptions,
245
+ key_default_values: key_default_values,
246
+ key_optionality_values: key_optionality_values,
247
+ key_type_overrides: key_type_overrides,
248
+ return_type: action_return_type
249
+ )
250
+ generate_tool_protocol(tool_swift_function: tool_swift_function)
251
+ return tool_swift_function
252
+ else
253
+ return SwiftFunction.new(
254
+ action_name: action_name,
255
+ keys: keys,
256
+ key_descriptions: key_descriptions,
257
+ key_default_values: key_default_values,
258
+ key_optionality_values: key_optionality_values,
259
+ key_type_overrides: key_type_overrides,
260
+ return_type: action_return_type
261
+ )
262
+ end
263
+ end
264
+ end
265
+ end