fastlane-plugin-mobile_tools 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26fdd7808252e393694a368045c09ebe1a09ec33bb520a6d0d91178a6150bfc8
4
- data.tar.gz: 7ee6768f01189eabd2cd7fef32ebf6022e32c088eb5438cd3b0abbc78078c29e
3
+ metadata.gz: bd0dd7ecb991b2905afdb6368415ec3004ff7f9aa528c7403fed5f888020eba3
4
+ data.tar.gz: 6f4a29739024b2b4ced1c8f68bba1cf98cd2b6261db93c423efdc07cb112f5a2
5
5
  SHA512:
6
- metadata.gz: e707b3d692c424b21636fb67c2f78ebbb1e67a2f62a40627744dc63320cd3d229f91c3ed7b523d6e06945d3e81081eecaf5f762293e805c650da0f0815ca191c
7
- data.tar.gz: def0229a1e8caca4a092fb46bb285d7fb6eba8b54582a749d0323591d72b150c29e056f228aea52a17d62b2c41d81e67e7a6920d3b275c9896d62f9effedd296
6
+ metadata.gz: 9246660088cf1d2290822fdadd357700bd17d1873ca6b1e87cda1b7c1a2663729d5ab3d16070d02e9122b8678da57798380cf97b4aa256677cb73c9808fb7e05
7
+ data.tar.gz: 31af1947838a34a35fa99ebfdc68beef61143db978fc41214cf34a5ece42e479851438caff500c3a0116e2eeb3483a154ad97cd5b03a9102cd0160fb234c9630
@@ -26,6 +26,10 @@ module Fastlane
26
26
  end
27
27
 
28
28
  create_xcframework(params)
29
+ remove_module_reference(params)
30
+ sign_xcframework(params)
31
+ zip_xcframework(params)
32
+ delete_xcframework(params)
29
33
 
30
34
  copy_dSYMs(params)
31
35
 
@@ -33,19 +37,28 @@ module Fastlane
33
37
 
34
38
  clean(params)
35
39
 
36
- provide_shared_values
40
+
41
+
42
+ provide_shared_values(params)
37
43
  else
38
44
  UI.important('xcframework can be produced only using Xcode 11 and above')
39
45
  end
40
46
  end
41
47
 
42
- def self.provide_shared_values
43
- Actions.lane_context[SharedValues::XCFRAMEWORK_OUTPUT_PATH] = File.expand_path(@xchelper.xcframework_path)
44
- ENV[SharedValues::XCFRAMEWORK_OUTPUT_PATH.to_s] = File.expand_path(@xchelper.xcframework_path)
45
- Actions.lane_context[SharedValues::XCFRAMEWORK_DSYM_OUTPUT_PATH] = File.expand_path(@xchelper.xcframework_dSYMs_path)
46
- ENV[SharedValues::XCFRAMEWORK_DSYM_OUTPUT_PATH.to_s] = File.expand_path(@xchelper.xcframework_dSYMs_path)
47
- Actions.lane_context[SharedValues::XCFRAMEWORK_BCSYMBOLMAPS_OUTPUT_PATH] = File.expand_path(@xchelper.xcframework_BCSymbolMaps_path)
48
- ENV[SharedValues::XCFRAMEWORK_BCSYMBOLMAPS_OUTPUT_PATH.to_s] = File.expand_path(@xchelper.xcframework_BCSymbolMaps_path)
48
+ def self.provide_shared_values(params)
49
+ frameworks = params[:frameworks] || [nil]
50
+ frameworks.each do |framework|
51
+ xcframework_path = framework ? @xchelper.get_xcframework_path(framework) : @xchelper.xcframework_path
52
+ dsyms_path = framework ? @xchelper.framework_dSYMs_path(framework) : @xchelper.xcframework_dSYMs_path
53
+ bcsymbolmaps_path = framework ? @xchelper.framework_BCSymbolMaps_path(framework) : @xchelper.xcframework_BCSymbolMaps_path
54
+
55
+ Actions.lane_context[SharedValues::XCFRAMEWORK_OUTPUT_PATH] = File.expand_path(xcframework_path)
56
+ ENV[SharedValues::XCFRAMEWORK_OUTPUT_PATH.to_s] = File.expand_path(xcframework_path)
57
+ Actions.lane_context[SharedValues::XCFRAMEWORK_DSYM_OUTPUT_PATH] = File.expand_path(dsyms_path)
58
+ ENV[SharedValues::XCFRAMEWORK_DSYM_OUTPUT_PATH.to_s] = File.expand_path(dsyms_path)
59
+ Actions.lane_context[SharedValues::XCFRAMEWORK_BCSYMBOLMAPS_OUTPUT_PATH] = File.expand_path(bcsymbolmaps_path)
60
+ ENV[SharedValues::XCFRAMEWORK_BCSYMBOLMAPS_OUTPUT_PATH.to_s] = File.expand_path(bcsymbolmaps_path)
61
+ end
49
62
  end
