Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions packages/react-native/scripts/cocoapods/rncore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -406,17 +406,50 @@ def self.download_nightly_rncore(react_native_path, version, configuration, dsym
end

def self.download_rncore_tarball(react_native_path, tarball_url, version, configuration, dsyms = false)
destination_path = configuration == nil ?
"#{artifacts_dir()}/reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}.tar.gz" :
"#{artifacts_dir()}/reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}-#{configuration}.tar.gz"
filename = configuration == nil ?
"reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}.tar.gz" :
"reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}-#{configuration}.tar.gz"
destination_path = "#{artifacts_dir()}/#{filename}"

if File.exist?(destination_path)
rncore_log("Tarball #{filename} already exists in Pods. Skipping download.")
return destination_path
end

unless File.exist?(destination_path)
`mkdir -p "#{artifacts_dir()}"`

cached_path = File.join(ReactNativePodsUtils.shared_cache_dir(), filename)
if File.exist?(cached_path)
rncore_log("Verifying checksum for cached #{filename}...")
if ReactNativePodsUtils.validate_tarball(cached_path, tarball_url)
rncore_log("Cache hit: copying #{filename} from shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
FileUtils.cp(cached_path, destination_path)
else
rncore_log("Shared cache file #{filename} failed SHA verification. Re-downloading.")
tmp_file = "#{artifacts_dir()}/reactnative-core.download"
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
rncore_log("Verifying checksum for downloaded #{filename}...")
if ReactNativePodsUtils.validate_tarball(destination_path, tarball_url)
FileUtils.cp(destination_path, cached_path)
rncore_log("Saved #{filename} to shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
else
rncore_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end
else
rncore_log("Cache miss: downloading #{filename} from #{tarball_url}")
# Download to a temporary file first so we don't cache incomplete downloads.
rncore_log("Downloading ReactNativeCore-prebuilt #{dsyms ? "dSYMs " : ""}#{configuration ? configuration.to_s : ""} tarball from #{tarball_url} to #{Pathname.new(destination_path).relative_path_from(Pathname.pwd).to_s}")
tmp_file = "#{artifacts_dir()}/reactnative-core.download"
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
else
rncore_log("Using downloaded ReactNativeCore-prebuilt #{dsyms ? "dSYMs " : ""}#{configuration ? configuration.to_s : ""} tarball at #{Pathname.new(destination_path).relative_path_from(Pathname.pwd).to_s}")
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
rncore_log("Verifying checksum for downloaded #{filename}...")
if ReactNativePodsUtils.validate_tarball(destination_path, tarball_url)
# Save to shared cache for future use
`mkdir -p "#{ReactNativePodsUtils.shared_cache_dir()}"`
FileUtils.cp(destination_path, cached_path)
rncore_log("Saved #{filename} to shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
else
rncore_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end

return destination_path
Expand Down
46 changes: 41 additions & 5 deletions packages/react-native/scripts/cocoapods/rndependencies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,50 @@ def self.podspec_source_download_prebuilt_nightly_tarball(version)
end

def self.download_rndeps_tarball(react_native_path, tarball_url, version, configuration)
destination_path = configuration == nil ?
"#{artifacts_dir()}/reactnative-dependencies-#{version}.tar.gz" :
"#{artifacts_dir()}/reactnative-dependencies-#{version}-#{configuration}.tar.gz"
filename = configuration == nil ?
"reactnative-dependencies-#{version}.tar.gz" :
"reactnative-dependencies-#{version}-#{configuration}.tar.gz"
destination_path = "#{artifacts_dir()}/#{filename}"

if File.exist?(destination_path)
rndeps_log("Tarball #{filename} already exists in Pods. Skipping download.")
return destination_path
end

unless File.exist?(destination_path)
`mkdir -p "#{artifacts_dir()}"`

cached_path = File.join(ReactNativePodsUtils.shared_cache_dir(), filename)
if File.exist?(cached_path)
rndeps_log("Verifying checksum for cached #{filename}...")
if ReactNativePodsUtils.validate_tarball(cached_path, tarball_url)
rndeps_log("Cache hit: copying #{filename} from shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
FileUtils.cp(cached_path, destination_path)
else
rndeps_log("Shared cache file #{filename} failed SHA verification. Re-downloading.")
tmp_file = "#{artifacts_dir()}/reactnative-dependencies.download"
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
rndeps_log("Verifying checksum for downloaded #{filename}...")
if ReactNativePodsUtils.validate_tarball(destination_path, tarball_url)
FileUtils.cp(destination_path, cached_path)
rndeps_log("Saved #{filename} to shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
else
rndeps_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end
else
rndeps_log("Cache miss: downloading #{filename} from #{tarball_url}")
# Download to a temporary file first so we don't cache incomplete downloads.
tmp_file = "#{artifacts_dir()}/reactnative-dependencies.download"
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
rndeps_log("Verifying checksum for downloaded #{filename}...")
if ReactNativePodsUtils.validate_tarball(destination_path, tarball_url)
# Save to shared cache for future use
`mkdir -p "#{ReactNativePodsUtils.shared_cache_dir()}"`
FileUtils.cp(destination_path, cached_path)
rndeps_log("Saved #{filename} to shared cache (#{ReactNativePodsUtils.shared_cache_dir()})")
else
rndeps_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end

return destination_path
Expand Down
42 changes: 42 additions & 0 deletions packages/react-native/scripts/cocoapods/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# LICENSE file in the root directory of this source tree.

require 'shellwords'
require 'digest'

require_relative "./helpers.rb"
require_relative "./jsengine.rb"
Expand Down Expand Up @@ -724,4 +725,45 @@ def self.resolve_use_frameworks(spec, header_mappings_dir: nil, module_name: nil
spec.header_mappings_dir = header_mappings_dir
end
end

# ==================== #
# Shared download cache #
# ==================== #

def self.shared_cache_dir()
return File.join(Dir.home, "Library", "Caches", "ReactNative")
end

def self.fetch_maven_sha1(tarball_url)
sha1 = `curl -sL "#{tarball_url}.sha1"`.strip
return sha1.downcase if $?.success? && sha1.match?(/\A[a-fA-F0-9]{40}\z/)
nil
end

def self.validate_tarball(path, tarball_url)
expected_sha1 = fetch_maven_sha1(tarball_url)
basename = File.basename(path)
if expected_sha1.nil?
cache_log("SHA1 not available from Maven for #{basename}. Skipping validation.")
return true
end
actual_sha1 = Digest::SHA1.file(path).hexdigest
if actual_sha1 == expected_sha1
cache_log("SHA1 verified for #{basename}")
return true
end
cache_log("SHA1 mismatch for #{basename}: expected #{expected_sha1}, got #{actual_sha1}", :error)
return false
end

def self.cache_log(message, level = :info)
return unless Object.const_defined?("Pod::UI")
prefix = '[Cache] '
case level
when :error
Pod::UI.puts prefix.red + message
else
Pod::UI.puts prefix.green + message
end
end
end
75 changes: 70 additions & 5 deletions packages/react-native/sdks/hermes-engine/hermes-utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

require 'digest'

HERMES_GITHUB_URL = "https://github.com/facebook/hermes.git"
ENV_BUILD_FROM_SOURCE = "RCT_BUILD_HERMES_FROM_SOURCE"

Expand Down Expand Up @@ -206,16 +208,79 @@ def download_stable_hermes(react_native_path, version, configuration)
download_hermes_tarball(react_native_path, tarball_url, version, configuration)
end

def shared_cache_dir()
return File.join(Dir.home, "Library", "Caches", "ReactNative")
end

def fetch_maven_sha1(tarball_url)
sha1 = `curl -sL "#{tarball_url}.sha1"`.strip
return sha1.downcase if $?.success? && sha1.match?(/\A[a-fA-F0-9]{40}\z/)
nil
end

def validate_hermes_tarball(path, tarball_url)
expected_sha1 = fetch_maven_sha1(tarball_url)
basename = File.basename(path)
if expected_sha1.nil?
hermes_log("SHA1 not available from Maven for #{basename}. Skipping validation.", :info)
return true
end
actual_sha1 = Digest::SHA1.file(path).hexdigest
if actual_sha1 == expected_sha1
hermes_log("SHA1 verified for #{basename}", :info)
return true
end
hermes_log("SHA1 mismatch for #{basename}: expected #{expected_sha1}, got #{actual_sha1}", :error)
return false
end

def download_hermes_tarball(react_native_path, tarball_url, version, configuration)
destination_path = configuration == nil ?
"#{artifacts_dir()}/hermes-ios-#{version}.tar.gz" :
"#{artifacts_dir()}/hermes-ios-#{version}-#{configuration}.tar.gz"
filename = configuration == nil ?
"hermes-ios-#{version}.tar.gz" :
"hermes-ios-#{version}-#{configuration}.tar.gz"
destination_path = "#{artifacts_dir()}/#{filename}"

if File.exist?(destination_path)
hermes_log("Tarball #{filename} already exists in Pods. Skipping download.", :info)
return destination_path
end

unless File.exist?(destination_path)
`mkdir -p "#{artifacts_dir()}"`

cached_path = File.join(shared_cache_dir(), filename)
if File.exist?(cached_path)
hermes_log("Verifying checksum for cached #{filename}...", :info)
if validate_hermes_tarball(cached_path, tarball_url)
hermes_log("Cache hit: copying #{filename} from shared cache (#{shared_cache_dir()})", :info)
FileUtils.cp(cached_path, destination_path)
else
hermes_log("Shared cache file #{filename} failed SHA verification. Re-downloading.", :info)
tmp_file = "#{artifacts_dir()}/hermes-ios.download"
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
hermes_log("Verifying checksum for downloaded #{filename}...", :info)
if validate_hermes_tarball(destination_path, tarball_url)
FileUtils.cp(destination_path, cached_path)
hermes_log("Saved #{filename} to shared cache (#{shared_cache_dir()})", :info)
else
hermes_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end
else
hermes_log("Cache miss: downloading #{filename} from #{tarball_url}", :info)
# Download to a temporary file first so we don't cache incomplete downloads.
tmp_file = "#{artifacts_dir()}/hermes-ios.download"
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
hermes_log("Verifying checksum for downloaded #{filename}...", :info)
if validate_hermes_tarball(destination_path, tarball_url)
# Save to shared cache for future use
`mkdir -p "#{shared_cache_dir()}"`
FileUtils.cp(destination_path, cached_path)
hermes_log("Saved #{filename} to shared cache (#{shared_cache_dir()})", :info)
else
hermes_log("Downloaded file #{filename} failed SHA verification!", :error)
end
end

return destination_path
end

Expand Down
Loading