mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Move LocalPodspecPatch to dedicated file (#34025)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34025 This diff moves the monkeypatch LocalPodspecPatch to a dedicated ruby file. It also adds test for that ## Changelog [iOS][Changed] - Move LocalPodspecPatch to dedicated file Reviewed By: cortinico Differential Revision: D37069361 fbshipit-source-id: 28fddb197484f45aa20ccac516c874e79448e999
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b6bbbf8efa
commit
8fe2b591c7
@@ -0,0 +1,171 @@
|
||||
# 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 "test/unit"
|
||||
require "json"
|
||||
require_relative "../local_podspec_patch.rb"
|
||||
require_relative "./test_utils/FileMock.rb"
|
||||
require_relative "./test_utils/DirMock.rb"
|
||||
require_relative "./test_utils/PodMock.rb"
|
||||
require_relative "./test_utils/LocalPodspecPatchMock.rb"
|
||||
|
||||
class LocalPodspecPatchTests < Test::Unit::TestCase
|
||||
def setup
|
||||
File.enable_testing_mode!
|
||||
Dir.enable_testing_mode!
|
||||
end
|
||||
|
||||
def teardown
|
||||
File.reset()
|
||||
Dir.reset()
|
||||
end
|
||||
|
||||
# =================== #
|
||||
# Test - Pods To Update #
|
||||
# =================== #
|
||||
|
||||
def test_podsToUpdate_whenNoFilesExists_returnLocalPodspecs
|
||||
# Arrange
|
||||
react_native_path = "../node_modules/react-native"
|
||||
globs = ["a/path/to/boost.podspec", "a/path/to/DoubleConversion.podspec"]
|
||||
mocked_pwd = "a/path/to"
|
||||
Dir.mocked_existing_globs(globs, "#{react_native_path}/third-party-podspecs/*")
|
||||
Dir.set_pwd(mocked_pwd)
|
||||
|
||||
# Act
|
||||
local_podspec = LocalPodspecPatch.pods_to_update(:react_native_path => react_native_path)
|
||||
|
||||
# Assert
|
||||
assert_equal(local_podspec, [])
|
||||
assert_equal(Dir.glob_invocation, ["#{react_native_path}/third-party-podspecs/*"])
|
||||
assert_equal(File.exist_invocation_params, [
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "boost.podspec.json"),
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "DoubleConversion.podspec.json"),
|
||||
])
|
||||
end
|
||||
|
||||
def test_podsToUpdate_whenFilesExistsWithSameVersions_returnsEmpty
|
||||
# Arrange
|
||||
react_native_path = "../node_modules/react-native"
|
||||
globs = ["a/path/to/boost.podspec", "a/path/to/DoubleConversion.podspec"]
|
||||
mocked_pwd = "a/path/to"
|
||||
prepare_PodsToUpdate_test_withMatchingVersions(react_native_path, globs, mocked_pwd)
|
||||
|
||||
# Act
|
||||
local_podspec = LocalPodspecPatch.pods_to_update(:react_native_path => react_native_path)
|
||||
|
||||
# Assert
|
||||
assert_equal(local_podspec, [])
|
||||
assert_equal(Dir.glob_invocation, ["#{react_native_path}/third-party-podspecs/*"])
|
||||
assert_equal(File.exist_invocation_params, [
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "boost.podspec.json"),
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "DoubleConversion.podspec.json"),
|
||||
])
|
||||
end
|
||||
|
||||
def test_podsToUpdate_whenFilesExistsWithDifferentVersions_returnsThem
|
||||
# Arrange
|
||||
react_native_path = "../node_modules/react-native"
|
||||
globs = ["a/path/to/boost.podspec", "a/path/to/DoubleConversion.podspec"]
|
||||
mocked_pwd = "a/path/to"
|
||||
prepare_PodsToUpdate_test_withDifferentVersions(react_native_path, globs, mocked_pwd)
|
||||
|
||||
# Act
|
||||
local_podspec = LocalPodspecPatch.pods_to_update(:react_native_path => react_native_path)
|
||||
|
||||
# Assert
|
||||
assert_equal(local_podspec, [
|
||||
"boost",
|
||||
"DoubleConversion"
|
||||
])
|
||||
assert_equal(Dir.glob_invocation, ["#{react_native_path}/third-party-podspecs/*"])
|
||||
assert_equal(File.exist_invocation_params, [
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "boost.podspec.json"),
|
||||
File.join(mocked_pwd, "Pods/Local Podspecs", "DoubleConversion.podspec.json"),
|
||||
])
|
||||
end
|
||||
|
||||
# ======================================== #
|
||||
# Test - Patch Detect Changes With Podfile #
|
||||
# ======================================== #
|
||||
def test_patchDetectChangesWithPodfile_whenAlreadyChanged_returnSameChangeSet()
|
||||
local_pods = [
|
||||
"boost",
|
||||
"DoubleConversion"
|
||||
]
|
||||
LocalPodspecPatch.mock_local_podspecs(local_pods)
|
||||
changes = {
|
||||
:unchanged => ["some_pod"],
|
||||
:changed => ["boost", "DoubleConversion", "another_pod"]
|
||||
}
|
||||
|
||||
Pod::Lockfile.prepend(LocalPodspecPatch)
|
||||
|
||||
new_changes = Pod::Lockfile.new().patch_detect_changes_with_podfile(changes)
|
||||
|
||||
assert_equal(new_changes, {
|
||||
:unchanged => ["some_pod"],
|
||||
:changed => ["boost", "DoubleConversion", "another_pod"]
|
||||
})
|
||||
end
|
||||
|
||||
def test_patchDetectChangesWithPodfile_whenLocalPodsUnchanged_movesLocalPodsToChangeSet()
|
||||
pods = [
|
||||
"boost",
|
||||
"DoubleConversion"
|
||||
]
|
||||
LocalPodspecPatch.mock_local_podspecs(pods)
|
||||
changes = {
|
||||
:unchanged => ["first_pod", "boost", "DoubleConversion"],
|
||||
:changed => ["another_pod"]
|
||||
}
|
||||
|
||||
Pod::Lockfile.prepend(LocalPodspecPatch)
|
||||
|
||||
new_changes = Pod::Lockfile.new().patch_detect_changes_with_podfile(changes)
|
||||
|
||||
assert_equal(new_changes, {
|
||||
:unchanged => ["first_pod"],
|
||||
:changed => ["another_pod", "boost", "DoubleConversion"]
|
||||
})
|
||||
end
|
||||
|
||||
# ========= #
|
||||
# Utilities #
|
||||
# ========= #
|
||||
def prepare_PodsToUpdate_test_withMatchingVersions(react_native_path, globs, mocked_pwd)
|
||||
File.mocked_existing_files([
|
||||
"a/path/to/Pods/Local Podspecs/boost.podspec.json",
|
||||
"a/path/to/Pods/Local Podspecs/DoubleConversion.podspec.json"
|
||||
])
|
||||
File.files_to_read({
|
||||
"a/path/to/Pods/Local Podspecs/boost.podspec.json" => "{ \"version\": \"0.0.1\"}",
|
||||
"a/path/to/Pods/Local Podspecs/DoubleConversion.podspec.json" => "{ \"version\": \"1.0.1\"}",
|
||||
})
|
||||
Dir.mocked_existing_globs(globs, "#{react_native_path}/third-party-podspecs/*")
|
||||
Dir.set_pwd(mocked_pwd)
|
||||
Pod::Specification.specs_from_file({
|
||||
"../node_modules/react-native/third-party-podspecs/boost.podspec" => Pod::PodSpecMock.new(:version => "0.0.1"),
|
||||
"../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" => Pod::PodSpecMock.new(:version => "1.0.1"),
|
||||
})
|
||||
end
|
||||
|
||||
def prepare_PodsToUpdate_test_withDifferentVersions(react_native_path, globs, mocked_pwd)
|
||||
File.mocked_existing_files([
|
||||
"a/path/to/Pods/Local Podspecs/boost.podspec.json",
|
||||
"a/path/to/Pods/Local Podspecs/DoubleConversion.podspec.json"
|
||||
])
|
||||
File.files_to_read({
|
||||
"a/path/to/Pods/Local Podspecs/boost.podspec.json" => "{ \"version\": \"0.0.1\"}",
|
||||
"a/path/to/Pods/Local Podspecs/DoubleConversion.podspec.json" => "{ \"version\": \"1.0.1\"}",
|
||||
})
|
||||
Dir.mocked_existing_globs(globs, "#{react_native_path}/third-party-podspecs/*")
|
||||
Dir.set_pwd(mocked_pwd)
|
||||
Pod::Specification.specs_from_file({
|
||||
"../node_modules/react-native/third-party-podspecs/boost.podspec" => Pod::PodSpecMock.new(:version => "0.1.1"),
|
||||
"../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" => Pod::PodSpecMock.new(:version => "1.1.1"),
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -9,6 +9,11 @@ class Dir
|
||||
@@exist_invocation_params = []
|
||||
@@mocked_existing_dirs = []
|
||||
|
||||
@@glob_invocation = []
|
||||
@@mocked_existing_globs = {}
|
||||
|
||||
@@pwd = nil
|
||||
|
||||
# Monkey patched exists? method.
|
||||
# It is used also by the test runner, so it can't start monkey patched
|
||||
# To use this, invoke the `is_testing` method before starting your test.
|
||||
@@ -33,6 +38,31 @@ class Dir
|
||||
@@mocked_existing_dirs = dirs
|
||||
end
|
||||
|
||||
# Set what the `glob` function should return
|
||||
def self.mocked_existing_globs(globs, path)
|
||||
@@mocked_existing_globs[path] = globs
|
||||
end
|
||||
|
||||
def self.glob_invocation
|
||||
return @@glob_invocation
|
||||
end
|
||||
|
||||
def self.glob(path)
|
||||
@@glob_invocation.push(path)
|
||||
return @@mocked_existing_globs[path]
|
||||
end
|
||||
|
||||
def self.set_pwd(pwd)
|
||||
@@pwd = pwd
|
||||
end
|
||||
|
||||
def self.pwd
|
||||
if @@pwd != nil
|
||||
return @@pwd
|
||||
end
|
||||
return pwd
|
||||
end
|
||||
|
||||
# Turn on the mocking features of the File mock
|
||||
def self.enable_testing_mode!()
|
||||
@@is_testing = true
|
||||
@@ -40,8 +70,11 @@ class Dir
|
||||
|
||||
# Resets all the settings for the File mock
|
||||
def self.reset()
|
||||
@@pwd = nil
|
||||
@@mocked_existing_dirs = []
|
||||
@@is_testing = false
|
||||
@@exist_invocation_params = []
|
||||
@@glob_invocation = []
|
||||
@@mocked_existing_globs = {}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,6 +16,8 @@ class File
|
||||
@@open_invocation_count = 0
|
||||
|
||||
@@open_files = []
|
||||
|
||||
@@files_to_read = {}
|
||||
attr_reader :collected_write
|
||||
attr_reader :fsync_invocation_count
|
||||
|
||||
@@ -91,6 +93,10 @@ class File
|
||||
return @@open_files
|
||||
end
|
||||
|
||||
def self.file_invocation_params
|
||||
return @@file_invocation_params
|
||||
end
|
||||
|
||||
def write(text)
|
||||
@collected_write.push(text.to_s)
|
||||
end
|
||||
@@ -99,6 +105,15 @@ class File
|
||||
@fsync_invocation_count += 1
|
||||
end
|
||||
|
||||
|
||||
def self.files_to_read(files)
|
||||
@@files_to_read = files
|
||||
end
|
||||
|
||||
def self.read(filepath)
|
||||
return @@files_to_read[filepath]
|
||||
end
|
||||
|
||||
# Resets all the settings for the File mock
|
||||
def self.reset()
|
||||
@@delete_invocation_count = 0
|
||||
@@ -108,7 +123,9 @@ class File
|
||||
@@open_invocation_count = 0
|
||||
@@mocked_existing_files = []
|
||||
@@is_testing = false
|
||||
@@file_invocation_params = []
|
||||
@@exist_invocation_params = []
|
||||
@@files_to_read = {}
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# 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.
|
||||
|
||||
module LocalPodspecPatch
|
||||
def self.mock_local_podspecs(pods)
|
||||
@@local_podspecs = pods
|
||||
end
|
||||
|
||||
def reset()
|
||||
@@local_podspecs = []
|
||||
end
|
||||
end
|
||||
@@ -83,4 +83,33 @@ module Pod
|
||||
@@executed_commands = []
|
||||
end
|
||||
end
|
||||
|
||||
class Specification
|
||||
@@specs_from_file = {}
|
||||
|
||||
def self.specs_from_file(specs)
|
||||
@@specs_from_file = specs
|
||||
end
|
||||
|
||||
def self.from_file(path)
|
||||
return @@specs_from_file[path]
|
||||
end
|
||||
|
||||
def reset()
|
||||
@@specs_from_file = {}
|
||||
end
|
||||
end
|
||||
|
||||
class PodSpecMock
|
||||
attr_reader :version
|
||||
|
||||
def initialize(version: "0.0.1")
|
||||
@version = version
|
||||
end
|
||||
end
|
||||
|
||||
class Lockfile
|
||||
def initialize()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# 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.
|
||||
|
||||
# Monkeypatch of `Pod::Lockfile` to ensure automatic update of dependencies integrated with a local podspec when their version changed.
|
||||
# This is necessary because local podspec dependencies must be otherwise manually updated.
|
||||
module LocalPodspecPatch
|
||||
# Returns local podspecs whose versions differ from the one in the `react-native` package.
|
||||
def self.pods_to_update(react_native_path: "../node_modules/react-native")
|
||||
@@local_podspecs = Dir.glob("#{react_native_path}/third-party-podspecs/*").map { |file| File.basename(file, ".podspec") }
|
||||
@@local_podspecs = @@local_podspecs.select do |podspec_name|
|
||||
|
||||
# Read local podspec to determine the cached version
|
||||
local_podspec_path = File.join(
|
||||
Dir.pwd, "Pods/Local Podspecs/#{podspec_name}.podspec.json"
|
||||
)
|
||||
|
||||
# Local podspec cannot be outdated if it does not exist, yet
|
||||
next unless File.exist?(local_podspec_path)
|
||||
|
||||
local_podspec = File.read(local_podspec_path)
|
||||
local_podspec_json = JSON.parse(local_podspec)
|
||||
local_version = local_podspec_json["version"]
|
||||
|
||||
# Read the version from a podspec from the `react-native` package
|
||||
podspec_path = "#{react_native_path}/third-party-podspecs/#{podspec_name}.podspec"
|
||||
current_podspec = Pod::Specification.from_file(podspec_path)
|
||||
current_version = current_podspec.version.to_s
|
||||
current_version != local_version
|
||||
end
|
||||
@@local_podspecs
|
||||
end
|
||||
|
||||
# Patched `detect_changes_with_podfile` method
|
||||
def detect_changes_with_podfile(podfile)
|
||||
Pod::UI.puts "Invoke detect_changes_with_podfile patched method".red
|
||||
changes = super(podfile)
|
||||
return patch_detect_changes_with_podfile(changes)
|
||||
end
|
||||
|
||||
def patch_detect_changes_with_podfile(changes)
|
||||
@@local_podspecs.each do |local_podspec|
|
||||
next unless changes[:unchanged].include?(local_podspec)
|
||||
|
||||
changes[:unchanged].delete(local_podspec)
|
||||
changes[:changed] << local_podspec
|
||||
end
|
||||
changes
|
||||
end
|
||||
end
|
||||
@@ -12,6 +12,7 @@ require_relative './cocoapods/fabric.rb'
|
||||
require_relative './cocoapods/codegen.rb'
|
||||
require_relative './cocoapods/utils.rb'
|
||||
require_relative './cocoapods/new_architecture.rb'
|
||||
require_relative './cocoapods/local_podspec_patch.rb'
|
||||
|
||||
$CODEGEN_OUTPUT_DIR = 'build/generated/ios'
|
||||
$CODEGEN_COMPONENT_DIR = 'react/renderer/components'
|
||||
@@ -121,7 +122,7 @@ def use_react_native! (options={})
|
||||
use_flipper_pods(flipper_configuration.versions, :configurations => flipper_configuration.configurations)
|
||||
end
|
||||
|
||||
pods_to_update = LocalPodspecPatch.pods_to_update(options)
|
||||
pods_to_update = LocalPodspecPatch.pods_to_update(:react_native_path => prefix)
|
||||
if !pods_to_update.empty?
|
||||
if Pod::Lockfile.public_instance_methods.include?(:detect_changes_with_podfile)
|
||||
Pod::Lockfile.prepend(LocalPodspecPatch)
|
||||
@@ -497,46 +498,3 @@ def __apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
time_header = "#{Pod::Config.instance.installation_root.to_s}/Pods/RCT-Folly/folly/portability/Time.h"
|
||||
`sed -i -e $'s/ && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)//' #{time_header}`
|
||||
end
|
||||
|
||||
# Monkeypatch of `Pod::Lockfile` to ensure automatic update of dependencies integrated with a local podspec when their version changed.
|
||||
# This is necessary because local podspec dependencies must be otherwise manually updated.
|
||||
module LocalPodspecPatch
|
||||
# Returns local podspecs whose versions differ from the one in the `react-native` package.
|
||||
def self.pods_to_update(react_native_options)
|
||||
prefix = react_native_options[:path] ||= "../node_modules/react-native"
|
||||
@@local_podspecs = Dir.glob("#{prefix}/third-party-podspecs/*").map { |file| File.basename(file, ".podspec") }
|
||||
@@local_podspecs = @@local_podspecs.select do |podspec_name|
|
||||
# Read local podspec to determine the cached version
|
||||
local_podspec_path = File.join(
|
||||
Dir.pwd, "Pods/Local Podspecs/#{podspec_name}.podspec.json"
|
||||
)
|
||||
|
||||
# Local podspec cannot be outdated if it does not exist, yet
|
||||
next unless File.file?(local_podspec_path)
|
||||
|
||||
local_podspec = File.read(local_podspec_path)
|
||||
local_podspec_json = JSON.parse(local_podspec)
|
||||
local_version = local_podspec_json["version"]
|
||||
|
||||
# Read the version from a podspec from the `react-native` package
|
||||
podspec_path = "#{prefix}/third-party-podspecs/#{podspec_name}.podspec"
|
||||
current_podspec = Pod::Specification.from_file(podspec_path)
|
||||
|
||||
current_version = current_podspec.version.to_s
|
||||
current_version != local_version
|
||||
end
|
||||
@@local_podspecs
|
||||
end
|
||||
|
||||
# Patched `detect_changes_with_podfile` method
|
||||
def detect_changes_with_podfile(podfile)
|
||||
changes = super(podfile)
|
||||
@@local_podspecs.each do |local_podspec|
|
||||
next unless changes[:unchanged].include?(local_podspec)
|
||||
|
||||
changes[:unchanged].delete(local_podspec)
|
||||
changes[:changed] << local_podspec
|
||||
end
|
||||
changes
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user