50
63
 
51
64
  def self.clean(params)
@@ -53,73 +66,202 @@ module Fastlane
53
66
  end
54
67
 
55
68
  def self.create_xcframework(params)
56
- xcframework = @xchelper.xcframework_path
57
- begin
58
- FileUtils.rm_rf(xcframework) if File.exist?(xcframework)
59
-
60
- arguments = ['-create-xcframework']
61
- arguments << '-allow-internal-distribution' if params[:allow_internal_distribution]
62
- params[:destinations].each_with_index do |_, index|
63
- arguments << "-framework #{@xchelper.xcarchive_framework_path(index)}"
64
- arguments << debug_symbols(index: index, params: params)
69
+ UI.message("params: #{params}")
70
+
71
+ if params[:frameworks]
72
+ params[:frameworks].each do |framework|
73
+ UI.message("▸ Creating xcframework for #{framework}")
74
+ xcframework = @xchelper.get_xcframework_path(framework)
75
+ UI.message("▸ Creating xcframework for #{framework} at path: #{xcframework}")
76
+ begin
77
+ FileUtils.rm_rf(xcframework) if File.exist?(xcframework)
78
+
79
+ arguments = ['-create-xcframework']
80
+ arguments << '-allow-internal-distribution' if params[:allow_internal_distribution]
81
+
82
+ params[:destinations].each_with_index do |_, index|
83
+ arguments << "-framework #{@xchelper.get_xcarchive_framework_path(index, framework)}"
84
+ arguments << debug_symbols(index: index, params: params, framework: framework)
85
+ end
86
+ arguments << "-output #{xcframework}"
87
+ UI.message("set -o pipefail && xcodebuild #{arguments.reject(&:empty?).join(' ')}")
88
+
89
+ Actions.sh("set -o pipefail && xcodebuild #{arguments.reject(&:empty?).join(' ')}")
90
+ rescue StandardError => e
91
+ UI.user_error!(e)
92
+ end
93
+ end
94
+ else
95
+ xcframework = @xchelper.xcframework_path
96
+ UI.message("▸ Creating xcframework at path: #{xcframework}")
97
+ begin
98
+ FileUtils.rm_rf(xcframework) if File.exist?(xcframework)
99
+
100
+ arguments = ['-create-xcframework']
101
+ arguments << '-allow-internal-distribution' if params[:allow_internal_distribution]
102
+
103
+ params[:destinations].each_with_index do |_, index|
104
+ arguments << "-framework #{@xchelper.xcarchive_framework_path(index)}"
105
+ arguments << debug_symbols(index: index, params: params, framework: @xchelper.framework)
106
+ end
107
+ arguments << "-output #{xcframework}"
108
+
109
+ Actions.sh("set -o pipefail && xcodebuild #{arguments.reject(&:empty?).join(' ')}")
110
+ rescue StandardError => e
111
+ UI.user_error!(e)
65
112
  end
66
- arguments << "-output #{xcframework}"
113
+ end
114
+ end
67
115
 
