Skip to content

Commit

Permalink
Stop generating the ReactCodegen.podspec in Cocoapods (#48815)
Browse files Browse the repository at this point in the history
Summary:

In an effort to reduce the responsibility of Cocoapods in React Native, we are moving the generation of the Reactcodegen podspec from Cocoapods itself to the codegen infrastructure.

This reduce the responsibility of Cocoapods and allow us to migrate away from it with more ease.

## Changelog:
[iOS][Changed] - Generate the ReactCodegen.podspec as part of codegen instead of as part of pod install.

Differential Revision: D68418268
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Jan 21, 2025
1 parent 037687d commit a13d1ad
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 626 deletions.
69 changes: 0 additions & 69 deletions packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -50,244 +50,6 @@ def teardown
DirMock.reset()
end

# ================================== #
# Test - GenerateReactCodegenPodspec #
# ================================== #

def testGenerateReactCodegenPodspec_whenItHasBeenAlreadyGenerated_doesNothing
# Arrange
spec = { :name => "Test Podspec" }
codegen_output_dir = "build"
CodegenUtils.set_react_codegen_podspec_generated(true)

# Act
CodegenUtils.new().generate_react_codegen_podspec!(spec, codegen_output_dir, file_manager: FileMock, logger: Pod::UI)

# Assert
assert_equal(Pod::UI.collected_messages, ["Skipping ReactCodegen podspec generation."])
assert_equal(Pathname.pwd_invocation_count, 0)
assert_equal(Pod::Executable.executed_commands, [])
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 0)
assert_true(CodegenUtils.react_codegen_podspec_generated)
end

def testGenerateReactCodegenPodspec_whenItHasNotBeenAlreadyGenerated_generatesIt
# Arrange
spec = { :name => "Test Podspec" }
codegen_output_dir = "build"

# Act
CodegenUtils.new().generate_react_codegen_podspec!(spec, codegen_output_dir, file_manager: FileMock, logger: Pod::UI)

# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(Pod::Executable.executed_commands, [{ "command" => 'mkdir', "arguments" => ["-p", "~/app/ios/build"]}])
assert_equal(Pod::UI.collected_messages, ["Generating ~/app/ios/build/ReactCodegen.podspec.json"])
assert_equal(FileMock.open_files_with_mode["~/app/ios/build/ReactCodegen.podspec.json"], 'w')
assert_equal(FileMock.open_files[0].collected_write, ['{"name":"Test Podspec"}'])
assert_equal(FileMock.open_files[0].fsync_invocation_count, 1)

assert_true(CodegenUtils.react_codegen_podspec_generated)
end

# ========================== #
# Test - GetReactCodegenSpec #
# ========================== #
def testGetReactCodegenSpec_whenFabricEnabledAndScriptPhases_generatesAPodspec
# Arrange
FileMock.files_to_read('package.json' => '{ "version": "99.98.97"}')

# Act
podspec = CodegenUtils.new().get_react_codegen_spec(
'package.json',
:hermes_enabled => true,
:script_phases => "echo Test Script Phase",
:file_manager => FileMock,
:logger => Pod::UI
)

# Assert
assert_equal(podspec, get_podspec_fabric_and_script_phases("echo Test Script Phase"))
assert_equal(Pod::UI.collected_messages, ["Adding script_phases to ReactCodegen."])
end

def testGetReactCodegenSpec_whenUseFrameworksAndNewArch_generatesAPodspec
# Arrange
ENV["USE_FRAMEWORKS"] = "static"
FileMock.files_to_read('package.json' => '{ "version": "99.98.97"}')

# Act
podspec = CodegenUtils.new().get_react_codegen_spec(
'package.json',

:hermes_enabled => true,
:script_phases => nil,
:file_manager => FileMock
)

# Assert
assert_equal(podspec, get_podspec_when_use_frameworks())
assert_equal(Pod::UI.collected_messages, [])
end

# =============================== #
# Test - GetCodegenConfigFromFile #
# =============================== #

