diff --git a/package.json b/package.json index 1180982b192dc6..0f8c55c64f9931 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "scripts/react_native_pods_utils/script_phases.rb", "scripts/react_native_pods_utils/script_phases.sh", "scripts/react_native_pods.rb", + "scripts/cocoapods/codegen.rb", + "scripts/cocoapods/fabric.rb", "scripts/cocoapods/flipper.rb", "scripts/react-native-xcode.sh", "sdks/hermes-engine", diff --git a/scripts/cocoapods/__tests__/codegen-test.rb b/scripts/cocoapods/__tests__/codegen-test.rb new file mode 100644 index 00000000000000..62526d9b4b5001 --- /dev/null +++ b/scripts/cocoapods/__tests__/codegen-test.rb @@ -0,0 +1,185 @@ +# 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_relative "../codegen.rb" +require_relative "./test_utils/PodMock.rb" +require_relative "./test_utils/PathnameMock.rb" +require_relative "./test_utils/FileMock.rb" +require_relative "./test_utils/DirMock.rb" +require_relative "./test_utils/systemUtils.rb" + +class CodegenTests < Test::Unit::TestCase + :third_party_provider_header + :third_party_provider_implementation + :base_path + :prefix + :tmp_schema_list_file + + def setup + File.enable_testing_mode! + Dir.enable_testing_mode! + Pod::Config.reset() + + @prefix = "../.." + @third_party_provider_header = "RCTThirdPartyFabricComponentsProvider.h" + @third_party_provider_implementation = "RCTThirdPartyFabricComponentsProvider.cpp" + @base_path = "~/app/ios" + @tmp_schema_list_file = "tmpSchemaList.txt" + Pathname.pwd!(@base_path) + Pod::Config.instance.installation_root.relative_path_from = @base_path + end + + def teardown + system_reset_commands() + Pod::UI.reset() + Pod::Executable.reset() + Pathname.reset() + File.reset() + Dir.reset() + end + + # ============================================== # + # Test - setup_fabric # + # ============================================== # + def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing() + + # Arrange + File.mocked_existing_files([ + @base_path + "/build/" + @third_party_provider_header, + @base_path + "/build/" + @third_party_provider_implementation, + ]) + + # Act + checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') + + # Assert + assert_equal(Pathname.pwd_invocation_count, 1) + assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) + assert_equal(File.exist_invocation_params, [ + @base_path + "/build/" + @third_party_provider_header, + @base_path + "/build/" + @third_party_provider_implementation, + ]) + assert_equal(Dir.exist_invocation_params, []) + assert_equal(Pod::UI.collected_messages, []) + assert_equal($collected_commands, []) + assert_equal(File.open_files.length, 0) + assert_equal(Pod::Executable.executed_commands.length, 0) + end + + def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_raiseError() + + # Arrange + File.mocked_existing_files([ + @base_path + "/build/" + @third_party_provider_implementation, + ]) + + # Act + assert_raise { + checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') + } + + # Assert + assert_equal(Pathname.pwd_invocation_count, 1) + assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) + assert_equal(File.exist_invocation_params, [ + @base_path + "/build/" + @third_party_provider_header + ]) + assert_equal(Dir.exist_invocation_params, [ + @base_path + "/"+ @prefix + "/packages/react-native-codegen", + @base_path + "/"+ @prefix + "/../react-native-codegen", + ]) + assert_equal(Pod::UI.collected_messages, []) + assert_equal($collected_commands, []) + assert_equal(File.open_files.length, 0) + assert_equal(Pod::Executable.executed_commands.length, 0) + end + + def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen() + + # Arrange + File.mocked_existing_files([ + @base_path + "/build/" + @third_party_provider_header, + @base_path + "/build/tmpSchemaList.txt" + ]) + + Dir.mocked_existing_dirs([ + @base_path + "/"+ @prefix + "/packages/react-native-codegen", + @base_path + "/"+ @prefix + "/packages/react-native-codegen/lib" + ]) + + # Act + checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') + + # Assert + assert_equal(Pathname.pwd_invocation_count, 1) + assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) + assert_equal(File.exist_invocation_params, [ + @base_path + "/build/" + @third_party_provider_header, + @base_path + "/build/" + @third_party_provider_implementation, + @base_path + "/build/tmpSchemaList.txt", + ]) + assert_equal(Dir.exist_invocation_params, [ + @base_path + "/"+ @prefix + "/packages/react-native-codegen", + @base_path + "/"+ @prefix + "/packages/react-native-codegen/lib", + ]) + assert_equal(Pod::UI.collected_messages, ["[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"]) + assert_equal($collected_commands, []) + assert_equal(File.open_invocation_count, 1) + assert_equal(File.open_files_with_mode[@base_path + "/build/tmpSchemaList.txt"], 'w') + assert_equal(File.open_files[0].collected_write, ["[]"]) + assert_equal(File.open_files[0].fsync_invocation_count, 1) + assert_equal(Pod::Executable.executed_commands[0], { + "command" => "node", + "arguments" => [ + @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", + "--platform", 'ios', + "--schemaListPath", @base_path + "/build/tmpSchemaList.txt", + "--outputDir", @base_path + "/build" + ] + }) + assert_equal(File.delete_invocation_count, 1) + assert_equal(File.deleted_files, [@base_path + "/build/tmpSchemaList.txt"]) + end + + def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen() + # Arrange + codegen_cli_path = @base_path + "/" + @prefix + "/../react-native-codegen" + Dir.mocked_existing_dirs([ + codegen_cli_path, + ]) + # Act + checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') + + # Assert + assert_equal(Pathname.pwd_invocation_count, 1) + assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) + assert_equal(File.exist_invocation_params, [ + @base_path + "/build/" + @third_party_provider_header, + @base_path + "/build/" + @tmp_schema_list_file + ]) + assert_equal(Dir.exist_invocation_params, [ + @base_path + "/" + @prefix + "/packages/react-native-codegen", + codegen_cli_path, + codegen_cli_path + "/lib", + ]) + assert_equal(Pod::UI.collected_messages, [ + "[Codegen] building #{codegen_cli_path}.", + "[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider" + ]) + assert_equal($collected_commands, ["~/app/ios/../../../react-native-codegen/scripts/oss/build.sh"]) + assert_equal(File.open_files[0].collected_write, ["[]"]) + assert_equal(File.open_files[0].fsync_invocation_count, 1) + assert_equal(Pod::Executable.executed_commands[0], { + "command" => "node", + "arguments" => [ + @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", + "--platform", 'ios', + "--schemaListPath", @base_path + "/build/" + @tmp_schema_list_file, + "--outputDir", @base_path + "/build" + ] + }) + end +end diff --git a/scripts/cocoapods/__tests__/fabric-test.rb b/scripts/cocoapods/__tests__/fabric-test.rb new file mode 100644 index 00000000000000..0cb0a6316161cb --- /dev/null +++ b/scripts/cocoapods/__tests__/fabric-test.rb @@ -0,0 +1,49 @@ +# 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_relative "../fabric.rb" +require_relative "./test_utils/podSpy.rb" + +class FabricTest < Test::Unit::TestCase + + def setup + podSpy_cleanUp() + end + + def test_setupFabric_installsPods + # Arrange + prefix = "../.." + + # Act + setup_fabric!(prefix) + + # Assert + check_installed_pods(prefix) + end + + def check_installed_pods(prefix) + assert_equal($podInvocationCount, 6) + + check_pod("React-Fabric", :path => "#{prefix}/ReactCommon") + check_pod("React-rncore", :path => "#{prefix}/ReactCommon") + check_pod("React-graphics", :path => "#{prefix}/ReactCommon/react/renderer/graphics") + check_pod("React-jsi/Fabric", :path => "#{prefix}/ReactCommon/jsi") + check_pod("React-RCTFabric", :path => "#{prefix}/React", :modular_headers => true) + check_pod("RCT-Folly/Fabric", :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec") + end + + def check_pod(name, path: nil, modular_headers: nil, podspec: nil) + params = $podInvocation[name] + expected_params = {} + + if path != nil then expected_params[:path] = path end + if modular_headers != nil then expected_params[:modular_headers] = modular_headers end + if podspec != nil then expected_params[:podspec] = podspec end + + assert_equal(params, expected_params) + end + +end diff --git a/scripts/cocoapods/__tests__/test_utils/DirMock.rb b/scripts/cocoapods/__tests__/test_utils/DirMock.rb new file mode 100644 index 00000000000000..329ab5c57ebfb1 --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/DirMock.rb @@ -0,0 +1,47 @@ +# 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. + +class Dir + + @@is_testing = false + @@exist_invocation_params = [] + @@mocked_existing_dirs = [] + + # 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. + # Remember to invoke `reset` after the test. + def self.exist?(path) + if !@@is_testing + return exists?(path) + end + + @@exist_invocation_params.push(path) + return @@mocked_existing_dirs.include?(path) + end + + # Getter for the `exist_invocation_params` to check that the exist method + # is invoked with the right parameters + def self.exist_invocation_params() + return @@exist_invocation_params + end + + # Set the list of dirs the test must return as existing + def self.mocked_existing_dirs(dirs) + @@mocked_existing_dirs = dirs + end + + # Turn on the mocking features of the File mock + def self.enable_testing_mode!() + @@is_testing = true + end + + # Resets all the settings for the File mock + def self.reset() + @@mocked_existing_dirs = [] + @@is_testing = false + @@exist_invocation_params = [] + end +end diff --git a/scripts/cocoapods/__tests__/test_utils/FileMock.rb b/scripts/cocoapods/__tests__/test_utils/FileMock.rb new file mode 100644 index 00000000000000..7099047cb2d350 --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/FileMock.rb @@ -0,0 +1,115 @@ +# 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. + +class File + + @@is_testing = false + @@exist_invocation_params = [] + @@mocked_existing_files = [] + + @@delete_invocation_count = 0 + @@deleted_files = [] + + @@open_files_with_mode = {} + @@open_invocation_count = 0 + + @@open_files = [] + attr_reader :collected_write + attr_reader :fsync_invocation_count + + def initialize() + @collected_write = [] + @fsync_invocation_count = 0 + end + + # 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. + # Remember to invoke `reset` after the test. + def self.exist?(path) + if !@@is_testing + return exists?(path) + end + + @@exist_invocation_params.push(path) + return @@mocked_existing_files.include?(path) + end + + def self.delete(path) + if !@@is_testing + delete(path) + return + end + + @@delete_invocation_count += 1 + @@deleted_files.push(path) + end + + def self.delete_invocation_count + return @@delete_invocation_count + end + + def self.deleted_files + return @@deleted_files + end + + # Getter for the `exist_invocation_params` to check that the exist method + # is invoked the right number of times with the right parameters + def self.exist_invocation_params() + return @@exist_invocation_params + end + + # Set the list of files the test must return as existing + def self.mocked_existing_files(files) + @@mocked_existing_files = files + end + + # Turn on the mocking features of the File mock + def self.enable_testing_mode!() + @@is_testing = true + end + + def self.open(path, mode, &block) + @@open_files_with_mode[path] = mode + @@open_invocation_count += 1 + file = File.new() + @@open_files.push(file) + yield(file) + end + + def self.open_files_with_mode + return @@open_files_with_mode + end + + def self.open_invocation_count + return @@open_invocation_count + end + + def self.open_files + return @@open_files + end + + def write(text) + @collected_write.push(text.to_s) + end + + def fsync() + @fsync_invocation_count += 1 + end + + # Resets all the settings for the File mock + def self.reset() + @@delete_invocation_count = 0 + @@deleted_files = [] + @@open_files = [] + @@open_files_with_mode = {} + @@open_invocation_count = 0 + @@mocked_existing_files = [] + @@is_testing = false + @@exist_invocation_params = [] + end + + +end diff --git a/scripts/cocoapods/__tests__/test_utils/PathnameMock.rb b/scripts/cocoapods/__tests__/test_utils/PathnameMock.rb new file mode 100644 index 00000000000000..7aa763bc2e5cb9 --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/PathnameMock.rb @@ -0,0 +1,28 @@ +# 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. + +class Pathname + @@pwd = "" + @@pwd_invocation_count = 0 + + def self.pwd!(pwd) + @@pwd = pwd + end + + def self.pwd() + @@pwd_invocation_count += 1 + return @@pwd + end + + def self.pwd_invocation_count + return @@pwd_invocation_count + end + + + def self.reset() + @@pwd = "" + @@pwd_invocation_count = 0 + end +end diff --git a/scripts/cocoapods/__tests__/test_utils/PodMock.rb b/scripts/cocoapods/__tests__/test_utils/PodMock.rb new file mode 100644 index 00000000000000..4f110a868ce18c --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/PodMock.rb @@ -0,0 +1,76 @@ +# 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 Pod + class Config + @@instance = Config.new() + + attr_reader :installation_root + + def initialize() + @installation_root = InstallationRootMock.new() + end + + def self.instance() + return @@instance + end + + def self.reset() + @@instance = Config.new() + end + end + + class InstallationRootMock + + attr_accessor :relative_path_from + attr_reader :relative_path_from_invocation_count + + def initialize() + @relative_path_from = "" + @relative_path_from_invocation_count = 0 + end + + def relative_path_from(path) + @relative_path_from_invocation_count += 1 + return @relative_path_from + end + end + + class UI + + @@collected_messages = [] + + def self.puts(message) + @@collected_messages.push(message) + end + + def self.collected_messages() + return @@collected_messages + end + + def self.reset() + @@collected_messages = [] + end + end + + class Executable + @@executed_commands = [] + + def self.execute_command(command, arguments) + @@executed_commands.push({ + "command" => command, + "arguments" => arguments + }) + end + + def self.executed_commands + return @@executed_commands + end + + def self.reset() + @@executed_commands = [] + end + end +end diff --git a/scripts/cocoapods/__tests__/test_utils/podSpy.rb b/scripts/cocoapods/__tests__/test_utils/podSpy.rb index 415bc73f832a49..76da694cf85f73 100644 --- a/scripts/cocoapods/__tests__/test_utils/podSpy.rb +++ b/scripts/cocoapods/__tests__/test_utils/podSpy.rb @@ -26,11 +26,13 @@ def podSpy_cleanUp $podInvocationCount = 0 end -def pod(name, version = nil, path: nil, configurations: nil) +def pod(name, version = nil, path: nil, configurations: nil, modular_headers: nil, podspec: nil) $podInvocationCount += 1 params = {} if version != nil then params[:version] = version end if path != nil then params[:path] = path end if configurations != nil then params[:configurations] = configurations end + if modular_headers != nil then params[:modular_headers] = modular_headers end + if podspec != nil then params[:podspec] = podspec end $podInvocation[name] = params end diff --git a/scripts/cocoapods/__tests__/test_utils/systemUtils.rb b/scripts/cocoapods/__tests__/test_utils/systemUtils.rb new file mode 100644 index 00000000000000..d5269dd3fa0c1f --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/systemUtils.rb @@ -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. + +$collected_commands = [] + +def system(command) + $collected_commands.push(command) +end + +def system_reset_commands() + $collected_commands = [] +end diff --git a/scripts/cocoapods/codegen.rb b/scripts/cocoapods/codegen.rb new file mode 100644 index 00000000000000..fff57845ef12f8 --- /dev/null +++ b/scripts/cocoapods/codegen.rb @@ -0,0 +1,67 @@ +# 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. + +# It builds the codegen CLI if it is not present +# +# @parameter react_native_path: the path to the react native installation +# @parameter relative_installation_root: the path to the relative installation root of the pods +# @throws an error if it could not find the codegen folder. +def build_codegen!(react_native_path, relative_installation_root) + codegen_repo_path = "#{relative_installation_root}/#{react_native_path}/packages/react-native-codegen"; + codegen_npm_path = "#{relative_installation_root}/#{react_native_path}/../react-native-codegen"; + codegen_cli_path = "" + + if Dir.exist?(codegen_repo_path) + codegen_cli_path = codegen_repo_path + elsif Dir.exist?(codegen_npm_path) + codegen_cli_path = codegen_npm_path + else + raise "[codegen] Couldn't not find react-native-codegen." + end + + if !Dir.exist?("#{codegen_cli_path}/lib") + Pod::UI.puts "[Codegen] building #{codegen_cli_path}." + system("#{codegen_cli_path}/scripts/oss/build.sh") + end + end + +# It generates an empty `ThirdPartyProvider`, required by Fabric to load the components +# +# @parameter react_native_path: path to the react native framework +# @parameter new_arch_enabled: whether the New Architecture is enabled or not +# @parameter codegen_output_dir: the output directory for the codegen +def checkAndGenerateEmptyThirdPartyProvider!(react_native_path, new_arch_enabled, codegen_output_dir) + return if new_arch_enabled + + relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) + + output_dir = "#{relative_installation_root}/#{codegen_output_dir}" + + provider_h_path = "#{output_dir}/RCTThirdPartyFabricComponentsProvider.h" + provider_cpp_path ="#{output_dir}/RCTThirdPartyFabricComponentsProvider.cpp" + + if(!File.exist?(provider_h_path) || !File.exist?(provider_cpp_path)) + # build codegen + build_codegen!(react_native_path, relative_installation_root) + + # Just use a temp empty schema list. + temp_schema_list_path = "#{output_dir}/tmpSchemaList.txt" + File.open(temp_schema_list_path, 'w') do |f| + f.write('[]') + f.fsync + end + + Pod::UI.puts '[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider' + Pod::Executable.execute_command( + 'node', + [ + "#{relative_installation_root}/#{react_native_path}/scripts/generate-provider-cli.js", + "--platform", 'ios', + "--schemaListPath", temp_schema_list_path, + "--outputDir", "#{output_dir}" + ]) + File.delete(temp_schema_list_path) if File.exist?(temp_schema_list_path) + end +end diff --git a/scripts/cocoapods/fabric.rb b/scripts/cocoapods/fabric.rb new file mode 100644 index 00000000000000..c27bf7975ed84c --- /dev/null +++ b/scripts/cocoapods/fabric.rb @@ -0,0 +1,19 @@ +# 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. + + +# It sets up the faric dependencies. +# +# @parameter prefix: prefix to use to reach react-native +# @parameter new_arch_enabled: whether the new arch is enabled or not +# @parameter codegen_output_dir: the directory where the code is generated +def setup_fabric!(prefix) + pod 'React-Fabric', :path => "#{prefix}/ReactCommon" + pod 'React-rncore', :path => "#{prefix}/ReactCommon" + pod 'React-graphics', :path => "#{prefix}/ReactCommon/react/renderer/graphics" + pod 'React-jsi/Fabric', :path => "#{prefix}/ReactCommon/jsi" + pod 'React-RCTFabric', :path => "#{prefix}/React", :modular_headers => true + pod 'RCT-Folly/Fabric', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec" +end diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 8ef86424cf4457..d17d089df14b70 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -6,6 +6,8 @@ require 'pathname' require_relative './react_native_pods_utils/script_phases.rb' require_relative './cocoapods/flipper.rb' +require_relative './cocoapods/fabric.rb' +require_relative './cocoapods/codegen.rb' $CODEGEN_OUTPUT_DIR = 'build/generated/ios' $CODEGEN_COMPONENT_DIR = 'react/renderer/components' @@ -22,6 +24,9 @@ def use_react_native! (options={}) # Include Fabric dependencies fabric_enabled = options[:fabric_enabled] ||= false + # New arch enabled + new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1' + # Include DevSupport dependency production = options[:production] ||= false @@ -73,7 +78,7 @@ def use_react_native! (options={}) pod 'boost', :podspec => "#{prefix}/third-party-podspecs/boost.podspec" pod 'RCT-Folly', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec", :modular_headers => true - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' + if new_arch_enabled app_path = options[:app_path] config_file_dir = options[:config_file_dir] use_react_native_codegen_discovery!({ @@ -92,13 +97,8 @@ def use_react_native! (options={}) pod 'React-Codegen', :path => $CODEGEN_OUTPUT_DIR, :modular_headers => true if fabric_enabled - checkAndGenerateEmptyThirdPartyProvider!(prefix) - pod 'React-Fabric', :path => "#{prefix}/ReactCommon" - pod 'React-rncore', :path => "#{prefix}/ReactCommon" - pod 'React-graphics', :path => "#{prefix}/ReactCommon/react/renderer/graphics" - pod 'React-jsi/Fabric', :path => "#{prefix}/ReactCommon/jsi" - pod 'React-RCTFabric', :path => "#{prefix}/React", :modular_headers => true - pod 'RCT-Folly/Fabric', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec" + checkAndGenerateEmptyThirdPartyProvider!(prefix, new_arch_enabled, $CODEGEN_OUTPUT_DIR) + setup_fabric!(prefix) end if hermes_enabled @@ -248,59 +248,6 @@ def modify_flags_for_new_architecture(installer, cpp_flags) end end -def build_codegen!(react_native_path) - relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) - codegen_repo_path = "#{relative_installation_root}/#{react_native_path}/packages/react-native-codegen"; - codegen_npm_path = "#{relative_installation_root}/#{react_native_path}/../react-native-codegen"; - codegen_cli_path = "" - if Dir.exist?(codegen_repo_path) - codegen_cli_path = codegen_repo_path - elsif Dir.exist?(codegen_npm_path) - codegen_cli_path = codegen_npm_path - else - raise "[codegen] Couldn't not find react-native-codegen." - end - - if !Dir.exist?("#{codegen_cli_path}/lib") - Pod::UI.puts "[Codegen] building #{codegen_cli_path}." - system("#{codegen_cli_path}/scripts/oss/build.sh") - end -end - -# This is a temporary supporting function until we enable use_react_native_codegen_discovery by default. -def checkAndGenerateEmptyThirdPartyProvider!(react_native_path) - return if ENV['RCT_NEW_ARCH_ENABLED'] == '1' - - relative_installation_root = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd) - output_dir = "#{relative_installation_root}/#{$CODEGEN_OUTPUT_DIR}" - - provider_h_path = "#{output_dir}/RCTThirdPartyFabricComponentsProvider.h" - provider_cpp_path ="#{output_dir}/RCTThirdPartyFabricComponentsProvider.cpp" - - if(!File.exist?(provider_h_path) || !File.exist?(provider_cpp_path)) - # build codegen - build_codegen!(react_native_path) - - # Just use a temp empty schema list. - temp_schema_list_path = "#{output_dir}/tmpSchemaList.txt" - File.open(temp_schema_list_path, 'w') do |f| - f.write('[]') - f.fsync - end - - Pod::UI.puts '[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider' - Pod::Executable.execute_command( - 'node', - [ - "#{relative_installation_root}/#{react_native_path}/scripts/generate-provider-cli.js", - "--platform", 'ios', - "--schemaListPath", temp_schema_list_path, - "--outputDir", "#{output_dir}" - ]) - File.delete(temp_schema_list_path) if File.exist?(temp_schema_list_path) - end -end - def get_react_codegen_spec(options={}) fabric_enabled = options[:fabric_enabled] ||= false script_phases = options[:script_phases] ||= nil