68
- Actions.sh("set -o pipefail && xcodebuild #{arguments.reject(&:empty?).join(' ')}")
69
- rescue StandardError => e
70
- UI.user_error!(e)
116
+ def self.sign_xcframework(params)
117
+ return if params[:code_sign_identity].nil?
118
+
119
+ frameworks = params[:frameworks] || [nil]
120
+
121
+ frameworks.each do |framework|
122
+ xcframework = framework ? @xchelper.get_xcframework_path(framework) : @xchelper.xcframework_path
123
+ UI.message("▸ Signing xcframework with '#{params[:code_sign_identity]}' at path: #{xcframework}")
124
+
125
+ begin
126
+ command = "codesign --force --sign '#{params[:code_sign_identity]}' --timestamp=none #{xcframework}"
127
+ UI.message(command)
128
+ Actions.sh(command)
129
+ rescue StandardError => e
130
+ UI.user_error!(e)
131
+ end
71
132
  end
72
133
  end
73
134
 
74
- def self.debug_symbols(index:, params:)
75
- return '' if !Helper.xcode_at_least?('12.0.0') || params[:include_debug_symbols] == false
135
+ def self.zip_xcframework(params)
136
+ return if params[:zip_xcframework].nil?
76
137
 
77
- debug_symbols = []
138
+ # Check if the zip utility is installed
139
+ unless system("which zip > /dev/null 2>&1")
140
+ UI.important("zip utility is not installed. Installing...")
141
+ system("brew install zip") || UI.crash!("Error: Failed to install zip utility")
142
+ end
143
+
144
+ frameworks = params[:frameworks] || [nil]
145
+
146
+ frameworks.each do |framework|
147
+ xcframework = framework ? @xchelper.get_xcframework_path(framework) : @xchelper.xcframework_path
148
+ UI.message("▸ Zipping xcframework at path: #{xcframework}")
149
+
150
+ begin
151
+ zip_path = "#{xcframework}.zip"
152
+ FileUtils.rm_f(zip_path) if File.exist?(zip_path)
153
+
154
+ command = "zip -r -X #{zip_path} #{xcframework}"
155
+ UI.message(command)
156
+
157
+ Actions.sh(command)
158
+ rescue StandardError => e
159
+ UI.user_error!(e)
160
+ end
161
+ end
162
+ end
163
+
164
+ def self.delete_xcframework(params)
165
+ return if params[:delete_xcframework].nil?
166
+
167
+ frameworks = params[:frameworks] || [nil]
78
168
 
79
- # Include dSYMs in xcframework
80
- if params[:include_dSYMs] != false
81
- debug_symbols << "-debug-symbols #{@xchelper.xcarchive_dSYMs_path(index)}/#{@xchelper.framework}.dSYM"
169
+ frameworks.each do |framework|
170
+ xcframework = framework ? @xchelper.get_xcframework_path(framework) : @xchelper.xcframework_path
171
+ UI.message("▸ Deleting xcframework at path: #{xcframework}")
172
+
173
+ begin
174
+ FileUtils.rm_rf(xcframework)
175
+ rescue StandardError => e
176
+ UI.user_error!(e)
177
+ end
82
178
  end
179
+ end
180
+
83
181
 
