Skip to content

Commit f13b1a0

Browse files
committed
Cache prebuilt iOS binaries in ~/Library/Caches/ReactNative
Currently, Hermes, ReactNativeDependencies, and ReactNativeCore tarballs are cached only inside the Pods/ directory. This means every clean `pod install` (or deleting the Pods folder) triggers a full re-download from Maven, even if the same version was already downloaded before. This adds a shared cache layer at ~/Library/Caches/ReactNative/. On first download, tarballs are saved to the shared cache. On subsequent pod installs, if the local Pods cache is empty but the shared cache has the tarball, it is copied locally instead of re-downloaded. This benefits: - Clean installs after deleting Pods/ - Multiple projects using the same React Native version - CI environments with a persistent home directory Added descriptive log messages for each scenario (local hit, shared cache hit, cache miss + download) to aid debugging.
1 parent 1e01e8d commit f13b1a0

3 files changed

Lines changed: 79 additions & 18 deletions

File tree

packages/react-native/scripts/cocoapods/rncore.rb

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,18 +403,36 @@ def self.download_nightly_rncore(react_native_path, version, configuration, dsym
403403
download_rncore_tarball(react_native_path, tarball_url, version, configuration, dsyms)
404404
end
405405

406+
def self.shared_cache_dir()
407+
return File.join(Dir.home, "Library", "Caches", "ReactNative")
408+
end
409+
406410
def self.download_rncore_tarball(react_native_path, tarball_url, version, configuration, dsyms = false)
407-
destination_path = configuration == nil ?
408-
"#{artifacts_dir()}/reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}.tar.gz" :
409-
"#{artifacts_dir()}/reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}-#{configuration}.tar.gz"
411+
filename = configuration == nil ?
412+
"reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}.tar.gz" :
413+
"reactnative-core-#{version}#{dsyms ? "-dSYM" : ""}-#{configuration}.tar.gz"
414+
destination_path = "#{artifacts_dir()}/#{filename}"
415+
416+
if File.exist?(destination_path)
417+
rncore_log("Tarball #{filename} already exists in Pods. Skipping download.")
418+
return destination_path
419+
end
410420

411-
unless File.exist?(destination_path)
421+
`mkdir -p "#{artifacts_dir()}"`
422+
423+
cached_path = File.join(shared_cache_dir(), filename)
424+
if File.exist?(cached_path)
425+
rncore_log("Cache hit: copying #{filename} from shared cache (#{shared_cache_dir()})")
426+
FileUtils.cp(cached_path, destination_path)
427+
else
428+
rncore_log("Cache miss: downloading #{filename} from #{tarball_url}")
412429
# Download to a temporary file first so we don't cache incomplete downloads.
413-
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}")
414430
tmp_file = "#{artifacts_dir()}/reactnative-core.download"
415-
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
416-
else
417-
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}")
431+
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
432+
# Save to shared cache for future use
433+
`mkdir -p "#{shared_cache_dir()}"`
434+
FileUtils.cp(destination_path, cached_path)
435+
rncore_log("Saved #{filename} to shared cache (#{shared_cache_dir()})")
418436
end
419437

420438
return destination_path

packages/react-native/scripts/cocoapods/rndependencies.rb

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,15 +232,36 @@ def self.podspec_source_download_prebuilt_nightly_tarball(version)
232232
return {:http => url}
233233
end
234234

235+
def self.shared_cache_dir()
236+
return File.join(Dir.home, "Library", "Caches", "ReactNative")
237+
end
238+
235239
def self.download_rndeps_tarball(react_native_path, tarball_url, version, configuration)
236-
destination_path = configuration == nil ?
237-
"#{artifacts_dir()}/reactnative-dependencies-#{version}.tar.gz" :
238-
"#{artifacts_dir()}/reactnative-dependencies-#{version}-#{configuration}.tar.gz"
240+
filename = configuration == nil ?
241+
"reactnative-dependencies-#{version}.tar.gz" :
242+
"reactnative-dependencies-#{version}-#{configuration}.tar.gz"
243+
destination_path = "#{artifacts_dir()}/#{filename}"
244+
245+
if File.exist?(destination_path)
246+
rndeps_log("Tarball #{filename} already exists in Pods. Skipping download.")
247+
return destination_path
248+
end
239249

240-
unless File.exist?(destination_path)
250+
`mkdir -p "#{artifacts_dir()}"`
251+
252+
cached_path = File.join(shared_cache_dir(), filename)
253+
if File.exist?(cached_path)
254+
rndeps_log("Cache hit: copying #{filename} from shared cache (#{shared_cache_dir()})")
255+
FileUtils.cp(cached_path, destination_path)
256+
else
257+
rndeps_log("Cache miss: downloading #{filename} from #{tarball_url}")
241258
# Download to a temporary file first so we don't cache incomplete downloads.
242259
tmp_file = "#{artifacts_dir()}/reactnative-dependencies.download"
243-
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
260+
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
261+
# Save to shared cache for future use
262+
`mkdir -p "#{shared_cache_dir()}"`
263+
FileUtils.cp(destination_path, cached_path)
264+
rndeps_log("Saved #{filename} to shared cache (#{shared_cache_dir()})")
244265
end
245266

246267
return destination_path

packages/react-native/sdks/hermes-engine/hermes-utils.rb

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,16 +236,38 @@ def download_stable_hermes(react_native_path, version, configuration)
236236
download_hermes_tarball(react_native_path, tarball_url, version, configuration)
237237
end
238238

239+
def shared_cache_dir()
240+
return File.join(Dir.home, "Library", "Caches", "ReactNative")
241+
end
242+
239243
def download_hermes_tarball(react_native_path, tarball_url, version, configuration)
240-
destination_path = configuration == nil ?
241-
"#{artifacts_dir()}/hermes-ios-#{version}.tar.gz" :
242-
"#{artifacts_dir()}/hermes-ios-#{version}-#{configuration}.tar.gz"
244+
filename = configuration == nil ?
245+
"hermes-ios-#{version}.tar.gz" :
246+
"hermes-ios-#{version}-#{configuration}.tar.gz"
247+
destination_path = "#{artifacts_dir()}/#{filename}"
248+
249+
if File.exist?(destination_path)
250+
hermes_log("Tarball #{filename} already exists in Pods. Skipping download.", :info)
251+
return destination_path
252+
end
243253

244-
unless File.exist?(destination_path)
254+
`mkdir -p "#{artifacts_dir()}"`
255+
256+
cached_path = File.join(shared_cache_dir(), filename)
257+
if File.exist?(cached_path)
258+
hermes_log("Cache hit: copying #{filename} from shared cache (#{shared_cache_dir()})", :info)
259+
FileUtils.cp(cached_path, destination_path)
260+
else
261+
hermes_log("Cache miss: downloading #{filename} from #{tarball_url}", :info)
245262
# Download to a temporary file first so we don't cache incomplete downloads.
246263
tmp_file = "#{artifacts_dir()}/hermes-ios.download"
247-
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
264+
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
265+
# Save to shared cache for future use
266+
`mkdir -p "#{shared_cache_dir()}"`
267+
FileUtils.cp(destination_path, cached_path)
268+
hermes_log("Saved #{filename} to shared cache (#{shared_cache_dir()})", :info)
248269
end
270+
249271
return destination_path
250272
end
251273

0 commit comments

Comments
 (0)