@@ -120,14 +120,161 @@ def self.podspec_source_download_prebuild_stable_tarball()
120
120
if @@build_from_source
121
121
return
122
122
end
123
-
124
123
url = stable_tarball_url ( @@react_native_version , :debug )
125
124
rncore_log ( "Using tarball from URL: #{ url } " )
126
125
download_stable_rncore ( @@react_native_path , @@react_native_version , :debug )
127
126
download_stable_rncore ( @@react_native_path , @@react_native_version , :release )
128
127
return { :http => url }
129
128
end
130
129
130
+ def self . process_dsyms ( frameworkTarball , dSymsTarball )
131
+ if !@@download_dsyms
132
+ return
133
+ end
134
+
135
+ if @@react_native_path == ""
136
+ rncore_log ( "react_native_path is not set" , :error )
137
+ return
138
+ end
139
+
140
+ if @@react_native_version == ""
141
+ rncore_log ( "react_native_version is not set" , :error )
142
+ return
143
+ end
144
+
145
+ if @@build_from_source
146
+ return
147
+ end
148
+
149
+ # gunzip the dSymsTarball and the frameworkTarball into a temporary folder
150
+ # and then copy the dSYMs into the framework folder and then tar/gz the framework folder again
151
+ # into the same location as the original frameworkTarball
152
+
153
+ rncore_log ( "Adding symbols #{ Pathname . new ( dSymsTarball ) . relative_path_from ( Pathname . pwd ) . to_s } to framework tarball #{ Pathname . new ( frameworkTarball ) . relative_path_from ( Pathname . pwd ) . to_s } " )
154
+
155
+ FileUtils . mkdir_p ( File . dirname ( frameworkTarball ) )
156
+ FileUtils . cp ( frameworkTarball , "#{ frameworkTarball } .orig" )
157
+
158
+ rncore_log ( " Backed up original tarballs" )
159
+
160
+ begin
161
+ # Now let's gunzip the framework tarball into a .tar file
162
+ # Get filename and foldername from the tarball path
163
+ frameworkFolder = File . dirname ( frameworkTarball )
164
+ frameworkFilename = File . basename ( frameworkTarball , ".tar.gz" )
165
+ frameworkTarPath = File . join ( frameworkFolder , frameworkFilename + ".tar" )
166
+
167
+ # Now gunzip the tarball into the frameworkFolder - this will remove the .gz file and leave us with a .tar file
168
+ rncore_log ( " Unpacking framework tarball" )
169
+ `gunzip "#{ frameworkTarball } "`
170
+
171
+ # Now let's untar the dSyms tarball into a temporary folder / dSYMs subfolder
172
+ dsyms_tmp_dir = "#{ artifacts_dir } /dSYMs"
173
+ rncore_log ( " Unpacking dSYMs to temporary folder" )
174
+ `mkdir -p "#{ dsyms_tmp_dir } " && tar -xzf "#{ dSymsTarball } " -C "#{ dsyms_tmp_dir } "`
175
+
176
+ # Now we need to remap the symbol files to be relative to the framework folder
177
+ remap_sourcemaps_for_symbols ( dsyms_tmp_dir )
178
+
179
+ # Add the dSYMs folder to the framework folder
180
+ rncore_log ( " Adding dSYMs to framework tarball" )
181
+ `(cd "$(dirname "#{ dsyms_tmp_dir } ")" && mkdir -p React.xcframework && cp -r "$(basename "#{ dsyms_tmp_dir } ")" React.xcframework/dSYMs && tar -rf "#{ frameworkTarPath } " React.xcframework/dSYMs && rm -rf React.xcframework)`
182
+
183
+ # Now gzip the framework tarball again - remember to use the .tar file and not the .gz file
184
+ rncore_log ( " Packing #{ Pathname . new ( frameworkTarPath ) . relative_path_from ( Pathname . pwd ) . to_s } " )
185
+ `gzip -1 "#{ frameworkTarPath } "`
186
+
187
+ # Clean up the temporary folder
188
+ FileUtils . remove_entry ( dsyms_tmp_dir )
189
+ rncore_log ( " Processed dSYMs into framework tarball #{ Pathname . new ( frameworkTarball ) . relative_path_from ( Pathname . pwd ) . to_s } " )
190
+
191
+ # Remove backup of original tarballs
192
+ FileUtils . rm_f ( "#{ frameworkTarball } .orig" )
193
+
194
+ rescue => e
195
+ rncore_log ( "Failed to process dSYMs: #{ e . message } " , :error )
196
+ # Restore the original tarballs
197
+ FileUtils . mv ( "#{ frameworkTarball } .orig" , frameworkTarball ) if File . exist? ( "#{ frameworkTarball } .orig" )
198
+ rncore_log ( "Restored original tarballs" , :error )
199
+ abort "Couldn't process dSYMs: #{ e . message } "
200
+ end
201
+ end
202
+
203
+ def self . remap_sourcemaps_for_symbols ( symbolsPath )
204
+ rncore_log ( " Remapping dSYMs to be relative to framework folder" )
205
+
206
+ # Find all .dSYM bundles in the symbols path
207
+ dsym_bundles = [ ]
208
+ Dir . glob ( File . join ( symbolsPath , "**" , "*.dSYM" ) ) . each do |path |
209
+ if File . directory? ( path )
210
+ # Check if it's a valid dSYM bundle with Info.plist
211
+ info_plist = File . join ( path , 'Contents' , 'Info.plist' )
212
+ dsym_bundles << path if File . exist? ( info_plist )
213
+ end
214
+ end
215
+
216
+ return if dsym_bundles . empty?
217
+
218
+ # Define source path mappings - from absolute build paths to relative framework paths
219
+ mappings = [
220
+ # Make sure to make react_native_path absolute
221
+ [ "/Users/runner/work/react-native/react-native/packages/react-native" , "#{ File . expand_path ( @@react_native_path ) } " ] ,
222
+ ]
223
+
224
+ dsym_bundles . each do |dsym_path | begin
225
+ # Get UUIDs for this dSYM bundle
226
+ uuid_output = `dwarfdump --uuid "#{ dsym_path } " 2>/dev/null`
227
+ uuids = uuid_output . scan ( /UUID:\s +([0-9A-F-]{36})/i ) . flatten
228
+
229
+ next if uuids . empty?
230
+
231
+ # Create Resources directory if it doesn't exist
232
+ resources_dir = File . join ( dsym_path , 'Contents' , 'Resources' )
233
+ FileUtils . mkdir_p ( resources_dir )
234
+
235
+ # Generate plist content with path mappings
236
+ plist_content = generate_plist_content ( mappings )
237
+
238
+ # Write plist for each UUID
239
+ uuids . each do |uuid |
240
+ plist_path = File . join ( resources_dir , "#{ uuid } .plist" )
241
+ File . write ( plist_path , plist_content )
242
+ end
243
+
244
+ rescue => e
245
+ rncore_log ( " Failed to process dSYM #{ dsym_path } : #{ e . message } " , :error )
246
+ end
247
+ end
248
+
249
+ rncore_log ( " Completed dSYM remapping for #{ dsym_bundles . length } bundles" )
250
+ end
251
+
252
+ def self . generate_plist_content ( mappings )
253
+ # Generate the source path remapping entries
254
+ remapping_entries = mappings . map do |from , to |
255
+ " <key>#{ from } </key><string>#{ to } </string>"
256
+ end . join ( "\n " )
257
+
258
+ # Use the first mapping for legacy keys
259
+ first_from , first_to = mappings . first
260
+
261
+ return <<~PLIST
262
+ <?xml version="1.0" encoding="UTF-8"?>
263
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
264
+ <plist version="1.0">
265
+ <dict>
266
+ <key>DBGVersion</key><string>3</string>
267
+ <key>DBGBuildSourcePath</key><string>#{ first_from } </string>
268
+ <key>DBGSourcePath</key><string>#{ first_to } </string>
269
+ <key>DBGSourcePathRemapping</key>
270
+ <dict>
271
+ #{ remapping_entries }
272
+ </dict>
273
+ </dict>
274
+ </plist>
275
+ PLIST
276
+ end
277
+
131
278
def self . stable_tarball_url ( version , build_type )
132
279
## You can use the `ENTERPRISE_REPOSITORY` ariable to customise the base url from which artifacts will be downloaded.
133
280
## The mirror's structure must be the same of the Maven repo the react-native core team publishes on Maven Central.
0 commit comments