84
- # Include BCSymbols in xcframework
85
- if params[:include_BCSymbolMaps] != false && params[:enable_bitcode] != false
86
- bc_symbols_dir = @xchelper.xcarchive_BCSymbolMaps_path(index)
87
- if Dir.exist?(bc_symbols_dir)
88
- arguments = Dir.children(bc_symbols_dir).map { |path| "-debug-symbols #{File.expand_path("#{bc_symbols_dir}/#{path}")}" }
89
- debug_symbols << arguments.join(' ')
182
+
183
+ # #Fix compile problem go to xcframework and run this command (https://developer.apple.com/forums/thread/123253):
184
+ # #The generated file includes many module references that Swift thinks are class references because it uses the class ahead of the module
185
+ # #The problem is that in the Swiftinterface file, we have a class named ABCConnections, but the module is also called ABCConnections.
186
+ def self.remove_module_reference(params)
187
+ return if params[:ignore_module_reference].nil?
188
+
189
+ frameworks = params[:frameworks] || [nil]
190
+
191
+ frameworks.each do |framework|
192
+ output_path = framework ? @xchelper.get_xcframework_path(framework) : @xchelper.xcframework_path
193
+ params[:ignore_module_reference].each do |module_reference|
194
+ begin
195
+ command = "find #{output_path} -name '*.swiftinterface' -exec sed -i -e 's/#{module_reference}\\.//g' {} \\;"
196
+ success = system(command)
197
+ unless success
198
+ UI.error("Failed to execute command: #{command}")
199
+ else
200
+ UI.success("▸ Removed module reference for #{module_reference} in all matching files")
201
+ end
202
+ rescue => e
203
+ UI.error("Error: #{e.message}")
204
+ end
90
205
  end
91
206
  end
207
+ end
92
208
 
209
+ def self.debug_symbols(index:, params:, framework: nil)
210
+ return '' if !Helper.xcode_at_least?('12.0.0') || params[:include_debug_symbols] == false
211
+
212
+ frameworks = params[:frameworks] || [framework]
213
+ debug_symbols = []
214
+
215
+ frameworks.each do |fw|
216
+ # Include dSYMs in xcframework
217
+ if params[:include_dSYMs] != false
218
+ debug_symbols << "-debug-symbols #{@xchelper.xcarchive_dSYMs_path(index)}/#{fw}.dSYM"
219
+ end
220
+
221
+ # Include BCSymbols in xcframework
222
+ if params[:include_BCSymbolMaps] != false
223
+ bc_symbols_dir = @xchelper.xcarchive_BCSymbolMaps_path(index)
224
+ if Dir.exist?(bc_symbols_dir)
225
+ arguments = Dir.children(bc_symbols_dir).map { |path| "-debug-symbols #{File.expand_path("#{bc_symbols_dir}/#{path}")}" }
226
+ debug_symbols << arguments.join(' ')
227
+ end
228
+ end
229
+ end
230
+
93
231
  debug_symbols.join(' ')
94
232
  end
95
233
 
96
234
  def self.copy_dSYMs(params)
97
235
  return if params[:include_dSYMs] == false
98
-
99
- dSYMs_output_dir = @xchelper.xcframework_dSYMs_path
100
- FileUtils.mkdir_p(dSYMs_output_dir)
101
-
102
- params[:destinations].each_with_index do |_, framework_index|
103
- dSYM_source = "#{@xchelper.xcarchive_dSYMs_path(framework_index)}/#{@xchelper.framework}.dSYM"
236
+
237
+ frameworks = params[:frameworks] || [nil]
238
+
239
+ frameworks.each_with_index do |framework, framework_index|
240
+ dSYMs_output_dir = framework ? @xchelper.framework_dSYMs_path(framework) : @xchelper.xcframework_dSYMs_path
241
+ FileUtils.mkdir_p(dSYMs_output_dir)
242
+
243
+ dSYM_source = "#{@xchelper.xcarchive_dSYMs_path(framework_index)}/#{framework}.dSYM"
104
244
  identifier = @xchelper.library_identifier(framework_index)
105
- dSYM = "#{@xchelper.framework}.#{identifier}.dSYM"
245
+ dSYM = "#{framework}.#{identifier}.dSYM"
106
246
  dSYM_destination = "#{dSYMs_output_dir}/#{dSYM}"
107
-
247
+
108
248
  UI.important("▸ Copying #{dSYM} to #{dSYMs_output_dir}")
109
249
  FileUtils.cp_r(dSYM_source, dSYM_destination)
110
250
  end
111
251
  end
112
252
 
113
253
  def self.copy_BCSymbolMaps(params)
114
- return if params[:enable_bitcode] == false || params[:include_BCSymbolMaps] == false
115
-
116
- symbols_output_dir = @xchelper.xcframework_BCSymbolMaps_path
117
- FileUtils.mkdir_p(symbols_output_dir)
118
-
119
- params[:destinations].each_with_index do |_, framework_index|
254
+ return if params[:include_BCSymbolMaps] == false
255
+
256
+ frameworks = params[:frameworks] || [nil]
257
+
258
+ frameworks.each_with_index do |framework, framework_index|
259
+ symbols_output_dir = framework ? @xchelper.framework_BCSymbolMaps_path(framework) : @xchelper.xcframework_BCSymbolMaps_path
260
+ FileUtils.mkdir_p(symbols_output_dir)
261
+
120
262
  symbols_xcarchive_dir = @xchelper.xcarchive_BCSymbolMaps_path(framework_index)
121
263
  next unless Dir.exist?(symbols_xcarchive_dir)
122
-
264
+
123
265
  FileUtils.cp_r("#{symbols_xcarchive_dir}/.", symbols_output_dir)
124
266
  UI.important("▸ Copying #{Dir.children(symbols_xcarchive_dir)} to #{symbols_output_dir}")
125
267
  end
@@ -133,22 +275,32 @@ module Fastlane
133
275
  end
134
276
 
135
277
  def self.update_xcargs(params)
136
- xcargs = []
137
- if params[:override_xcargs]
138
- UI.important('Overwriting SKIP_INSTALL and BUILD_LIBRARY_FOR_DISTRIBUTION options')
139
- if params[:xcargs]
140
- params[:xcargs].gsub!(/SKIP_INSTALL(=|\s+)(YES|NO)/, '')
141
- params[:xcargs].gsub!(/BUILD_LIBRARY_FOR_DISTRIBUTION(=|\s+)(YES|NO)/, '')
278
+ xcargs = params[:override_xcargs].to_s.strip.split(' ')
279
+ skip_install_set = false
280
+ build_library_for_distribution_set = false
281
+
282
+ xcargs.each do |arg|
283
+ if arg.match?(/SKIP_INSTALL(=|\s+)/)
284
+ skip_install_set = true
285
+ unless arg.match?(/SKIP_INSTALL=NO/)
286
+ xcargs.delete(arg)
287
+ xcargs << 'SKIP_INSTALL=NO'
288
+ end
289
+ end
290
+
291
+ if arg.match?(/BUILD_LIBRARY_FOR_DISTRIBUTION(=|\s+)/)
292
+ build_library_for_distribution_set = true
293
+ unless arg.match?(/BUILD_LIBRARY_FOR_DISTRIBUTION=YES/)
294
+ xcargs.delete(arg)
295
+ xcargs << 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'
296
+ end
142
297
  end
143
- xcargs.concat(['SKIP_INSTALL=NO', 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'])
144
- end
145
-
146
- if params[:enable_bitcode] != false
147
- params[:xcargs].gsub!(/ENABLE_BITCODE(=|\s+)(YES|NO)/, '') if params[:xcargs]
148
- xcargs << ['OTHER_CFLAGS="-fembed-bitcode"', 'BITCODE_GENERATION_MODE="bitcode"', 'ENABLE_BITCODE=YES']
149
298
  end
150
-
151
- "#{params[:xcargs].to_s.strip} #{xcargs.join(' ')}"
299
+
300
+ xcargs << 'SKIP_INSTALL=NO' unless skip_install_set
301
+ xcargs << 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES' unless build_library_for_distribution_set
302
+
303
+ xcargs.join(' ')
152
304
  end
153
305
 
154
306
  def self.update_destinations(params)
@@ -218,13 +370,6 @@ module Fastlane
218
370
  description: "The project's scheme. Make sure it's marked as Shared",
219
371
  optional: false
220
372
  ),
221
- FastlaneCore::ConfigItem.new(
222
- key: :enable_bitcode,
223
- description: 'Should the project be built with bitcode enabled?',
224
- optional: true,
225
- is_string: false,
226
- default_value: true
227
- ),
228
373
  FastlaneCore::ConfigItem.new(
229
374
  key: :destinations,
230
375
  description: 'Use custom destinations for building the xcframework',
@@ -282,6 +427,37 @@ module Fastlane
282
427
  'Set this to false to preserve the passed xcargs',
283
428
  optional: true,
284
429
  default_value: true
430
+ ),
431
+ FastlaneCore::ConfigItem.new(
432
+ key: :frameworks,
433
+ description: 'List of frameworks to create xcframework for',
434
+ optional: true,
435
+ is_string: false,
436
+ type: Array,
437
+ default_value: []),
438
+ FastlaneCore::ConfigItem.new(
439
+ key: :code_sign_identity,
440
+ description: 'Code sign identity to use for building the xcframework',
441
+ optional: true
442
+ ),
443
+ FastlaneCore::ConfigItem.new(
444
+ key: :zip_xcframework,
445
+ description: 'Zip the xcframework after creation',
446
+ optional: true,
447
+ default_value: false
448
+ ),
449
+ FastlaneCore::ConfigItem.new(
450
+ key: :ignore_module_reference,
451
+ description: 'List of module references to remove from the xcframework',
452
+ optional: true,
453
+ is_string: false,
454
+ type: Array,
455
+ default_value: []),
456
+ FastlaneCore::ConfigItem.new(
457
+ key: :delete_xcframework,
458
+ description: 'Delete the xcframework after creation',
459
+ optional: true,
460
+ default_value: false
285
461
  )
286
462
  ]
287
463
  end
@@ -32,6 +32,22 @@ module Fastlane
32
32
  UI.user_error!("▸ PRODUCT_NAME was misdefined: `#{product_name}`. Please, provide :product_name option")
33
33
  end
34
34
 
35
+ def get_xcarchive_framework_path(framework_index, framework_name)
36
+ UI.message("▸ get_xcarchive_framework_path: framework_name: `#{framework_name}`")
37
+ framework_path = "#{xcarchive_path_for_destination(framework_index)}/Products/Library/Frameworks/#{framework_name}.framework"
38
+ UI.message("▸ get_xcarchive_framework_path: framework_path: `#{framework_path}`")
39
+ return framework_path if File.exist?(framework_path)
40
+
41
+ UI.user_error!("▸ get_xcarchive_framework_path: framework_name was misdefined: `#{framework_name}`. Please, provide :framework_name option")
42
+ end
43
+
44
+ def xcarchive_frameworks_dir(framework_index)
45
+ frameworks_dir = "#{xcarchive_path_for_destination(framework_index)}/Products/Library/Frameworks"
46
+ return frameworks_dir if File.exist?(frameworks_dir)
47
+
48
+ UI.user_error!("▸ Frameworks directory does not exist for the given index: `#{framework_index}`.")
49
+ end
50
+
35
51
  def xcarchive_frameworks_path
36
52
  @params[:destinations].each_with_index.map { |_, i| xcarchive_framework_path(i) }
37
53
  end
@@ -44,6 +60,10 @@ module Fastlane
44
60
  File.expand_path("#{output_directory}/#{product_name}.dSYMs")
45
61
  end
46
62
 
63
+ def framework_dSYMs_path(framework_name)
64
+ File.expand_path("#{output_directory}/#{framework_name}.dSYMs")
65
+ end
66
+
47
67
  def xcarchive_BCSymbolMaps_path(framework_index)
48
68
  File.expand_path("#{xcarchive_path_for_destination(framework_index)}/BCSymbolMaps")
49
69
  end
@@ -52,10 +72,18 @@ module Fastlane
52
72
  File.expand_path("#{output_directory}/#{product_name}.BCSymbolMaps")
53
73
  end
54
74
 
75
+ def framework_BCSymbolMaps_path(framework_name)
76
+ File.expand_path("#{output_directory}/#{framework_name}.BCSymbolMaps")
77
+ end
78
+
55
79
  def xcframework_path
56
80
  File.expand_path("#{output_directory}/#{xcframework}")
57
81
  end
58
82
 
83
+ def get_xcframework_path(framework_name)
84
+ File.expand_path("#{output_directory}/#{framework_name}.xcframework")
85
+ end
86
+
59
87
  def output_directory
60
88
  @params[:xcframework_output_directory] || ''
61
89
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module MobileTools
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-mobile_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yogesh Khandelwal