From d0a2c02c6bcdb1d5892ea2d5332acbdab412342d Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Tue, 11 Feb 2025 19:09:05 -0800 Subject: [PATCH] Generate a correct `.flutter-plugin-dependencies` file for iOS/macOS projects (#162834) Closes https://github.com/flutter/flutter/issues/162704. /cc @loic-sharma. I expect I'll have to update some iOS/macOS unit and possibly integration tests due to this change, but wanted something concrete to talk about during our 1:1. Feel free to leave comments or questions even if this PR is in "draft". --- .../tasks/build_ios_framework_module_test.dart | 5 +++++ dev/devicelab/bin/tasks/module_test_ios.dart | 5 +++++ .../lib/src/commands/build_aar.dart | 2 +- .../lib/src/commands/build_ios_framework.dart | 16 ++++++++++++++++ .../lib/src/commands/build_macos_framework.dart | 15 +++++++++++++++ .../lib/src/macos/cocoapod_utils.dart | 10 +++++++++- .../lib/src/runner/flutter_command.dart | 4 ++-- 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart index 09a9423959..8fe120d747 100644 --- a/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart +++ b/dev/devicelab/bin/tasks/build_ios_framework_module_test.dart @@ -13,6 +13,11 @@ import 'package:path/path.dart' as path; /// Tests that iOS and macOS .xcframeworks can be built. Future main() async { await task(() async { + // TODO(matanlurey): Remove after default. + // https://github.com/flutter/flutter/issues/160257 + section('Opt-in to --explicit-package-dependencies'); + await flutter('config', options: ['--explicit-package-dependencies']); + section('Create module project'); final Directory tempDir = Directory.systemTemp.createTempSync('flutter_module_test.'); diff --git a/dev/devicelab/bin/tasks/module_test_ios.dart b/dev/devicelab/bin/tasks/module_test_ios.dart index db70d0833a..d26643ffb1 100644 --- a/dev/devicelab/bin/tasks/module_test_ios.dart +++ b/dev/devicelab/bin/tasks/module_test_ios.dart @@ -18,6 +18,11 @@ import 'package:path/path.dart' as path; /// adding Flutter to an existing iOS app. Future main() async { await task(() async { + // TODO(matanlurey): Remove after default. + // https://github.com/flutter/flutter/issues/160257 + section('Opt-in to --explicit-package-dependencies'); + await flutter('config', options: ['--explicit-package-dependencies']); + // Update pod repo. await eval( 'pod', diff --git a/packages/flutter_tools/lib/src/commands/build_aar.dart b/packages/flutter_tools/lib/src/commands/build_aar.dart index 9174c1f5e7..b0184338c2 100644 --- a/packages/flutter_tools/lib/src/commands/build_aar.dart +++ b/packages/flutter_tools/lib/src/commands/build_aar.dart @@ -112,7 +112,7 @@ class BuildAarCommand extends BuildSubCommand { } @override - bool get regeneratePlatformSpecificToolingDurifyVerify => false; + bool get regeneratePlatformSpecificToolingDuringVerify => false; @override Future runCommand() async { diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart index 647f701f63..924e49f527 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart @@ -238,6 +238,9 @@ class BuildIOSFrameworkCommand extends BuildFrameworkCommand { } } + @override + bool get regeneratePlatformSpecificToolingDuringVerify => false; + @override Future runCommand() async { final String outputArgument = @@ -258,10 +261,23 @@ class BuildIOSFrameworkCommand extends BuildFrameworkCommand { final List buildInfos = await getBuildInfos(); displayNullSafetyMode(buildInfos.first); for (final BuildInfo buildInfo in buildInfos) { + // Create the build-mode specific metadata. + // + // This normally would be done in the verifyAndRun step of FlutterCommand, but special "meta" + // build commands (like flutter build ios-framework) make multiple builds, and do not have a + // single "buildInfo", so the step has to be done manually for each build. + // + // See regeneratePlatformSpecificToolingDurifyVerify. + await regeneratePlatformSpecificToolingIfApplicable( + project, + releaseMode: buildInfo.mode.isRelease, + ); + final String? productBundleIdentifier = await project.ios.productBundleIdentifier(buildInfo); globals.printStatus( 'Building frameworks for $productBundleIdentifier in ${buildInfo.mode.cliName} mode...', ); + final String xcodeBuildConfiguration = sentenceCase(buildInfo.mode.cliName); final Directory modeDirectory = outputDirectory.childDirectory(xcodeBuildConfiguration); diff --git a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart index cc0dc04b68..e94a70fad4 100644 --- a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart @@ -50,6 +50,9 @@ class BuildMacOSFrameworkCommand extends BuildFrameworkCommand { DevelopmentArtifact.macOS, }; + @override + bool get regeneratePlatformSpecificToolingDuringVerify => false; + @override Future runCommand() async { final String outputArgument = @@ -73,6 +76,18 @@ class BuildMacOSFrameworkCommand extends BuildFrameworkCommand { for (final BuildInfo buildInfo in buildInfos) { globals.printStatus('Building macOS frameworks in ${buildInfo.mode.cliName} mode...'); + // Create the build-mode specific metadata. + // + // This normally would be done in the verifyAndRun step of FlutterCommand, but special "meta" + // build commands (like flutter build ios-framework) make multiple builds, and do not have a + // single "buildInfo", so the step has to be done manually for each build. + // + // See regeneratePlatformSpecificToolingDurifyVerify. + await regeneratePlatformSpecificToolingIfApplicable( + project, + releaseMode: buildInfo.mode.isRelease, + ); + final String xcodeBuildConfiguration = sentenceCase(buildInfo.mode.cliName); final Directory modeDirectory = outputDirectory.childDirectory(xcodeBuildConfiguration); diff --git a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart index 2547245958..5a03c3379c 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart @@ -5,6 +5,7 @@ import '../base/fingerprint.dart'; import '../build_info.dart'; import '../cache.dart'; +import '../features.dart'; import '../flutter_plugins.dart'; import '../globals.dart' as globals; import '../plugins.dart'; @@ -34,12 +35,19 @@ Future processPodsIfNeeded( iosPlatform: project.ios.existsSync(), macOSPlatform: project.macos.existsSync(), forceCocoaPodsOnly: forceCocoaPodsOnly, + + // TODO(matanlurey): Ideally processPodsIfNeeded would not be used at all, and it would definitely + // not call refreshPluginsList, but until that happens (https://github.com/flutter/flutter/issues/157391) + // we have to reproduce some of the work that otherwise would be handled by underlying commands, otherwise + // this call to refreshPluginsList would overwrite the correct plugins list generated elsewhere. + determineDevDependencies: + featureFlags.isExplicitPackageDependenciesEnabled && buildMode.isRelease, + // TODO(matanlurey): As-per discussion on https://github.com/flutter/flutter/pull/157393 // we'll assume that iOS/MacOS builds do not use or rely on the `.flutter-plugins` legacy // file being generated. A better long-term fix would be not to have a call to refreshPluginsList // at all, and instead have it implicitly run by the FlutterCommand instead. See // https://github.com/flutter/flutter/issues/157391 for details. - determineDevDependencies: false, generateLegacyPlugins: false, ); diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 3497b21c1b..1d67049488 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1885,7 +1885,7 @@ Run 'flutter -h' (or 'flutter -h') for available flutter commands and } } - if (regeneratePlatformSpecificToolingDurifyVerify) { + if (regeneratePlatformSpecificToolingDuringVerify) { await regeneratePlatformSpecificToolingIfApplicable(project); } @@ -1904,7 +1904,7 @@ Run 'flutter -h' (or 'flutter -h') for available flutter commands and /// builds sequentially in one-go) may choose to override this and provide `false`, instead /// calling [regeneratePlatformSpecificTooling] manually when applicable. @visibleForOverriding - bool get regeneratePlatformSpecificToolingDurifyVerify => true; + bool get regeneratePlatformSpecificToolingDuringVerify => true; /// Runs [FlutterProject.regeneratePlatformSpecificTooling] for [project] with appropriate configuration. ///