diff --git a/packages/cli-platform-ios/CHANGELOG.md b/packages/cli-platform-ios/CHANGELOG.md index 7faf26d76..c57e68481 100644 --- a/packages/cli-platform-ios/CHANGELOG.md +++ b/packages/cli-platform-ios/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# 15.0.0-alpha.1 (2024-03-15) + +feat: added autolinking.rb, which breaks up use_native_modules! into list_native_modules!, and link_native_modules! (which lives in react-native). + # 8.0.0-alpha.3 (2022-04-22) **Note:** Version bump only for package @react-native-community/cli-platform-ios diff --git a/packages/cli-platform-ios/autolinking.rb b/packages/cli-platform-ios/autolinking.rb new file mode 100644 index 000000000..735d669f4 --- /dev/null +++ b/packages/cli-platform-ios/autolinking.rb @@ -0,0 +1,98 @@ +# This is a function which is used inside your Podfile. +# +# This is a function which is used inside your Podfile. It is deeply coupled to the Community Config. +# init_native_modules! in @react-native/core-cli-utils/autolinking/ios/native_modules.rb#link_native_modules + +require 'pathname' +require 'cocoapods' + +# Including this as it bring in the *legacy* use_native_modules!, but we should remove this +# require once the deprecation is complete. +require_relative './native_modules.rb' + +require Pod::Executable.execute_command('node', ['-p', + 'require.resolve( + "react-native/scripts/react_native_pods.rb", + {paths: [process.argv[1]]}, + )', __dir__]).strip + + +def list_native_modules!() + cli_bin = Pod::Executable.execute_command("node", ["-p", "require('@react-native-community/cli').bin"], true).strip + + json = [] + + IO.popen(["node", cli_bin, "config"]) do |data| + while line = data.gets + json << line + end + end + + config = JSON.parse(json.join("\n")) + + project_root = Pathname.new(config["project"]["ios"]["sourceDir"]) + + packages = config["dependencies"] + found_pods = [] + + packages.each do |package_name, package| + next unless package_config = package["platforms"]["ios"] + + podspec_path = package_config["podspecPath"] + configurations = package_config["configurations"] + + # Add a warning to the queue and continue to the next dependency if the podspec_path is nil/empty + if podspec_path.nil? || podspec_path.empty? + Pod::UI.warn("list_native_modules! skipped the react-native dependency '#{package["name"]}'. No podspec file was found.", + [ + "Check to see if there is an updated version that contains the necessary podspec file", + "Contact the library maintainers or send them a PR to add a podspec. The react-native-webview podspec is a good example of a package.json driven podspec. See https://github.com/react-native-community/react-native-webview/blob/master/react-native-webview.podspec", + "If necessary, you can disable autolinking for the dependency and link it manually. See https://github.com/react-native-community/cli/blob/main/docs/autolinking.md#how-can-i-disable-autolinking-for-unsupported-library" + ]) + end + next if podspec_path.nil? || podspec_path.empty? + + spec = Pod::Specification.from_file(podspec_path) + + # Skip pods that do not support the platform of the current target. + if platform = current_target_definition.platform + next unless spec.supported_on_platform?(platform.name) + else + # TODO: In a future RN version we should update the Podfile template and + # enable this assertion. + # + # raise Pod::Informative, "Cannot invoke `!` before defining the supported `platform`" + end + + podspec_dir_path = Pathname.new(File.dirname(podspec_path)) + + relative_path = podspec_dir_path.relative_path_from project_root + + # pod spec.name, :path => relative_path.to_path, :configurations => configurations + + found_pods.push({ + "name": name, + "path": relative_path.to_path, + "configurations": configurations + }) + end + + if found_pods.size > 0 + pods = found_pods.map { |p| p.name }.sort.to_sentence + Pod::UI.puts "Found #{found_pods.size} #{"module".pluralize(found_pods.size)} for target `#{current_target_definition.name}`" + end + + absolute_react_native_path = Pathname.new(config["reactNativePath"]) + + { + "ios_packages": found_pods, + "project_root_path": project_root.to_s, + "react_native_path": absolute_react_native_path.relative_path_from(project_root).to_s + } +end + +# You should be using this instead of use_native_modules, which is deprecated. +def autolink_native_modules!() + link_native_modules! list_native_modules!() +end + diff --git a/packages/cli-platform-ios/native_modules.rb b/packages/cli-platform-ios/native_modules.rb index 82f537c9f..4020c12ee 100644 --- a/packages/cli-platform-ios/native_modules.rb +++ b/packages/cli-platform-ios/native_modules.rb @@ -12,6 +12,11 @@ require 'pathname' require 'cocoapods' +VERSIONS = { + :warn => Pod::Version.create("0.75"), + :deprecated => Pod::Version.create("0.76"), +} + def use_native_modules!(config = nil) if (config.is_a? String) Pod::UI.warn("Passing custom root to use_native_modules! is deprecated.", @@ -37,6 +42,20 @@ def use_native_modules!(config = nil) config = JSON.parse(json.join("\n")) end + version = Pod::Version.new(config["reactNativeVersion"]) + if version >= VERSIONS.deprecated + Pod::UI.warn("use_native_modules! is deprecated since #{VERSIONS.deprecated}", [ + "Please consult the React Native Upgrade Helper to upgrade your iOS Podfile:", + "https://react-native-community.github.io/upgrade-helper/?from=#{version}#RnDiffApp-ios-Podfile" + ]) + abort "use_native_modules! is depreacted" + elsif version >= VERSIONS.warn + Pod::UI.warn("use_native_modules! is going to be deprecated in #{VERSIONS.deprecated}", [ + "Please consult the React Native Upgrade Helper to upgrade your iOS Podfile:", + "https://react-native-community.github.io/upgrade-helper/?from=#{version}#RnDiffApp-ios-Podfile" + ]) + end + project_root = Pathname.new(config["project"]["ios"]["sourceDir"]) packages = config["dependencies"] diff --git a/packages/cli-platform-ios/package.json b/packages/cli-platform-ios/package.json index 59c6ffc9c..fe40c776c 100644 --- a/packages/cli-platform-ios/package.json +++ b/packages/cli-platform-ios/package.json @@ -7,12 +7,17 @@ "access": "public" }, "dependencies": { - "@react-native-community/cli-platform-apple": "14.0.0-alpha.0" + "@react-native-community/cli-platform-apple": "14.0.0-alpha.0", + "@react-native/core-cli-utils": "nightly" + }, + "peerDependencies": { + "react-native": ">= 0.75" }, "files": [ "build", "!*.d.ts", "!*.map", + "autolinking.rb", "native_modules.rb" ], "homepage": "https://github.com/react-native-community/cli/tree/main/packages/cli-platform-ios", diff --git a/packages/cli-types/src/autolinking.ts b/packages/cli-types/src/autolinking.ts new file mode 100644 index 000000000..1a3370c85 --- /dev/null +++ b/packages/cli-types/src/autolinking.ts @@ -0,0 +1,10 @@ +export interface CocoaPodDescription { + name: string; + relativePath: string; + configurations: string[]; +} + +export interface ListModules { + reactNativePath: string; + pods: CocoaPodDescription[]; +} diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index eac915f4c..38bc27b25 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -11,6 +11,7 @@ import { AndroidDependencyConfig, AndroidDependencyParams, } from './android'; +export type {CocoaPodDescription, ListModules} from './autolinking'; export type Prompt = any;