From 003135e2d0e09f5986e601d116fa16f08a9abcf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= <737941+loic-sharma@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:01:26 -0800 Subject: [PATCH] [SwiftPM] Update .flutter-plugin-dependencies format (#158138) In the future, it will be possible for Swift Package Manager to be enabled on one but not all platforms (see https://github.com/flutter/flutter/issues/151567#issuecomment-2455941279). This updates the `.flutter-plugin-dependencies` file format to separate iOS's and macOS's SwiftPM enablement. For now, these platforms will always have the same value. This `.flutter-plugin-dependencies` file is read by our CocoaPods scripts to determine whether we should use CocoaPods or not to inject plugins. Part of https://github.com/flutter/flutter/issues/151567 --- .../bin/tasks/plugin_dependencies_test.dart | 14 +++++++++- packages/flutter_tools/bin/podhelper.rb | 8 ++++-- .../lib/src/flutter_plugins.dart | 13 +++++++-- .../test/general.shard/plugins_test.dart | 28 +++++++++++++++++-- .../swift_package_manager_test.dart | 18 ++++++------ 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/dev/devicelab/bin/tasks/plugin_dependencies_test.dart b/dev/devicelab/bin/tasks/plugin_dependencies_test.dart index baae2f6bf63..e0f6178c9f0 100644 --- a/dev/devicelab/bin/tasks/plugin_dependencies_test.dart +++ b/dev/devicelab/bin/tasks/plugin_dependencies_test.dart @@ -210,7 +210,7 @@ public class DummyPluginAClass { final String flutterPluginsDependenciesFileContent = flutterPluginsDependenciesFile.readAsStringSync(); final Map jsonContent = json.decode(flutterPluginsDependenciesFileContent) as Map; - final bool swiftPackageManagerEnabled = jsonContent['swift_package_manager_enabled'] as bool? ?? false; + final Map? swiftPackageManagerJson = jsonContent['swift_package_manager_enabled'] as Map?; // Verify the dependencyGraph object is valid. The rest of the contents of this file are not relevant to the // dependency graph and are tested by unit tests. @@ -304,6 +304,18 @@ public class DummyPluginAClass { return TaskResult.failure('Failed to build plugin A example iOS app'); } + final bool? swiftPackageManagerEnabled = swiftPackageManagerJson?['ios'] as bool?; + if (swiftPackageManagerEnabled == null) { + return TaskResult.failure( + '${flutterPluginsDependenciesFile.path} is missing the ' + '"swift_package_manager_enabled" > "ios" property.\n' + '\n' + '.flutter_plugin_dependencies content:\n' + '\n' + '$flutterPluginsDependenciesFileContent', + ); + } + if (swiftPackageManagerEnabled) { // Check plugins are built statically if using SwiftPM. final String executable = path.join(appBundle.path, 'Runner'); diff --git a/packages/flutter_tools/bin/podhelper.rb b/packages/flutter_tools/bin/podhelper.rb index 64e163ea85d..008dc64fe7b 100644 --- a/packages/flutter_tools/bin/podhelper.rb +++ b/packages/flutter_tools/bin/podhelper.rb @@ -304,7 +304,7 @@ def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, pl plugins_file = File.join(application_path, '..', '.flutter-plugins-dependencies') dependencies_hash = flutter_parse_plugins_file(plugins_file) plugin_pods = flutter_get_plugins_list(dependencies_hash, platform) - swift_package_manager_enabled = flutter_get_swift_package_manager_enabled(dependencies_hash) + swift_package_manager_enabled = flutter_get_swift_package_manager_enabled(dependencies_hash, platform) plugin_pods.each do |plugin_hash| plugin_name = plugin_hash['name'] @@ -353,10 +353,12 @@ def flutter_get_plugins_list(dependencies_hash, platform) dependencies_hash['plugins'][platform] || [] end -def flutter_get_swift_package_manager_enabled(dependencies_hash) +def flutter_get_swift_package_manager_enabled(dependencies_hash, platform) return false unless dependencies_hash.any? return false unless dependencies_hash.has_key?('swift_package_manager_enabled') - dependencies_hash['swift_package_manager_enabled'] == true + return false unless dependencies_hash['swift_package_manager_enabled'].has_key?(platform) + + dependencies_hash['swift_package_manager_enabled'][platform] == true end def flutter_relative_path_from_podfile(path) diff --git a/packages/flutter_tools/lib/src/flutter_plugins.dart b/packages/flutter_tools/lib/src/flutter_plugins.dart index f19d2450f1a..e815d750620 100644 --- a/packages/flutter_tools/lib/src/flutter_plugins.dart +++ b/packages/flutter_tools/lib/src/flutter_plugins.dart @@ -214,7 +214,8 @@ const String _kFlutterPluginsSharedDarwinSource = 'shared_darwin_source'; bool _writeFlutterPluginsList( FlutterProject project, List plugins, { - bool forceCocoaPodsOnly = false, + required bool swiftPackageManagerEnabledIos, + required bool swiftPackageManagerEnabledMacos, }) { final File pluginsFile = project.flutterPluginsDependenciesFile; if (plugins.isEmpty) { @@ -250,7 +251,11 @@ bool _writeFlutterPluginsList( result['dependencyGraph'] = _createPluginLegacyDependencyGraph(plugins); result['date_created'] = globals.systemClock.now().toString(); result['version'] = globals.flutterVersion.frameworkVersion; - result['swift_package_manager_enabled'] = !forceCocoaPodsOnly && project.usesSwiftPackageManager; + + result['swift_package_manager_enabled'] = { + 'ios': swiftPackageManagerEnabledIos, + 'macos': swiftPackageManagerEnabledMacos, + }; // Only notify if the plugins list has changed. [date_created] will always be different, // [version] is not relevant for this check. @@ -1065,10 +1070,12 @@ Future refreshPluginsList( // Write the legacy plugin files to avoid breaking existing apps. final bool legacyChanged = useImplicitPubspecResolution && _writeFlutterPluginsListLegacy(project, plugins); + final bool swiftPackageManagerEnabled = !forceCocoaPodsOnly && project.usesSwiftPackageManager; final bool changed = _writeFlutterPluginsList( project, plugins, - forceCocoaPodsOnly: forceCocoaPodsOnly, + swiftPackageManagerEnabledIos: swiftPackageManagerEnabled, + swiftPackageManagerEnabledMacos: swiftPackageManagerEnabled, ); if (changed || legacyChanged || forceCocoaPodsOnly) { createPluginSymlinks(project, force: true); diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart index cc3a29ddd60..6051e967bd8 100644 --- a/packages/flutter_tools/test/general.shard/plugins_test.dart +++ b/packages/flutter_tools/test/general.shard/plugins_test.dart @@ -548,7 +548,15 @@ dependencies: expect(jsonContent['dependencyGraph'], expectedDependencyGraph); expect(jsonContent['date_created'], dateCreated.toString()); expect(jsonContent['version'], '1.0.0'); - expect(jsonContent['swift_package_manager_enabled'], false); + + final Map expectedSwiftPackageManagerEnabled = { + 'ios': false, + 'macos': false, + }; + expect( + jsonContent['swift_package_manager_enabled'], + expectedSwiftPackageManagerEnabled, + ); // Make sure tests are updated if a new object is added/removed. final List expectedKeys = [ @@ -665,7 +673,14 @@ dependencies: .readAsStringSync(); final Map jsonContent = json.decode(pluginsString) as Map; - expect(jsonContent['swift_package_manager_enabled'], true); + final Map expectedSwiftPackageManagerEnabled = { + 'ios': true, + 'macos': true, + }; + expect( + jsonContent['swift_package_manager_enabled'], + expectedSwiftPackageManagerEnabled, + ); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), @@ -702,7 +717,14 @@ dependencies: .readAsStringSync(); final Map jsonContent = json.decode(pluginsString) as Map; - expect(jsonContent['swift_package_manager_enabled'], false); + final Map expectedSwiftPackageManagerEnabled = { + 'ios': false, + 'macos': false, + }; + expect( + jsonContent['swift_package_manager_enabled'], + expectedSwiftPackageManagerEnabled, + ); }, overrides: { FileSystem: () => fs, ProcessManager: () => FakeProcessManager.any(), diff --git a/packages/flutter_tools/test/integration.shard/swift_package_manager_test.dart b/packages/flutter_tools/test/integration.shard/swift_package_manager_test.dart index a07ed3e64f3..dcc7f09df16 100644 --- a/packages/flutter_tools/test/integration.shard/swift_package_manager_test.dart +++ b/packages/flutter_tools/test/integration.shard/swift_package_manager_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; + import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/base/error_handling_io.dart'; import 'package:flutter_tools/src/base/file_system.dart'; @@ -553,14 +555,14 @@ void main() { .childFile('.flutter-plugins-dependencies'); expect(flutterPluginsDependenciesFile, exists); - expect( - flutterPluginsDependenciesFile.readAsStringSync(), - isNot(contains('"swift_package_manager_enabled":true')), - ); - expect( - flutterPluginsDependenciesFile.readAsStringSync(), - contains('"swift_package_manager_enabled":false'), - ); + + final String dependenciesString = flutterPluginsDependenciesFile.readAsStringSync(); + final Map? dependenciesJson = json.decode(dependenciesString) as Map?; + final Map? swiftPackageManagerEnabled = + dependenciesJson?['swift_package_manager_enabled'] as Map?; + final bool? swiftPackageManagerEnabledIos = swiftPackageManagerEnabled?['ios'] as bool?; + + expect(swiftPackageManagerEnabledIos, isFalse); }, skip: !platform.isMacOS); // [intended] Swift Package Manager only works on macos. test("Generated Swift package uses iOS's project minimum deployment", () async {