def testGetCodegenConfigFromFile_whenFileDoesNotExists_returnEmpty
# Arrange

# Act
codegen = CodegenUtils.new().get_codegen_config_from_file('package.json', 'codegenConfig', file_manager: FileMock)

# Assert
assert_equal(codegen, {})
end

def testGetCodegenConfigFromFile_whenFileExistsButHasNoKey_returnEmpty
# Arrange
FileMock.mocked_existing_files(['package.json'])
FileMock.files_to_read('package.json' => '{ "codegenConfig": {}}')

# Act
codegen = CodegenUtils.new().get_codegen_config_from_file('package.json', 'codegen', file_manager: FileMock)

# Assert
assert_equal(codegen, {})
end

def testGetCodegenConfigFromFile_whenFileExistsAndHasKey_returnObject
# Arrange
FileMock.mocked_existing_files(['package.json'])
FileMock.files_to_read('package.json' => '{ "codegenConfig": {"name": "MySpec"}}')

# Act
codegen = CodegenUtils.new().get_codegen_config_from_file('package.json', 'codegenConfig', file_manager: FileMock )

# Assert
assert_equal(codegen, { "name" => "MySpec"})
end

# ======================= #
# Test - GetListOfJSSpecs #
# ======================= #
def testGetListOfJSSpecs_whenUsesLibraries_returnAListOfFiles
# Arrange
app_codegen_config = {
'libraries' => [
{
'name' => 'First Lib',
'jsSrcsDir' => './firstlib/js'
},
{
'name' => 'Second Lib',
'jsSrcsDir' => './secondlib/js'
},
]
}
app_path = "~/MyApp/"
Finder.set_files_for_paths({
'~/MyApp/./firstlib/js' => ["MyFabricComponent1NativeComponent.js", "MyFabricComponent2NativeComponent.js"],
'~/MyApp/./secondlib/js' => ["NativeModule1.js", "NativeModule2.js"],
})

# Act
files = CodegenUtils.new().get_list_of_js_specs(app_codegen_config, app_path, file_manager: FileMock)

# Assert
assert_equal(Pod::UI.collected_warns , ["[Deprecated] You are using the old `libraries` array to list all your codegen.\\nThis method will be removed in the future.\\nUpdate your `package.json` with a single object."])
assert_equal(Finder.captured_paths, ['~/MyApp/./firstlib/js', '~/MyApp/./secondlib/js'])
assert_equal(files, [
"${PODS_ROOT}/../MyFabricComponent1NativeComponent.js",
"${PODS_ROOT}/../MyFabricComponent2NativeComponent.js",
"${PODS_ROOT}/../NativeModule1.js",
"${PODS_ROOT}/../NativeModule2.js",
])
end

def testGetListOfJSSpecs_whenDoesNotUsesLibraries_returnAListOfFiles
# Arrange
app_codegen_config = {
'name' => 'First Lib',
'jsSrcsDir' => './js'
}

app_path = "~/MyApp/"
Finder.set_files_for_paths({
'~/MyApp/./js' => ["MyFabricComponent1NativeComponent.js", "NativeModule1.js"],
})

# Act
files = CodegenUtils.new().get_list_of_js_specs(app_codegen_config, app_path, file_manager: FileMock)

# Assert
assert_equal(Pod::UI.collected_warns , [])
assert_equal(Finder.captured_paths, ['~/MyApp/./js'])
assert_equal(files, [
"${PODS_ROOT}/../MyFabricComponent1NativeComponent.js",
"${PODS_ROOT}/../NativeModule1.js",
])
end

# ================================== #
# Test - GetReactCodegenScriptPhases #
# ================================== #

def testGetReactCodegenScriptPhases_whenAppPathNotDefined_abort
# Arrange

# Act
assert_raises() {
CodegenUtils.new().get_react_codegen_script_phases(nil, file_manager: FileMock, logger: Pod::UI)
}
# Assert
assert_equal(Pod::UI.collected_warns, ["error: app_path is required to use codegen discovery."])
end

