7
7
require 'rexml/document'
8
8
require 'open3' # [macOS]
9
9
require 'json' # [macOS]
10
+ require 'tmpdir' # [macOS]
10
11
11
12
HERMES_GITHUB_URL = "https://github.com/facebook/hermes.git"
12
13
ENV_BUILD_FROM_SOURCE = "RCT_BUILD_HERMES_FROM_SOURCE"
@@ -175,8 +176,18 @@ def podspec_source_build_from_github_tag(react_native_path)
175
176
end
176
177
177
178
def podspec_source_build_from_github_main ( )
178
- hermes_log ( "Using the latest commit from main." )
179
- return { :git => HERMES_GITHUB_URL , :commit => `git ls-remote #{ HERMES_GITHUB_URL } main | cut -f 1` . strip }
179
+ # hermes_log("Using the latest commit from main.")
180
+ # return {:git => HERMES_GITHUB_URL, :commit => `git ls-remote #{HERMES_GITHUB_URL} main | cut -f 1`.strip}
181
+
182
+ # [macOS
183
+ # The logic for this is a bit different on macOS.
184
+ # Since react-native-macos lags slightly behind facebook/react-native, we can't always use
185
+ # the latest Hermes commit because Hermes and JSI don't always guarantee backwards compatibility.
186
+ # Instead, we take the commit hash of Hermes at the time of the merge base with facebook/react-native.
187
+ commit = hermes_commit_at_merge_base ( )
188
+ hermes_log ( "Using Hermes commit from the merge base with facebook/react-native: #{ commit } " )
189
+ return { :git => HERMES_GITHUB_URL , :commit => commit }
190
+ # macOS]
180
191
end
181
192
182
193
def podspec_source_download_prebuild_release_tarball ( react_native_path , version )
@@ -199,6 +210,51 @@ def artifacts_dir()
199
210
return File . join ( Pod ::Config . instance . project_pods_root , "hermes-engine-artifacts" )
200
211
end
201
212
213
+ # [macOS
214
+ def hermes_commit_at_merge_base ( )
215
+ # We don't need ls-remote because react-native-macos is a fork of facebook/react-native
216
+ fetch_result = `git fetch -q https://github.com/facebook/react-native.git`
217
+ if $?. exitstatus != 0
218
+ abort <<-EOS
219
+ [Hermes] Failed to fetch facebook/react-native into the local repository.
220
+ EOS
221
+ end
222
+
223
+ merge_base = `git merge-base FETCH_HEAD HEAD` . strip
224
+ if merge_base . empty?
225
+ abort <<-EOS
226
+ [Hermes] Unable to find the merge base between our HEAD and upstream's HEAD.
227
+ EOS
228
+ end
229
+
230
+ timestamp = `git show -s --format=%ci #{ merge_base } ` . strip
231
+ if timestamp . empty?
232
+ abort <<-EOS
233
+ [Hermes] Unable to extract the timestamp for the merge base (#{ merge_base } ).
234
+ EOS
235
+ end
236
+
237
+ commit = nil
238
+ Dir . mktmpdir do |tmpdir |
239
+ hermes_git_dir = File . join ( tmpdir , "hermes.git" )
240
+ # Unfortunately we can't use git rev-list on HERMES_GITHUB_URL directly since we're not in that repo.
241
+ # Instead, we create a shallow clone to avoid downloading the entire history.
242
+ `git clone -q --bare --shallow-since="#{ timestamp } " #{ HERMES_GITHUB_URL } "#{ hermes_git_dir } "`
243
+ `git --git-dir="#{ hermes_git_dir } " fetch -q --deepen=1`
244
+
245
+ # If all goes well, this will be the commit hash of Hermes at the time of the merge base
246
+ commit = `git --git-dir="#{ hermes_git_dir } " rev-list -1 --before="#{ timestamp } " HEAD` . strip
247
+ if commit . empty?
248
+ abort <<-EOS
249
+ [Hermes] Unable to find the Hermes commit hash at time #{ timestamp } .
250
+ EOS
251
+ end
252
+ end
253
+
254
+ return commit
255
+ end
256
+ # macOS]
257
+
202
258
def hermestag_file ( react_native_path )
203
259
return File . join ( react_native_path , "sdks" , ".hermesversion" )
204
260
end
@@ -236,15 +292,20 @@ def resolve_url_redirects(url)
236
292
return ( `curl -Ls -o /dev/null -w %{url_effective} \" #{ url } \" ` )
237
293
end
238
294
239
- # [macOS react-native-macos does not publish macos specific hermes artifacts
240
- # so we attempt to find the latest patch version of the iOS artifacts and use that
241
- def findLastestVersionWithArtifact ( version )
242
- # See https://central.sonatype.org/search/rest-api-guide/ for details on query params
243
- versionWithoutPatch = "#{ version . match ( /^(\d +\. \d +)/ ) } "
244
- res , = Open3 . capture3 ( "curl -s https://search.maven.org/solrsearch/select?q=g:com.facebook.react+AND+a:react-native-artifacts+AND+v:#{ versionWithoutPatch } .*&core=gav&rows=1&wt=json" )
245
- wt = JSON . parse ( res )
246
- response = wt [ 'response' ]
247
- return response [ 'docs' ] [ 0 ] [ 'v' ] unless response [ 'numFound' ] == 0
295
+ # [macOS
296
+ # Tries to find a suitable Hermes version for a given react-native-macos package.
297
+ # For stable branches, we prefer this to be specified as a peer dependency.
298
+ def findMatchingHermesVersion ( package )
299
+ if package [ 'version' ] == "1000.0.0"
300
+ # The main branch builds from source, so skip this check
301
+ return nil
302
+ end
303
+
304
+ if package [ 'peerDependencies' ]
305
+ return package [ 'peerDependencies' ] [ 'react-native' ]
306
+ end
307
+
308
+ hermes_log ( "No matching Hermes version found. Defaulting to main branch, which may be unreliable." )
248
309
end
249
310
# macOS]
250
311
0 commit comments