From 1546666a6d713ef756b2f11de9581e3b2bbe08dc Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 20 Oct 2022 10:43:31 -0700 Subject: [PATCH] Consume Tarball from Maven (#35034) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35034 Currently, when creating an app using the command: `npx react-native init MyApp --version nightly` iOS fails to install the dependencies because it does not find a proper tarball to run Hermes. This diff solve the problem by fetching the Hermes tarball that is created by the CI while building the nightly. ## Changelog: [iOS][Fixed] - Make the nightly work with the proper Hermes tarball Reviewed By: cortinico Differential Revision: D40512418 fbshipit-source-id: f510f84be9f19807236091687df5e13961103318 --- scripts/__tests__/hermes-utils-test.js | 21 ++++++++++++++++++ scripts/hermes/hermes-utils.js | 10 +++++++-- sdks/hermes-engine/hermes-engine.podspec | 11 +++++++++- sdks/hermes-engine/hermes-utils.rb | 27 ++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 sdks/hermes-engine/hermes-utils.rb diff --git a/scripts/__tests__/hermes-utils-test.js b/scripts/__tests__/hermes-utils-test.js index 22e255c37e29c6..16d694399998c0 100644 --- a/scripts/__tests__/hermes-utils-test.js +++ b/scripts/__tests__/hermes-utils-test.js @@ -101,6 +101,10 @@ function populateMockFilesystem() { path.join(SDKS_DIR, 'hermes-engine', 'hermes-engine.podspec'), 'Dummy file', ); + fs.writeFileSync( + path.join(SDKS_DIR, 'hermes-engine', 'hermes-utils.rb'), + 'Dummy file', + ); } describe('hermes-utils', () => { @@ -279,6 +283,23 @@ describe('hermes-utils', () => { ), ); }); + it('should copy hermes-utils.rb to Hermes source directory', () => { + copyPodSpec(); + expect( + fs.readFileSync(path.join(SDKS_DIR, 'hermes', 'hermes-utils.rb'), { + encoding: 'utf8', + flag: 'r', + }), + ).toEqual( + fs.readFileSync( + path.join(SDKS_DIR, 'hermes-engine', 'hermes-utils.rb'), + { + encoding: 'utf8', + flag: 'r', + }, + ), + ); + }); }); describe('shouldUsePrebuiltHermesC', () => { it('returns false if path to osx hermesc does not exist', () => { diff --git a/scripts/hermes/hermes-utils.js b/scripts/hermes/hermes-utils.js index 7f702e73032504..79caaffff49103 100644 --- a/scripts/hermes/hermes-utils.js +++ b/scripts/hermes/hermes-utils.js @@ -152,9 +152,15 @@ function copyPodSpec() { if (!fs.existsSync(HERMES_DIR)) { fs.mkdirSync(HERMES_DIR, {recursive: true}); } + const podspec = 'hermes-engine.podspec'; fs.copyFileSync( - path.join(SDKS_DIR, 'hermes-engine', 'hermes-engine.podspec'), - path.join(HERMES_DIR, 'hermes-engine.podspec'), + path.join(SDKS_DIR, 'hermes-engine', podspec), + path.join(HERMES_DIR, podspec), + ); + const utils = 'hermes-utils.rb'; + fs.copyFileSync( + path.join(SDKS_DIR, 'hermes-engine', utils), + path.join(HERMES_DIR, utils), ); } diff --git a/sdks/hermes-engine/hermes-engine.podspec b/sdks/hermes-engine/hermes-engine.podspec index fd108231491024..b2e7b238667585 100644 --- a/sdks/hermes-engine/hermes-engine.podspec +++ b/sdks/hermes-engine/hermes-engine.podspec @@ -4,6 +4,7 @@ # LICENSE file in the root directory of this source tree. require "json" +require_relative "./hermes-utils.rb" react_native_path = File.join(__dir__, "..", "..") @@ -24,13 +25,21 @@ import_hermesc_file=File.join(react_native_path, "sdks", "hermesc", "osx-bin", " source = {} git = "https://github.com/facebook/hermes.git" +isInMain = version.include?('1000.0.0') +isNightly = version.start_with?('0.0.0-') + if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH') Pod::UI.puts '[Hermes] Using pre-built Hermes binaries from local path.' if Object.const_defined?("Pod::UI") source[:http] = "file://#{ENV['HERMES_ENGINE_TARBALL_PATH']}" -elsif version.include? '1000.0.0' || version.start_with?('0.0.0-') +elsif isInMain Pod::UI.puts '[Hermes] Installing hermes-engine may take a while, building Hermes from source...'.yellow if Object.const_defined?("Pod::UI") source[:git] = git source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip +elsif isNightly + Pod::UI.puts '[Hermes] Nightly version, download pre-built for Hermes'.yellow if Object.const_defined?("Pod::UI") + destination_path = download_nightly_hermes(react_native_path, version) + # set tarball as hermes engine + source[:http] = "file://#{destination_path}" elsif File.exists?(hermestag_file) && isInCI Pod::UI.puts '[Hermes] Detected that you are on a React Native release branch, building Hermes from source...'.yellow if Object.const_defined?("Pod::UI") hermestag = File.read(hermestag_file).strip diff --git a/sdks/hermes-engine/hermes-utils.rb b/sdks/hermes-engine/hermes-utils.rb new file mode 100644 index 00000000000000..f16c06231c42fb --- /dev/null +++ b/sdks/hermes-engine/hermes-utils.rb @@ -0,0 +1,27 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +require 'net/http' +require 'rexml/document' + +# This function downloads the nightly prebuilt version of Hermes based on the passed version +# and save it in the node_module/react_native/sdks/downloads folder +# It then returns the path to the hermes tarball +# +# Parameters +# - react_native_path: the path to the React Native folder in node modules. It is used as root path to store the Hermes tarball +# - version: the version of React Native that requires the Hermes tarball +# Returns: the path to the downloaded Hermes tarball +def download_nightly_hermes(react_native_path, version) + # TODO: convert hermes-ios to hermes-ios-debug + params = "r=snapshots\&g=com.facebook.react\&a=react-native-artifacts\&c=hermes-ios-debug\&e=tar.gz\&v=#{version}-SNAPSHOT" + tarball_url = "http://oss.sonatype.org/service/local/artifact/maven/redirect\?#{params}" + + destination_folder = "#{react_native_path}/sdks/downloads" + destination_path = "#{destination_folder}/hermes-ios.tar.gz" + + `mkdir -p "#{destination_folder}" && curl "#{tarball_url}" -Lo "#{destination_path}"` + return destination_path +end