def testGetReactCodegenScriptPhases_returnTheScriptObject
# Arrange
app_path = "~/MyApp"
input_files = ["${PODS_ROOT}/../MyFabricComponent1NativeComponent.js", "${PODS_ROOT}/../NativeModule1.js"]
computed_script = "echo ScriptPhases"
codegen_config = { "name" => "MyCodegenModule", "jsSrcsDir" => "./js"}
codegen_utils_mock = CodegenUtilsMock.new(:js_spec_list => input_files, :codegen_config => codegen_config)
script_phase_extractor_mock = CodegenScriptPhaseExtractorMock.new(computed_script)

# Act

scripts = CodegenUtils.new().get_react_codegen_script_phases(
app_path,
:codegen_utils => codegen_utils_mock,
:script_phase_extractor => script_phase_extractor_mock,
:file_manager => FileMock
)

# Assert
assert_equal(codegen_utils_mock.get_codegen_config_from_file_params, [{
"config_key" => "codegenConfig",
"config_path" => "~/MyApp/package.json"
}])
assert_equal(codegen_utils_mock.get_list_of_js_specs_params, [{
"app_codegen_config" => {"jsSrcsDir"=>"./js", "name"=>"MyCodegenModule"},
"app_path" => "~/MyApp"
}])
assert_equal(script_phase_extractor_mock.extract_script_phase_params, [{
fabric_enabled: false,
react_native_path: "../node_modules/react-native",
relative_app_root: "~/MyApp",
relative_config_file_dir: ""
}])
assert_equal(scripts, {
'name': 'Generate Specs',
'execution_position': :before_compile,
'input_files' => input_files,
'show_env_vars_in_log': true,
'output_files': ["${DERIVED_FILE_DIR}/react-codegen.log"],
'script': computed_script
})
end

# ================================ #
# Test - UseReactCodegenDiscovery! #
# ================================ #
Expand Down Expand Up @@ -334,57 +96,6 @@ def testUseReactCodegenDiscovery_whenAppPathUndefined_abort
])
end

def testUseReactCodegenDiscovery_whenParametersAreGood_executeCodegen
# Arrange
app_path = "~/app"
computed_script = "echo TestScript"
codegen_spec = {"name" => "ReactCodegen"}

codegen_utils_mock = CodegenUtilsMock.new(
:react_codegen_script_phases => computed_script,
:react_codegen_spec => codegen_spec
)

# Act
CodegenUtils.new().use_react_native_codegen_discovery!(
false,
app_path,
:codegen_utils => codegen_utils_mock,
:file_manager => FileMock,
:logger => Pod::UI
)

# Assert
assert_true(CodegenUtils.react_codegen_discovery_done())
assert_equal(Pod::UI.collected_warns, [
'warn: using experimental new codegen integration'
])
assert_equal(codegen_utils_mock.get_react_codegen_script_phases_params, [{
:app_path => app_path,
:config_file_dir => "",
:config_key => "codegenConfig",
:react_native_path => "../node_modules/react-native"}
])
assert_equal(codegen_utils_mock.get_react_codegen_spec_params, [{
:folly_version=>Helpers::Constants.folly_config()[:version],
:package_json_file => "#{app_path}/ios/../node_modules/react-native/package.json",
:script_phases => "echo TestScript"
}])
assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, [{
:codegen_output_dir=>"build/generated/ios",
:react_codegen_spec=>{"name"=>"ReactCodegen"}
}])
assert_equal(Pod::Executable.executed_commands, [
{
"command" => "node",
"arguments"=> ["~/app/ios/../node_modules/react-native/scripts/generate-codegen-artifacts.js",
"-p", "~/app",
"-o", Pod::Config.instance.installation_root,
"-t", "ios"]
}
])
end

# ============================= #
# Test - CleanUpCodegenFolder #
# ============================= #
Expand Down
Loading

0 comments on commit a13d1ad

Please sign in to comment.