Skip to content

Commit b2517c3

Browse files
fortmarekfacebook-github-bot
authored andcommitted
Automatic update of RCT-Folly (#32659)
Summary: When upgrading `react-native`, the version `RCT-Folly` defined [here](https://github.com/facebook/react-native/blob/main/third-party-podspecs/RCT-Folly.podspec) can change. If that happens, if you run `pod install` after `yarn install`, you will get a similar error to this: ``` [!] CocoaPods could not find compatible versions for pod "RCT-Folly": In snapshot (Podfile.lock): RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) In Podfile: RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) was resolved to 0.66.3, which depends on RCT-Folly (= 2021.06.28.00-v2) ``` This error occurs because `Cocoapods` does not update pods that point to a local podspec. Locally, you could resolve this issue by running `pod update RCT-Folly --no-repo-update`. On the CI, you have to do a clean checkout (in case you cache the `Pods` folder which we do). All of this makes upgrading `react-native` painful - for the whole community and for us shopify There are other users who have struggled with this, such as [here](#32423). The suggestion there is to delete `Podfile.lock` which is unnecessary - but it shows that users are confused what to do with this error and is something worth fixing. To mitigate these issues, `react_native_pods.rb` automatically marks `RCT-Folly` as changed in the [detect_changes_with_podfile method](https://github.com/CocoaPods/Core/blob/master/lib/cocoapods-core/lockfile.rb#L289) from `Pod::Lockfile` if the version in `node_modules/react-native/third-party-podspecs/RCT-Folly.podspec` and `Pods/Local Podspecs/RCT-Folly.podspec.json` mismatch. Instead of automatically updating the local podspec (in `Pods/Local Podspecs` directory) we could also: a) integrate `RCT-Folly` as a local pod (such as `React-Core` and others) b) integrate `RCT-Folly` as an external dependency (going through Cocoapods' centralized repository) I don't have enough context on why `RCT-Folly` is bundled the way it is, so I am open to suggestions here. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Fixed] - Fix `pod install` when `RCT-Folly` version has been updated. Pull Request resolved: #32659 Test Plan: I have created a [repository](https://github.com/fortmarek/react-native-upgrade-reproduction) where you can reproduce the issue. You can simply: 1) clone the repo (`git clone https://github.com/fortmarek/react-native-upgrade-reproduction`) 2) Run `yarn install && cd ios && pod install` 3) Change `react-native` version in `package.json` to `0.66.3` 4) Run again `yarn install && pod install` 5) Observe error To test the fix, you can then: 1) copy-paste the `react_native_pods.rb` file from this branch to `react-native-upgrade-reproduction/node_modules/scripts/react_native_pods.rb` 2) run `pod install` again This time, the `pod install` command should succeed. Reviewed By: sota000 Differential Revision: D32720758 Pulled By: cortinico fbshipit-source-id: 940db9c9f0530f896e47b676dec46bc93cea0085
1 parent c71e6ef commit b2517c3

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

scripts/react_native_pods.rb

+52
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ def use_react_native! (options={})
119119
end
120120
pod 'libevent', '~> 2.1.12'
121121
end
122+
123+
pods_to_update = LocalPodspecPatch.pods_to_update(options)
124+
if !pods_to_update.empty?
125+
if Pod::Lockfile.public_instance_methods.include?(:detect_changes_with_podfile)
126+
Pod::Lockfile.prepend(LocalPodspecPatch)
127+
else
128+
Pod::UI.warn "Automatically updating #{pods_to_update.join(", ")} has failed, please run `pod update #{pods_to_update.join(" ")} --no-repo-update` manually to fix the issue."
129+
end
130+
end
122131
end
123132

124133
def get_default_flags()
@@ -696,3 +705,46 @@ def __apply_Xcode_12_5_M1_post_install_workaround(installer)
696705
time_header = "#{Pod::Config.instance.installation_root.to_s}/Pods/RCT-Folly/folly/portability/Time.h"
697706
`sed -i -e $'s/ && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)//' #{time_header}`
698707
end
708+
709+
# Monkeypatch of `Pod::Lockfile` to ensure automatic update of dependencies integrated with a local podspec when their version changed.
710+
# This is necessary because local podspec dependencies must be otherwise manually updated.
711+
module LocalPodspecPatch
712+
# Returns local podspecs whose versions differ from the one in the `react-native` package.
713+
def self.pods_to_update(react_native_options)
714+
prefix = react_native_options[:path] ||= "../node_modules/react-native"
715+
@@local_podspecs = Dir.glob("#{prefix}/third-party-podspecs/*").map { |file| File.basename(file, ".podspec") }
716+
@@local_podspecs = @@local_podspecs.select do |podspec_name|
717+
# Read local podspec to determine the cached version
718+
local_podspec_path = File.join(
719+
Dir.pwd, "Pods/Local Podspecs/#{podspec_name}.podspec.json"
720+
)
721+
722+
# Local podspec cannot be outdated if it does not exist, yet
723+
next unless File.file?(local_podspec_path)
724+
725+
local_podspec = File.read(local_podspec_path)
726+
local_podspec_json = JSON.parse(local_podspec)
727+
local_version = local_podspec_json["version"]
728+
729+
# Read the version from a podspec from the `react-native` package
730+
podspec_path = "#{prefix}/third-party-podspecs/#{podspec_name}.podspec"
731+
current_podspec = Pod::Specification.from_file(podspec_path)
732+
733+
current_version = current_podspec.version.to_s
734+
current_version != local_version
735+
end
736+
@@local_podspecs
737+
end
738+
739+
# Patched `detect_changes_with_podfile` method
740+
def detect_changes_with_podfile(podfile)
741+
changes = super(podfile)
742+
@@local_podspecs.each do |local_podspec|
743+
next unless changes[:unchanged].include?(local_podspec)
744+
745+
changes[:unchanged].delete(local_podspec)
746+
changes[:changed] << local_podspec
747+
end
748+
changes
749+
end
750+
end

0 commit comments

Comments
 (0)