Skip to content

Commit 2092992

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 2f1d1e3 commit 2092992

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
@@ -405,18 +405,36 @@ def self.download_nightly_rncore(react_native_path, version, configuration, dsym
405405
download_rncore_tarball(react_native_path, tarball_url, version, configuration, dsyms)
406406
end
407407

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

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

422440
return destination_path

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

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

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

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

245266
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
@@ -206,16 +206,38 @@ def download_stable_hermes(react_native_path, version, configuration)
206206
download_hermes_tarball(react_native_path, tarball_url, version, configuration)
207207
end
208208

209+
def shared_cache_dir()
210+
return File.join(Dir.home, "Library", "Caches", "ReactNative")
211+
end
212+
209213
def download_hermes_tarball(react_native_path, tarball_url, version, configuration)
210-
destination_path = configuration == nil ?
211-
"#{artifacts_dir()}/hermes-ios-#{version}.tar.gz" :
212-
"#{artifacts_dir()}/hermes-ios-#{version}-#{configuration}.tar.gz"
214+
filename = configuration == nil ?
215+
"hermes-ios-#{version}.tar.gz" :
216+
"hermes-ios-#{version}-#{configuration}.tar.gz"
217+
destination_path = "#{artifacts_dir()}/#{filename}"
218+
219+
if File.exist?(destination_path)
220+
hermes_log("Tarball #{filename} already exists in Pods. Skipping download.", :info)
221+
return destination_path
222+
end
213223

214-
unless File.exist?(destination_path)
224+
`mkdir -p "#{artifacts_dir()}"`
225+
226+
cached_path = File.join(shared_cache_dir(), filename)
227+
if File.exist?(cached_path)
228+
hermes_log("Cache hit: copying #{filename} from shared cache (#{shared_cache_dir()})", :info)
229+
FileUtils.cp(cached_path, destination_path)
230+
else
231+
hermes_log("Cache miss: downloading #{filename} from #{tarball_url}", :info)
215232
# Download to a temporary file first so we don't cache incomplete downloads.
216233
tmp_file = "#{artifacts_dir()}/hermes-ios.download"
217-
`mkdir -p "#{artifacts_dir()}" && curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
234+
`curl "#{tarball_url}" -Lo "#{tmp_file}" && mv "#{tmp_file}" "#{destination_path}"`
235+
# Save to shared cache for future use
236+
`mkdir -p "#{shared_cache_dir()}"`
237+
FileUtils.cp(destination_path, cached_path)
238+
hermes_log("Saved #{filename} to shared cache (#{shared_cache_dir()})", :info)
218239
end
240+
219241
return destination_path
220242
end
221243

0 commit comments

Comments
 (0)