Convert ProjectMigration and ProjectMigrator to be async (#146537)

Convert `ProjectMigration.run()` and `ProjectMigrator.migrate()` to be async.

Needed for Swift Package Manager migration, which requires some async processes: https://github.com/flutter/flutter/pull/146256
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 78fb5d9..713173a 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -316,7 +316,7 @@
     ];
 
     final ProjectMigration migration = ProjectMigration(migrators);
-    migration.run();
+    await migration.run();
 
     final bool usesAndroidX = isAppUsingAndroidX(project.android.hostAppGradleRoot);
     if (usesAndroidX) {
diff --git a/packages/flutter_tools/lib/src/android/migrations/android_studio_java_gradle_conflict_migration.dart b/packages/flutter_tools/lib/src/android/migrations/android_studio_java_gradle_conflict_migration.dart
index b8d4888..d1bae08 100644
--- a/packages/flutter_tools/lib/src/android/migrations/android_studio_java_gradle_conflict_migration.dart
+++ b/packages/flutter_tools/lib/src/android/migrations/android_studio_java_gradle_conflict_migration.dart
@@ -84,7 +84,7 @@
   final Java? _java;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     try {
       if (!_gradleWrapperPropertiesFile.existsSync()) {
         logger.printTrace(gradleWrapperNotFound);
diff --git a/packages/flutter_tools/lib/src/android/migrations/min_sdk_version_migration.dart b/packages/flutter_tools/lib/src/android/migrations/min_sdk_version_migration.dart
index c890ebd..9473193 100644
--- a/packages/flutter_tools/lib/src/android/migrations/min_sdk_version_migration.dart
+++ b/packages/flutter_tools/lib/src/android/migrations/min_sdk_version_migration.dart
@@ -27,7 +27,7 @@
   final AndroidProject _project;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     // Skip applying migration in modules as the FlutterExtension is not applied.
     if (_project.isModule) {
       return;
diff --git a/packages/flutter_tools/lib/src/android/migrations/top_level_gradle_build_file_migration.dart b/packages/flutter_tools/lib/src/android/migrations/top_level_gradle_build_file_migration.dart
index 71b54b6..fa85aa1 100644
--- a/packages/flutter_tools/lib/src/android/migrations/top_level_gradle_build_file_migration.dart
+++ b/packages/flutter_tools/lib/src/android/migrations/top_level_gradle_build_file_migration.dart
@@ -28,7 +28,7 @@
   final File _topLevelGradleBuildFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_topLevelGradleBuildFile.existsSync()) {
       logger.printTrace('Top-level Gradle build file not found, skipping migration of task "clean".');
       return;
diff --git a/packages/flutter_tools/lib/src/base/project_migrator.dart b/packages/flutter_tools/lib/src/base/project_migrator.dart
index f133de4..ea3cd2c 100644
--- a/packages/flutter_tools/lib/src/base/project_migrator.dart
+++ b/packages/flutter_tools/lib/src/base/project_migrator.dart
@@ -16,7 +16,7 @@
   @protected
   final Logger logger;
 
-  void migrate();
+  Future<void> migrate();
 
   /// Return null if the line should be deleted.
   @protected
@@ -79,9 +79,9 @@
 
   final List<ProjectMigrator> migrators;
 
-  void run() {
+  Future<void> run() async {
     for (final ProjectMigrator migrator in migrators) {
-      migrator.migrate();
+      await migrator.migrate();
     }
   }
 }
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 9da2f15..454e4dc 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -161,7 +161,7 @@
   ];
 
   final ProjectMigration migration = ProjectMigration(migrators);
-  migration.run();
+  await migration.run();
 
   if (!_checkXcodeVersion()) {
     return XcodeBuildResult(success: false);
diff --git a/packages/flutter_tools/lib/src/ios/migrations/host_app_info_plist_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/host_app_info_plist_migration.dart
index 53f22e9..f544f6f 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/host_app_info_plist_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/host_app_info_plist_migration.dart
@@ -19,7 +19,7 @@
   final File _infoPlist;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_infoPlist.existsSync()) {
       logger.printTrace('Info.plist not found, skipping host app Info.plist migration.');
       return;
diff --git a/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart
index 3f1a423..e1a8638 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart
@@ -20,7 +20,7 @@
   final File _appFrameworkInfoPlist;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (_xcodeProjectInfoFile.existsSync()) {
       processFileLines(_xcodeProjectInfoFile);
     } else {
diff --git a/packages/flutter_tools/lib/src/ios/migrations/project_base_configuration_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/project_base_configuration_migration.dart
index 4f688b1..ecbd5cd 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/project_base_configuration_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/project_base_configuration_migration.dart
@@ -16,7 +16,7 @@
   final File _xcodeProjectInfoFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectInfoFile.existsSync()) {
       logger.printTrace('Xcode project not found, skipping Runner project build settings and configuration migration');
       return;
diff --git a/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart
index 80e14d2..adeaa97 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/project_build_location_migration.dart
@@ -16,7 +16,7 @@
   final File _xcodeProjectWorkspaceData;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectWorkspaceData.existsSync()) {
       logger.printTrace('Xcode project workspace data not found, skipping build location migration.');
       return;
diff --git a/packages/flutter_tools/lib/src/ios/migrations/remove_bitcode_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/remove_bitcode_migration.dart
index 4042113..23b157a 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/remove_bitcode_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/remove_bitcode_migration.dart
@@ -16,7 +16,7 @@
   final File _xcodeProjectInfoFile;
 
   @override
-  bool migrate() {
+  Future<bool> migrate() async {
     if (_xcodeProjectInfoFile.existsSync()) {
       processFileLines(_xcodeProjectInfoFile);
     } else {
diff --git a/packages/flutter_tools/lib/src/ios/migrations/remove_framework_link_and_embedding_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/remove_framework_link_and_embedding_migration.dart
index a64644d..28e004f 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/remove_framework_link_and_embedding_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/remove_framework_link_and_embedding_migration.dart
@@ -28,7 +28,7 @@
   final Analytics _analytics;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectInfoFile.existsSync()) {
       logger.printTrace('Xcode project not found, skipping framework link and embedding migration');
       return;
diff --git a/packages/flutter_tools/lib/src/ios/migrations/xcode_build_system_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/xcode_build_system_migration.dart
index 6a3d909..b2a11c7 100644
--- a/packages/flutter_tools/lib/src/ios/migrations/xcode_build_system_migration.dart
+++ b/packages/flutter_tools/lib/src/ios/migrations/xcode_build_system_migration.dart
@@ -18,7 +18,7 @@
   final File? _xcodeWorkspaceSharedSettings;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     final File? xcodeWorkspaceSharedSettings = _xcodeWorkspaceSharedSettings;
     if (xcodeWorkspaceSharedSettings == null || !xcodeWorkspaceSharedSettings.existsSync()) {
       logger.printTrace('Xcode workspace settings not found, skipping build system migration');
diff --git a/packages/flutter_tools/lib/src/linux/build_linux.dart b/packages/flutter_tools/lib/src/linux/build_linux.dart
index 1a5e886..82f6215 100644
--- a/packages/flutter_tools/lib/src/linux/build_linux.dart
+++ b/packages/flutter_tools/lib/src/linux/build_linux.dart
@@ -53,7 +53,7 @@
   ];
 
   final ProjectMigration migration = ProjectMigration(migrators);
-  migration.run();
+  await migration.run();
 
   // Build the environment that needs to be set for the re-entrant flutter build
   // step.
diff --git a/packages/flutter_tools/lib/src/macos/build_macos.dart b/packages/flutter_tools/lib/src/macos/build_macos.dart
index c206078..dbbff10 100644
--- a/packages/flutter_tools/lib/src/macos/build_macos.dart
+++ b/packages/flutter_tools/lib/src/macos/build_macos.dart
@@ -86,7 +86,7 @@
   ];
 
   final ProjectMigration migration = ProjectMigration(migrators);
-  migration.run();
+  await migration.run();
 
   final Directory flutterBuildDir = globals.fs.directory(getMacOSBuildDirectory());
   if (!flutterBuildDir.existsSync()) {
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart
index 582a96a..1c4517e 100644
--- a/packages/flutter_tools/lib/src/macos/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -185,7 +185,7 @@
           _logger,
         ),
       ]);
-      postPodMigration.run();
+      await postPodMigration.run();
 
       podsProcessed = true;
     }
diff --git a/packages/flutter_tools/lib/src/macos/migrations/flutter_application_migration.dart b/packages/flutter_tools/lib/src/macos/migrations/flutter_application_migration.dart
index 1b5d159..d21f6c7 100644
--- a/packages/flutter_tools/lib/src/macos/migrations/flutter_application_migration.dart
+++ b/packages/flutter_tools/lib/src/macos/migrations/flutter_application_migration.dart
@@ -24,7 +24,7 @@
   final File _infoPlistFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (_infoPlistFile.existsSync()) {
       final String? principalClass =
           globals.plistParser.getValueFromFile<String>(_infoPlistFile.path, PlistParser.kNSPrincipalClassKey);
diff --git a/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart b/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart
index 48b6aee..3b021c9 100644
--- a/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart
+++ b/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart
@@ -18,7 +18,7 @@
   final File _podfile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (_xcodeProjectInfoFile.existsSync()) {
       processFileLines(_xcodeProjectInfoFile);
     } else {
diff --git a/packages/flutter_tools/lib/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart b/packages/flutter_tools/lib/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart
index 1039d70..a11b3d8 100644
--- a/packages/flutter_tools/lib/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart
+++ b/packages/flutter_tools/lib/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart
@@ -26,7 +26,7 @@
   final Analytics _analytics;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectInfoFile.existsSync()) {
       logger.printTrace(
           'Xcode project not found, skipping framework link and embedding migration');
diff --git a/packages/flutter_tools/lib/src/migrations/cmake_custom_command_migration.dart b/packages/flutter_tools/lib/src/migrations/cmake_custom_command_migration.dart
index 54ddcb5..09f818b 100644
--- a/packages/flutter_tools/lib/src/migrations/cmake_custom_command_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/cmake_custom_command_migration.dart
@@ -16,7 +16,7 @@
   final File _cmakeFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_cmakeFile.existsSync()) {
       logger.printTrace('CMake project not found, skipping add_custom_command() VERBATIM migration');
       return;
diff --git a/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart b/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart
index c7f2135..3cbbe58 100644
--- a/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/cmake_native_assets_migration.dart
@@ -23,7 +23,7 @@
   final String os;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_cmakeFile.existsSync()) {
       logger.printTrace('CMake project not found, skipping install() NATIVE_ASSETS_DIR migration.');
       return;
diff --git a/packages/flutter_tools/lib/src/migrations/cocoapods_script_symlink.dart b/packages/flutter_tools/lib/src/migrations/cocoapods_script_symlink.dart
index f0d90ca..6dd6c3b 100644
--- a/packages/flutter_tools/lib/src/migrations/cocoapods_script_symlink.dart
+++ b/packages/flutter_tools/lib/src/migrations/cocoapods_script_symlink.dart
@@ -25,7 +25,7 @@
   final XcodeProjectInterpreter _xcodeProjectInterpreter;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_podRunnerFrameworksScript.existsSync()) {
       logger.printTrace('CocoaPods Pods-Runner-frameworks.sh script not found, skipping "readlink -f" workaround.');
       return;
diff --git a/packages/flutter_tools/lib/src/migrations/cocoapods_toolchain_directory_migration.dart b/packages/flutter_tools/lib/src/migrations/cocoapods_toolchain_directory_migration.dart
index 4ab406b..91e94df 100644
--- a/packages/flutter_tools/lib/src/migrations/cocoapods_toolchain_directory_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/cocoapods_toolchain_directory_migration.dart
@@ -26,7 +26,7 @@
   final XcodeProjectInterpreter _xcodeProjectInterpreter;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_podRunnerTargetSupportFiles.existsSync()) {
       logger.printTrace('CocoaPods Pods-Runner Target Support Files not found, skipping TOOLCHAIN_DIR workaround.');
       return;
diff --git a/packages/flutter_tools/lib/src/migrations/xcode_project_object_version_migration.dart b/packages/flutter_tools/lib/src/migrations/xcode_project_object_version_migration.dart
index 1b7ce63..deeab5f 100644
--- a/packages/flutter_tools/lib/src/migrations/xcode_project_object_version_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/xcode_project_object_version_migration.dart
@@ -18,7 +18,7 @@
   final File _xcodeProjectSchemeFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (_xcodeProjectInfoFile.existsSync()) {
       processFileLines(_xcodeProjectInfoFile);
     } else {
diff --git a/packages/flutter_tools/lib/src/migrations/xcode_script_build_phase_migration.dart b/packages/flutter_tools/lib/src/migrations/xcode_script_build_phase_migration.dart
index cd8b2f7..34fdb3f 100644
--- a/packages/flutter_tools/lib/src/migrations/xcode_script_build_phase_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/xcode_script_build_phase_migration.dart
@@ -15,7 +15,7 @@
   final File _xcodeProjectInfoFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectInfoFile.existsSync()) {
       logger.printTrace('Xcode project not found, skipping script build phase dependency analysis removal.');
       return;
diff --git a/packages/flutter_tools/lib/src/migrations/xcode_thin_binary_build_phase_input_paths_migration.dart b/packages/flutter_tools/lib/src/migrations/xcode_thin_binary_build_phase_input_paths_migration.dart
index 3f079a4..464d6d4 100644
--- a/packages/flutter_tools/lib/src/migrations/xcode_thin_binary_build_phase_input_paths_migration.dart
+++ b/packages/flutter_tools/lib/src/migrations/xcode_thin_binary_build_phase_input_paths_migration.dart
@@ -16,7 +16,7 @@
   final File _xcodeProjectInfoFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     if (!_xcodeProjectInfoFile.existsSync()) {
       logger.printTrace('Xcode project not found, skipping script build phase dependency analysis removal.');
       return;
diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart
index f3460215..22302d0 100644
--- a/packages/flutter_tools/lib/src/web/compile.dart
+++ b/packages/flutter_tools/lib/src/web/compile.dart
@@ -84,7 +84,7 @@
     ];
 
     final ProjectMigration migration = ProjectMigration(migrators);
-    migration.run();
+    await migration.run();
 
     final Status status = _logger.startProgress('Compiling $target for the Web...');
     final Stopwatch sw = Stopwatch()..start();
diff --git a/packages/flutter_tools/lib/src/web/migrations/scrub_generated_plugin_registrant.dart b/packages/flutter_tools/lib/src/web/migrations/scrub_generated_plugin_registrant.dart
index 6827d74..caea2bb 100644
--- a/packages/flutter_tools/lib/src/web/migrations/scrub_generated_plugin_registrant.dart
+++ b/packages/flutter_tools/lib/src/web/migrations/scrub_generated_plugin_registrant.dart
@@ -18,7 +18,7 @@
   final Logger _logger;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     final File registrant = _project.libDirectory.childFile('generated_plugin_registrant.dart');
     final File gitignore = _project.parent.directory.childFile('.gitignore');
 
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index 5072be3..91d81ac 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -73,7 +73,7 @@
   ];
 
   final ProjectMigration migration = ProjectMigration(migrators);
-  migration.run();
+  await migration.run();
 
   // Ensure that necessary ephemeral files are generated and up to date.
   _writeGeneratedFlutterConfig(windowsProject, buildInfo, target);
diff --git a/packages/flutter_tools/lib/src/windows/migrations/build_architecture_migration.dart b/packages/flutter_tools/lib/src/windows/migrations/build_architecture_migration.dart
index 442ade5..463fcd2 100644
--- a/packages/flutter_tools/lib/src/windows/migrations/build_architecture_migration.dart
+++ b/packages/flutter_tools/lib/src/windows/migrations/build_architecture_migration.dart
@@ -71,7 +71,7 @@
   final Directory _buildDirectory;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     final Directory oldRunnerDirectory = _buildDirectory
       .parent
       .childDirectory('runner');
diff --git a/packages/flutter_tools/lib/src/windows/migrations/show_window_migration.dart b/packages/flutter_tools/lib/src/windows/migrations/show_window_migration.dart
index bebb5ec..799fd56 100644
--- a/packages/flutter_tools/lib/src/windows/migrations/show_window_migration.dart
+++ b/packages/flutter_tools/lib/src/windows/migrations/show_window_migration.dart
@@ -39,7 +39,7 @@
   final File _file;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     // Skip this migration if the affected file does not exist. This indicates
     // the app has done non-trivial changes to its runner and this migration
     // might not work as expected if applied.
diff --git a/packages/flutter_tools/lib/src/windows/migrations/version_migration.dart b/packages/flutter_tools/lib/src/windows/migrations/version_migration.dart
index 733bc98..f5765e5 100644
--- a/packages/flutter_tools/lib/src/windows/migrations/version_migration.dart
+++ b/packages/flutter_tools/lib/src/windows/migrations/version_migration.dart
@@ -69,7 +69,7 @@
   final File _resourceFile;
 
   @override
-  void migrate() {
+  Future<void> migrate() async {
     // Skip this migration if the affected files do not exist. This indicates
     // the app has done non-trivial changes to its runner and this migration
     // might not work as expected if applied.
diff --git a/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart b/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
index 500b6f2..e8af1b4 100644
--- a/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_project_migration_test.dart
@@ -137,17 +137,17 @@
         topLevelGradleBuildFile = project.hostAppGradleRoot.childFile('build.gradle');
       });
 
-      testUsingContext('skipped if files are missing', () {
+      testUsingContext('skipped if files are missing', () async {
         final TopLevelGradleBuildFileMigration androidProjectMigration = TopLevelGradleBuildFileMigration(
           project,
           bufferLogger,
         );
-        androidProjectMigration.migrate();
+        await androidProjectMigration.migrate();
         expect(topLevelGradleBuildFile.existsSync(), isFalse);
         expect(bufferLogger.traceText, contains('Top-level Gradle build file not found, skipping migration of task "clean".'));
       });
 
-      testUsingContext('skipped if nothing to upgrade', () {
+      testUsingContext('skipped if nothing to upgrade', () async {
         topLevelGradleBuildFile.writeAsStringSync('''
 tasks.register("clean", Delete) {
   delete rootProject.buildDir
@@ -159,12 +159,12 @@
           bufferLogger,
         );
         final DateTime previousLastModified = topLevelGradleBuildFile.lastModifiedSync();
-        androidProjectMigration.migrate();
+        await androidProjectMigration.migrate();
 
         expect(topLevelGradleBuildFile.lastModifiedSync(), previousLastModified);
       });
 
-      testUsingContext('top-level build.gradle is migrated', () {
+      testUsingContext('top-level build.gradle is migrated', () async {
         topLevelGradleBuildFile.writeAsStringSync('''
 task clean(type: Delete) {
     delete rootProject.buildDir
@@ -175,7 +175,7 @@
           project,
           bufferLogger,
         );
-        androidProjectMigration.migrate();
+        await androidProjectMigration.migrate();
 
         expect(bufferLogger.traceText, contains('Migrating "clean" Gradle task to lazy declaration style.'));
         expect(topLevelGradleBuildFile.readAsStringSync(), equals('''
@@ -208,33 +208,33 @@
             .childFile(gradleWrapperPropertiesFilename);
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
           project: project,
           androidStudio: FakeAndroidStudio(version: androidStudioDolphin),
         );
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.existsSync(), isFalse);
         expect(bufferLogger.traceText, contains(gradleWrapperNotFound));
       });
 
 
-      testWithoutContext('skipped if android studio is null', () {
+      testWithoutContext('skipped if android studio is null', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
           project: project,
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(bufferLogger.traceText, contains(androidStudioNotFound));
         expect(gradleWrapperPropertiesFile.readAsStringSync(),
             gradleWrapperToMigrate);
       });
 
-      testWithoutContext('skipped if android studio version is null', () {
+      testWithoutContext('skipped if android studio version is null', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
@@ -242,13 +242,13 @@
           androidStudio: FakeAndroidStudio(version: null),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(bufferLogger.traceText, contains(androidStudioNotFound));
         expect(gradleWrapperPropertiesFile.readAsStringSync(),
             gradleWrapperToMigrate);
       });
 
-      testWithoutContext('skipped if error is encountered in migrate()', () {
+      testWithoutContext('skipped if error is encountered in migrate()', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeErroringJava(),
           bufferLogger,
@@ -256,13 +256,13 @@
           androidStudio: FakeAndroidStudio(version: androidStudioFlamingo),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(bufferLogger.traceText, contains(errorWhileMigrating));
         expect(gradleWrapperPropertiesFile.readAsStringSync(),
             gradleWrapperToMigrate);
       });
 
-      testWithoutContext('skipped if android studio version is less than flamingo', () {
+      testWithoutContext('skipped if android studio version is less than flamingo', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(),
           bufferLogger,
@@ -270,12 +270,12 @@
           androidStudio: FakeAndroidStudio(version: androidStudioDolphin),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.readAsStringSync(), gradleWrapperToMigrate);
         expect(bufferLogger.traceText, contains(androidStudioVersionBelowFlamingo));
       });
 
-      testWithoutContext('skipped if bundled java version is less than 17', () {
+      testWithoutContext('skipped if bundled java version is less than 17', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion16),
           bufferLogger,
@@ -283,13 +283,13 @@
           androidStudio: FakeAndroidStudio(version: androidStudioFlamingo),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.readAsStringSync(), gradleWrapperToMigrate);
         expect(bufferLogger.traceText, contains(javaVersionNot17));
       });
 
       testWithoutContext('nothing is changed if gradle version not one that was '
-          'used by flutter create', () {
+          'used by flutter create', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
@@ -297,13 +297,13 @@
           androidStudio: FakeAndroidStudio(version: androidStudioFlamingo),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(otherGradleVersionWrapper);
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.readAsStringSync(), otherGradleVersionWrapper);
         expect(bufferLogger.traceText, isEmpty);
       });
 
       testWithoutContext('change is made with one of the specific gradle versions'
-          ' we migrate for', () {
+          ' we migrate for', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
@@ -311,14 +311,14 @@
           androidStudio: FakeAndroidStudio(version: androidStudioFlamingo),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate);
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.readAsStringSync(), gradleWrapperToMigrateTo);
         expect(bufferLogger.statusText, contains('Conflict detected between '
             'Android Studio Java version and Gradle version, upgrading Gradle '
             'version from 6.7 to $gradleVersion7_6_1.'));
       });
 
-      testWithoutContext('change is not made when opt out flag is set', () {
+      testWithoutContext('change is not made when opt out flag is set', () async {
         final AndroidStudioJavaGradleConflictMigration migration = AndroidStudioJavaGradleConflictMigration(
           java: FakeJava(version: _javaVersion17),
           bufferLogger,
@@ -326,7 +326,7 @@
           androidStudio: FakeAndroidStudio(version: androidStudioFlamingo),
         );
         gradleWrapperPropertiesFile.writeAsStringSync(gradleWrapperToMigrate + optOutFlag);
-        migration.migrate();
+        await migration.migrate();
         expect(gradleWrapperPropertiesFile.readAsStringSync(), gradleWrapperToMigrate + optOutFlag);
         expect(bufferLogger.traceText, contains(optOutFlagEnabled));
       });
@@ -354,48 +354,48 @@
         );
       });
 
-      testWithoutContext('do nothing when files missing', () {
-        migration.migrate();
+      testWithoutContext('do nothing when files missing', () async {
+        await migration.migrate();
         expect(bufferLogger.traceText, contains(appGradleNotFoundWarning));
       });
 
-      testWithoutContext('replace when api 19', () {
+      testWithoutContext('replace when api 19', () async {
         const String minSdkVersion19 = 'minSdkVersion 19';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(minSdkVersion19));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(replacementMinSdkText));
       });
 
-      testWithoutContext('replace when api 20', () {
+      testWithoutContext('replace when api 20', () async {
         const String minSdkVersion20 = 'minSdkVersion 20';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(minSdkVersion20));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(replacementMinSdkText));
       });
 
-      testWithoutContext('do nothing when >=api 21', () {
+      testWithoutContext('do nothing when >=api 21', () async {
         const String minSdkVersion21 = 'minSdkVersion 21';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(minSdkVersion21));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(minSdkVersion21));
       });
 
       testWithoutContext('do nothing when already using '
-          'flutter.minSdkVersion', () {
+          'flutter.minSdkVersion', () async {
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(replacementMinSdkText));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(replacementMinSdkText));
       });
 
-      testWithoutContext('avoid rewriting comments', () {
+      testWithoutContext('avoid rewriting comments', () async {
         const String code = '// minSdkVersion 19  // old default\n'
             '        minSdkVersion 23  // new version';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(code));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(code));
       });
 
-      testWithoutContext('do nothing when project is a module', () {
+      testWithoutContext('do nothing when project is a module', () async {
         project = FakeAndroidProject(
           root: memoryFileSystem.currentDirectory.childDirectory('android'),
           module: true,
@@ -406,23 +406,23 @@
         );
         const String minSdkVersion19 = 'minSdkVersion 19';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(minSdkVersion19));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(minSdkVersion19));
       });
 
       testWithoutContext('do nothing when minSdkVersion is set '
-          'to a constant', () {
+          'to a constant', () async {
         const String minSdkVersionConstant = 'minSdkVersion kMinSdkversion';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(minSdkVersionConstant));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(minSdkVersionConstant));
       });
 
       testWithoutContext('do nothing when minSdkVersion is set '
-          'using = syntax', () {
+          'using = syntax', () async {
         const String equalsSyntaxMinSdkVersion19 = 'minSdkVersion = 19';
         project.appGradleFile.writeAsStringSync(sampleModuleGradleBuildFile(equalsSyntaxMinSdkVersion19));
-        migration.migrate();
+        await migration.migrate();
         expect(project.appGradleFile.readAsStringSync(), sampleModuleGradleBuildFile(equalsSyntaxMinSdkVersion19));
       });
     });
diff --git a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart
index cfaf978..9934ca2 100644
--- a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart
@@ -44,10 +44,10 @@
       );
     });
 
-    testWithoutContext('migrators succeed', () {
+    testWithoutContext('migrators succeed', () async {
       final FakeIOSMigrator fakeIOSMigrator = FakeIOSMigrator();
       final ProjectMigration migration = ProjectMigration(<ProjectMigrator>[fakeIOSMigrator]);
-      migration.run();
+      await migration.run();
     });
 
     group('remove framework linking and embedding migration', () {
@@ -64,14 +64,14 @@
         project.xcodeProjectInfoFile = xcodeProjectInfoFile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final RemoveFrameworkLinkAndEmbeddingMigration iosProjectMigration = RemoveFrameworkLinkAndEmbeddingMigration(
           project,
           testLogger,
           testUsage,
           fakeAnalytics,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(testUsage.events, isEmpty);
         expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -81,7 +81,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String contents = 'Nothing to upgrade';
         xcodeProjectInfoFile.writeAsStringSync(contents);
         final DateTime projectLastModified = xcodeProjectInfoFile.lastModifiedSync();
@@ -92,7 +92,7 @@
           testUsage,
           fakeAnalytics,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(testUsage.events, isEmpty);
         expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -102,7 +102,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skips migrating script with embed', () {
+      testWithoutContext('skips migrating script with embed', () async {
         const String contents = r'''
 shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
 			''';
@@ -114,12 +114,12 @@
           testUsage,
           fakeAnalytics,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectInfoFile.readAsStringSync(), contents);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated', () {
+      testWithoutContext('Xcode project is migrated', () async {
         xcodeProjectInfoFile.writeAsStringSync(r'''
 prefix 3B80C3941E831B6300D905FE
 3B80C3951E831B6300D905FE suffix
@@ -142,7 +142,7 @@
           testUsage,
           fakeAnalytics,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(testUsage.events, isEmpty);
         expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -242,33 +242,33 @@
         project.xcodeWorkspaceSharedSettings = xcodeWorkspaceSharedSettings;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Xcode workspace settings not found, skipping build system migration'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if _xcodeWorkspaceSharedSettings is null', () {
+      testWithoutContext('skipped if _xcodeWorkspaceSharedSettings is null', () async {
         final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
           project,
           testLogger,
         );
         project.xcodeWorkspaceSharedSettings = null;
 
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Xcode workspace settings not found, skipping build system migration'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String contents = '''
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -284,12 +284,12 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeWorkspaceSharedSettings.existsSync(), isTrue);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated', () {
+      testWithoutContext('Xcode project is migrated', () async {
         const String contents = '''
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -307,7 +307,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
 
         expect(testLogger.statusText, contains('Legacy build system detected, removing'));
@@ -328,19 +328,19 @@
         project.xcodeProjectWorkspaceData = xcodeProjectWorkspaceData;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectWorkspaceData.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Xcode project workspace data not found, skipping build location migration.'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String contents = '''
  <?xml version="1.0" encoding="UTF-8"?>
  <Workspace
@@ -355,12 +355,12 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectWorkspaceData.existsSync(), isTrue);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated', () {
+      testWithoutContext('Xcode project is migrated', () async {
         const String contents = '''
  <?xml version="1.0" encoding="UTF-8"?>
  <Workspace
@@ -379,7 +379,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectWorkspaceData.readAsStringSync(), '''
  <?xml version="1.0" encoding="UTF-8"?>
  <Workspace
@@ -407,19 +407,19 @@
         project.xcodeProjectInfoFile = xcodeProjectInfoFile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final ProjectBaseConfigurationMigration iosProjectMigration = ProjectBaseConfigurationMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectInfoFile.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Xcode project not found, skipping Runner project build settings and configuration migration'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String contents = 'Nothing to upgrade';
         xcodeProjectInfoFile.writeAsStringSync(contents);
         final DateTime projectLastModified = xcodeProjectInfoFile.lastModifiedSync();
@@ -428,7 +428,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
         expect(xcodeProjectInfoFile.readAsStringSync(), contents);
@@ -436,7 +436,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated with template identifiers', () {
+      testWithoutContext('Xcode project is migrated with template identifiers', () async {
         xcodeProjectInfoFile.writeAsStringSync('''
 		97C147031CF9000F007C117D /* Debug */ = {
 			isa = XCBuildConfiguration;
@@ -456,7 +456,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.readAsStringSync(), '''
 		97C147031CF9000F007C117D /* Debug */ = {
@@ -472,7 +472,7 @@
         expect(testLogger.statusText, contains('Project base configurations detected, removing.'));
       });
 
-      testWithoutContext('Xcode project is migrated with custom identifiers', () {
+      testWithoutContext('Xcode project is migrated with custom identifiers', () async {
         xcodeProjectInfoFile.writeAsStringSync('''
 		97C147031CF9000F007C1171 /* Debug */ = {
 			isa = XCBuildConfiguration;
@@ -511,7 +511,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.readAsStringSync(), '''
 		97C147031CF9000F007C1171 /* Debug */ = {
@@ -569,12 +569,12 @@
         project.podfile = podfile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final IOSDeploymentTargetMigration iosProjectMigration = IOSDeploymentTargetMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectInfoFile.existsSync(), isFalse);
         expect(appFrameworkInfoPlist.existsSync(), isFalse);
         expect(podfile.existsSync(), isFalse);
@@ -585,7 +585,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String xcodeProjectInfoFileContents = 'IPHONEOS_DEPLOYMENT_TARGET = 12.0;';
         xcodeProjectInfoFile.writeAsStringSync(xcodeProjectInfoFileContents);
 
@@ -605,7 +605,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
         expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -616,7 +616,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated to 12', () {
+      testWithoutContext('Xcode project is migrated to 12', () async {
         xcodeProjectInfoFile.writeAsStringSync('''
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -656,7 +656,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.readAsStringSync(), '''
 				GCC_WARN_UNUSED_VARIABLE = YES;
@@ -715,12 +715,12 @@
         project.schemeFile = xcodeProjectSchemeFile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final XcodeProjectObjectVersionMigration iosProjectMigration = XcodeProjectObjectVersionMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(xcodeProjectInfoFile.existsSync(), isFalse);
         expect(xcodeProjectSchemeFile.existsSync(), isFalse);
 
@@ -729,7 +729,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String xcodeProjectInfoFileContents = '''
 	classes = {
 	};
@@ -752,7 +752,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
         expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -761,7 +761,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated to newest objectVersion', () {
+      testWithoutContext('Xcode project is migrated to newest objectVersion', () async {
         xcodeProjectInfoFile.writeAsStringSync('''
 	classes = {
 	};
@@ -782,7 +782,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(xcodeProjectInfoFile.readAsStringSync(), '''
 	classes = {
@@ -818,19 +818,19 @@
         project.defaultHostInfoPlist = infoPlistFile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final HostAppInfoPlistMigration iosProjectMigration = HostAppInfoPlistMigration(
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(infoPlistFile.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Info.plist not found, skipping host app Info.plist migration.'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String infoPlistFileContent = '''
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -850,13 +850,13 @@
           testLogger,
         );
         final DateTime infoPlistFileLastModified = infoPlistFile.lastModifiedSync();
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(infoPlistFile.lastModifiedSync(), infoPlistFileLastModified);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('info.plist is migrated', () {
+      testWithoutContext('info.plist is migrated', () async {
         const String infoPlistFileContent = '''
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -871,7 +871,7 @@
           project,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(infoPlistFile.readAsStringSync(), equals('''
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -901,19 +901,19 @@
         project.xcodeProjectInfoFile = xcodeProjectInfoFile;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final RemoveBitcodeMigration migration = RemoveBitcodeMigration(
           project,
           testLogger,
         );
-        expect(migration.migrate(), isTrue);
+        expect(await migration.migrate(), isTrue);
         expect(xcodeProjectInfoFile.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('Xcode project not found, skipping removing bitcode migration'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String xcodeProjectInfoFileContents = 'IPHONEOS_DEPLOYMENT_TARGET = 12.0;';
         xcodeProjectInfoFile.writeAsStringSync(xcodeProjectInfoFileContents);
         final DateTime projectLastModified = xcodeProjectInfoFile.lastModifiedSync();
@@ -922,7 +922,7 @@
           project,
           testLogger,
         );
-        expect(migration.migrate(), isTrue);
+        expect(await migration.migrate(), isTrue);
 
         expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
         expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -930,7 +930,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('bitcode build setting is removed', () {
+      testWithoutContext('bitcode build setting is removed', () async {
         xcodeProjectInfoFile.writeAsStringSync('''
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ENABLE_BITCODE = YES;
@@ -943,7 +943,7 @@
           project,
           testLogger,
         );
-        expect(migration.migrate(), isTrue);
+        expect(await migration.migrate(), isTrue);
 
         expect(xcodeProjectInfoFile.readAsStringSync(), '''
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
@@ -975,20 +975,20 @@
         project.podRunnerFrameworksScript = podRunnerFrameworksScript;
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final CocoaPodsScriptReadlink iosProjectMigration = CocoaPodsScriptReadlink(
           project,
           xcode143ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerFrameworksScript.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('CocoaPods Pods-Runner-frameworks.sh script not found'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to upgrade', () {
+      testWithoutContext('skipped if nothing to upgrade', () async {
         const String contents = r'''
   if [ -L "${source}" ]; then
     echo "Symlinked..."
@@ -1001,13 +1001,13 @@
           xcode143ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerFrameworksScript.existsSync(), isTrue);
         expect(testLogger.traceText, isEmpty);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if Xcode version below 14.3', () {
+      testWithoutContext('skipped if Xcode version below 14.3', () async {
         const String contents = r'''
   if [ -L "${source}" ]; then
     echo "Symlinked..."
@@ -1025,13 +1025,13 @@
           xcode142ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerFrameworksScript.existsSync(), isTrue);
         expect(testLogger.traceText, contains('Detected Xcode version is 14.2.0, below 14.3, skipping "readlink -f" workaround'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated', () {
+      testWithoutContext('Xcode project is migrated', () async {
         const String contents = r'''
   if [ -L "${source}" ]; then
     echo "Symlinked..."
@@ -1044,7 +1044,7 @@
           xcode143ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerFrameworksScript.readAsStringSync(), r'''
   if [ -L "${source}" ]; then
     echo "Symlinked..."
@@ -1073,33 +1073,33 @@
         project.podRunnerTargetSupportFiles = podRunnerTargetSupportFiles;
       });
 
-      testWithoutContext('skip if directory is missing', () {
+      testWithoutContext('skip if directory is missing', () async {
         final CocoaPodsToolchainDirectoryMigration iosProjectMigration = CocoaPodsToolchainDirectoryMigration(
           project,
           xcode15ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerTargetSupportFiles.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('CocoaPods Pods-Runner Target Support Files not found'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skip if xcconfig files are missing', () {
+      testWithoutContext('skip if xcconfig files are missing', () async {
         podRunnerTargetSupportFiles.createSync();
         final CocoaPodsToolchainDirectoryMigration iosProjectMigration = CocoaPodsToolchainDirectoryMigration(
           project,
           xcode15ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(podRunnerTargetSupportFiles.existsSync(), isTrue);
         expect(testLogger.traceText, isEmpty);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skip if nothing to upgrade', () {
+      testWithoutContext('skip if nothing to upgrade', () async {
         podRunnerTargetSupportFiles.createSync();
         final File debugConfig = podRunnerTargetSupportFiles.childFile('Pods-Runner.debug.xcconfig');
         const String contents = r'''
@@ -1119,13 +1119,13 @@
           xcode15ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(debugConfig.existsSync(), isTrue);
         expect(testLogger.traceText, isEmpty);
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if Xcode version below 15', () {
+      testWithoutContext('skipped if Xcode version below 15', () async {
         podRunnerTargetSupportFiles.createSync();
         final File debugConfig = podRunnerTargetSupportFiles.childFile('Pods-Runner.debug.xcconfig');
         const String contents = r'''
@@ -1150,13 +1150,13 @@
           xcode14ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
         expect(debugConfig.existsSync(), isTrue);
         expect(testLogger.traceText, contains('Detected Xcode version is 14.0.0, below 15.0'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('Xcode project is migrated and ignores leading whitespace', () {
+      testWithoutContext('Xcode project is migrated and ignores leading whitespace', () async {
         podRunnerTargetSupportFiles.createSync();
         final File debugConfig = podRunnerTargetSupportFiles.childFile('Pods-Runner.debug.xcconfig');
         const String contents = r'''
@@ -1176,7 +1176,7 @@
           xcode15ProjectInterpreter,
           testLogger,
         );
-        iosProjectMigration.migrate();
+        await iosProjectMigration.migrate();
 
         expect(debugConfig.existsSync(), isTrue);
         expect(debugConfig.readAsStringSync(), r'''
@@ -1214,19 +1214,19 @@
       project.xcodeProjectInfoFile = xcodeProjectInfoFile;
     });
 
-    testWithoutContext('skipped if files are missing', () {
+    testWithoutContext('skipped if files are missing', () async {
       final XcodeScriptBuildPhaseMigration iosProjectMigration = XcodeScriptBuildPhaseMigration(
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
       expect(xcodeProjectInfoFile.existsSync(), isFalse);
 
       expect(testLogger.traceText, contains('Xcode project not found, skipping script build phase dependency analysis removal'));
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to upgrade', () {
+    testWithoutContext('skipped if nothing to upgrade', () async {
       const String xcodeProjectInfoFileContents = '''
 /* Begin PBXShellScriptBuildPhase section */
 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@@ -1245,7 +1245,7 @@
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
       expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -1253,7 +1253,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('alwaysOutOfDate is migrated', () {
+    testWithoutContext('alwaysOutOfDate is migrated', () async {
       xcodeProjectInfoFile.writeAsStringSync('''
 /* Begin PBXShellScriptBuildPhase section */
 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@@ -1276,7 +1276,7 @@
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.readAsStringSync(), '''
 /* Begin PBXShellScriptBuildPhase section */
@@ -1315,19 +1315,19 @@
       project.xcodeProjectInfoFile = xcodeProjectInfoFile;
     });
 
-    testWithoutContext('skipped if files are missing', () {
+    testWithoutContext('skipped if files are missing', () async {
       final XcodeThinBinaryBuildPhaseInputPathsMigration iosProjectMigration = XcodeThinBinaryBuildPhaseInputPathsMigration(
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
       expect(xcodeProjectInfoFile.existsSync(), isFalse);
 
       expect(testLogger.traceText, contains('Xcode project not found, skipping script build phase dependency analysis removal'));
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to upgrade', () {
+    testWithoutContext('skipped if nothing to upgrade', () async {
       const String xcodeProjectInfoFileContents = r'''
 /* Begin PBXShellScriptBuildPhase section */
 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@@ -1348,7 +1348,7 @@
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
       expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -1356,7 +1356,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('Thin Binary inputPaths is migrated', () {
+    testWithoutContext('Thin Binary inputPaths is migrated', () async {
       xcodeProjectInfoFile.writeAsStringSync(r'''
 /* Begin PBXShellScriptBuildPhase section */
 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
@@ -1382,7 +1382,7 @@
         project,
         testLogger,
       );
-      iosProjectMigration.migrate();
+      await iosProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.readAsStringSync(), r'''
 /* Begin PBXShellScriptBuildPhase section */
@@ -1446,7 +1446,7 @@
     : super(BufferLogger.test());
 
   @override
-  void migrate() {}
+  Future<void> migrate() async {}
 
   @override
   String migrateLine(String line) {
diff --git a/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart b/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart
index 291e9ec..0348ec3 100644
--- a/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart
@@ -40,7 +40,7 @@
       macOSProject.xcodeProjectInfoFile = xcodeProjectInfoFile;
     });
 
-    testWithoutContext('skipped if files are missing', () {
+    testWithoutContext('skipped if files are missing', () async {
       final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration =
           RemoveMacOSFrameworkLinkAndEmbeddingMigration(
         macOSProject,
@@ -48,7 +48,7 @@
         testUsage,
         fakeAnalytics,
       );
-      macosProjectMigration.migrate();
+      await macosProjectMigration.migrate();
       expect(testUsage.events, isEmpty);
       expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -61,7 +61,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to upgrade', () {
+    testWithoutContext('skipped if nothing to upgrade', () async {
       const String contents = 'Nothing to upgrade';
       xcodeProjectInfoFile.writeAsStringSync(contents);
       final DateTime projectLastModified =
@@ -74,7 +74,7 @@
         testUsage,
         fakeAnalytics,
       );
-      macosProjectMigration.migrate();
+      await macosProjectMigration.migrate();
       expect(testUsage.events, isEmpty);
       expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -84,7 +84,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skips migrating script with embed', () {
+    testWithoutContext('skips migrating script with embed', () async {
       const String contents = r'''
 shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
 			''';
@@ -97,12 +97,12 @@
         testUsage,
         fakeAnalytics,
       );
-      macosProjectMigration.migrate();
+      await macosProjectMigration.migrate();
       expect(xcodeProjectInfoFile.readAsStringSync(), contents);
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('Xcode project is migrated', () {
+    testWithoutContext('Xcode project is migrated', () async {
       xcodeProjectInfoFile.writeAsStringSync(r'''
 prefix D73912F022F37F9E000D13A0
 D73912F222F3801D000D13A0 suffix
@@ -121,7 +121,7 @@
         testUsage,
         fakeAnalytics,
       );
-      macosProjectMigration.migrate();
+      await macosProjectMigration.migrate();
       expect(testUsage.events, isEmpty);
       expect(fakeAnalytics.sentEvents, isEmpty);
 
@@ -206,12 +206,12 @@
       project.podfile = podfile;
     });
 
-    testWithoutContext('skipped if files are missing', () {
+    testWithoutContext('skipped if files are missing', () async {
       final MacOSDeploymentTargetMigration macOSProjectMigration = MacOSDeploymentTargetMigration(
         project,
         testLogger,
       );
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(xcodeProjectInfoFile.existsSync(), isFalse);
       expect(podfile.existsSync(), isFalse);
 
@@ -220,7 +220,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to upgrade', () {
+    testWithoutContext('skipped if nothing to upgrade', () async {
       const String xcodeProjectInfoFileContents = 'MACOSX_DEPLOYMENT_TARGET = 10.14;';
       xcodeProjectInfoFile.writeAsStringSync(xcodeProjectInfoFileContents);
 
@@ -234,7 +234,7 @@
         project,
         testLogger,
       );
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified);
       expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents);
@@ -244,7 +244,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('Xcode project is migrated from 10.11 to 10.14', () {
+    testWithoutContext('Xcode project is migrated from 10.11 to 10.14', () async {
       xcodeProjectInfoFile.writeAsStringSync('''
  				GCC_WARN_UNUSED_VARIABLE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 10.11;
@@ -260,7 +260,7 @@
         project,
         testLogger,
       );
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.readAsStringSync(), '''
  				GCC_WARN_UNUSED_VARIABLE = YES;
@@ -276,7 +276,7 @@
       expect('Updating minimum macOS deployment target to 10.14'.allMatches(testLogger.statusText).length, 1);
     });
 
-    testWithoutContext('Xcode project is migrated from 10.13 to 10.14', () {
+    testWithoutContext('Xcode project is migrated from 10.13 to 10.14', () async {
       xcodeProjectInfoFile.writeAsStringSync('''
  				GCC_WARN_UNUSED_VARIABLE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 10.13;
@@ -292,7 +292,7 @@
         project,
         testLogger,
       );
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
 
       expect(xcodeProjectInfoFile.readAsStringSync(), '''
  				GCC_WARN_UNUSED_VARIABLE = YES;
@@ -344,7 +344,7 @@
         project,
         testLogger,
       );
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(infoPlistFile.existsSync(), isFalse);
 
       expect(testLogger.traceText, isEmpty);
@@ -357,7 +357,7 @@
         testLogger,
       );
       infoPlistFile.writeAsStringSync('contents'); // Just so it exists: parser is a fake.
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(fakePlistParser.getValueFromFile<String>(infoPlistFile.path, PlistParser.kNSPrincipalClassKey), isNull);
       expect(testLogger.statusText, isEmpty);
     });
@@ -369,7 +369,7 @@
         testLogger,
       );
       infoPlistFile.writeAsStringSync('contents'); // Just so it exists: parser is a fake.
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(fakePlistParser.getValueFromFile<String>(infoPlistFile.path, PlistParser.kNSPrincipalClassKey), 'NSApplication');
       expect(testLogger.statusText, isEmpty);
     });
@@ -381,7 +381,7 @@
         testLogger,
       );
       infoPlistFile.writeAsStringSync('contents'); // Just so it exists: parser is a fake.
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(fakePlistParser.getValueFromFile<String>(infoPlistFile.path, PlistParser.kNSPrincipalClassKey), 'NSApplication');
       // Only print once.
       expect('Updating ${infoPlistFile.basename} to use NSApplication instead of FlutterApplication.'.allMatches(testLogger.statusText).length, 1);
@@ -395,7 +395,7 @@
         testLogger,
       );
       infoPlistFile.writeAsStringSync('contents'); // Just so it exists: parser is a fake.
-      macOSProjectMigration.migrate();
+      await macOSProjectMigration.migrate();
       expect(fakePlistParser.getValueFromFile<String>(infoPlistFile.path, PlistParser.kNSPrincipalClassKey), differentApp);
       expect(testLogger.traceText, isEmpty);
     });
diff --git a/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart b/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart
index 6ebbfa9..1933977 100644
--- a/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/migrations/cmake_project_migration_test.dart
@@ -33,19 +33,19 @@
         mockCmakeProject = FakeCmakeProject(managedCmakeFile);
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final CmakeCustomCommandMigration cmakeProjectMigration = CmakeCustomCommandMigration(
           mockCmakeProject,
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
         expect(managedCmakeFile.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('CMake project not found, skipping add_custom_command() VERBATIM migration'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to migrate', () {
+      testWithoutContext('skipped if nothing to migrate', () async {
         const String contents = 'Nothing to migrate';
         managedCmakeFile.writeAsStringSync(contents);
         final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
@@ -54,7 +54,7 @@
           mockCmakeProject,
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
         expect(managedCmakeFile.readAsStringSync(), contents);
@@ -62,7 +62,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if already migrated', () {
+      testWithoutContext('skipped if already migrated', () async {
         const String contents = r'''
 add_custom_command(
   OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
@@ -81,7 +81,7 @@
           mockCmakeProject,
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
         expect(managedCmakeFile.readAsStringSync(), contents);
@@ -89,7 +89,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('is migrated to use VERBATIM', () {
+      testWithoutContext('is migrated to use VERBATIM', () async {
         managedCmakeFile.writeAsStringSync(r'''
 add_custom_command(
   OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
@@ -105,7 +105,7 @@
           mockCmakeProject,
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.readAsStringSync(), r'''
 add_custom_command(
@@ -122,7 +122,7 @@
         expect(testLogger.statusText, contains('add_custom_command() missing VERBATIM or FLUTTER_TARGET_PLATFORM, updating.'));
       });
 
-      testWithoutContext('is migrated to use FLUTTER_TARGET_PLATFORM', () {
+      testWithoutContext('is migrated to use FLUTTER_TARGET_PLATFORM', () async {
         managedCmakeFile.writeAsStringSync(r'''
 add_custom_command(
   OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
@@ -139,7 +139,7 @@
           mockCmakeProject,
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.readAsStringSync(), r'''
 add_custom_command(
@@ -175,20 +175,20 @@
         mockCmakeProject = FakeCmakeProject(managedCmakeFile);
       });
 
-      testWithoutContext('skipped if files are missing', () {
+      testWithoutContext('skipped if files are missing', () async {
         final CmakeNativeAssetsMigration cmakeProjectMigration = CmakeNativeAssetsMigration(
           mockCmakeProject,
           'linux',
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
         expect(managedCmakeFile.existsSync(), isFalse);
 
         expect(testLogger.traceText, contains('CMake project not found, skipping install() NATIVE_ASSETS_DIR migration.'));
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if nothing to migrate', () {
+      testWithoutContext('skipped if nothing to migrate', () async {
         const String contents = 'Nothing to migrate';
         managedCmakeFile.writeAsStringSync(contents);
         final DateTime projectLastModified = managedCmakeFile.lastModifiedSync();
@@ -198,7 +198,7 @@
           'linux',
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
         expect(managedCmakeFile.readAsStringSync(), contents);
@@ -206,7 +206,7 @@
         expect(testLogger.statusText, isEmpty);
       });
 
-      testWithoutContext('skipped if already migrated', () {
+      testWithoutContext('skipped if already migrated', () async {
         const String contents = r'''
 # Copy the native assets provided by the build.dart from all packages.
 set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
@@ -222,7 +222,7 @@
           'linux',
           testLogger,
         );
-        cmakeProjectMigration.migrate();
+        await cmakeProjectMigration.migrate();
 
         expect(managedCmakeFile.lastModifiedSync(), projectLastModified);
         expect(managedCmakeFile.readAsStringSync(), contents);
@@ -231,7 +231,7 @@
       });
 
       for (final String os in <String>['linux', 'windows']) {
-        testWithoutContext('is migrated to copy native assets', () {
+        testWithoutContext('is migrated to copy native assets', () async {
           managedCmakeFile.writeAsStringSync(r'''
 foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
   install(FILES "${bundled_library}"
@@ -254,7 +254,7 @@
             os,
             testLogger,
           );
-          cmakeProjectMigration.migrate();
+          await cmakeProjectMigration.migrate();
 
           expect(managedCmakeFile.readAsStringSync(), '''
 foreach(bundled_library \${PLUGIN_BUNDLED_LIBRARIES})
diff --git a/packages/flutter_tools/test/general.shard/windows/migrations/build_architecture_migration_test.dart b/packages/flutter_tools/test/general.shard/windows/migrations/build_architecture_migration_test.dart
index 0cc1e9d..160b4c5 100644
--- a/packages/flutter_tools/test/general.shard/windows/migrations/build_architecture_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows/migrations/build_architecture_migration_test.dart
@@ -33,7 +33,7 @@
       mockProject = FakeWindowsProject(cmakeFile);
     });
 
-    testWithoutContext('delete old runner directory', () {
+    testWithoutContext('delete old runner directory', () async {
       buildDirectory.createSync();
       final Directory oldRunnerDirectory =
         buildDirectory
@@ -49,7 +49,7 @@
         buildDirectory,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(oldRunnerDirectory.existsSync(), isFalse);
       expect(testLogger.traceText,
@@ -61,13 +61,13 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if CMake file is missing', () {
+    testWithoutContext('skipped if CMake file is missing', () async {
       final BuildArchitectureMigration migration = BuildArchitectureMigration(
         mockProject,
         buildDirectory,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
       expect(cmakeFile.existsSync(), isFalse);
 
       expect(testLogger.traceText,
@@ -75,7 +75,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to migrate', () {
+    testWithoutContext('skipped if nothing to migrate', () async {
       const String cmakeFileContents = 'Nothing to migrate';
 
       cmakeFile.writeAsStringSync(cmakeFileContents);
@@ -87,14 +87,14 @@
         buildDirectory,
         testLogger,
       );
-      buildArchitectureMigration.migrate();
+      await buildArchitectureMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated', () {
+    testWithoutContext('skipped if already migrated', () async {
       const String cmakeFileContents =
         '# TODO: Move the rest of this into files in ephemeral. See\n'
         '# https://github.com/flutter/flutter/issues/57146.\n'
@@ -128,7 +128,7 @@
         buildDirectory,
         testLogger,
       );
-      buildArchitectureMigration.migrate();
+      await buildArchitectureMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
@@ -136,7 +136,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated (CRLF)', () {
+    testWithoutContext('skipped if already migrated (CRLF)', () async {
       const String cmakeFileContents =
         '# TODO: Move the rest of this into files in ephemeral. See\r\n'
         '# https://github.com/flutter/flutter/issues/57146.\r\n'
@@ -170,7 +170,7 @@
         buildDirectory,
         testLogger,
       );
-      buildArchitectureMigration.migrate();
+      await buildArchitectureMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
@@ -178,7 +178,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('migrates project to set the target platform', () {
+    testWithoutContext('migrates project to set the target platform', () async {
       cmakeFile.writeAsStringSync(
         '# TODO: Move the rest of this into files in ephemeral. See\n'
         '# https://github.com/flutter/flutter/issues/57146.\n'
@@ -203,7 +203,7 @@
         buildDirectory,
         testLogger,
       );
-      buildArchitectureMigration.migrate();
+      await buildArchitectureMigration.migrate();
 
       expect(cmakeFile.readAsStringSync(),
         '# TODO: Move the rest of this into files in ephemeral. See\n'
@@ -233,7 +233,7 @@
       expect(testLogger.statusText, contains('windows/flutter/CMakeLists.txt does not use FLUTTER_TARGET_PLATFORM, updating.'));
     });
 
-    testWithoutContext('migrates project to set the target platform (CRLF)', () {
+    testWithoutContext('migrates project to set the target platform (CRLF)', () async {
       cmakeFile.writeAsStringSync(
         '# TODO: Move the rest of this into files in ephemeral. See\r\n'
         '# https://github.com/flutter/flutter/issues/57146.\r\n'
@@ -259,7 +259,7 @@
         buildDirectory,
         testLogger,
       );
-      buildArchitectureMigration.migrate();
+      await buildArchitectureMigration.migrate();
 
       expect(cmakeFile.readAsStringSync(),
         '# TODO: Move the rest of this into files in ephemeral. See\r\n'
diff --git a/packages/flutter_tools/test/general.shard/windows/migrations/show_window_migration_test.dart b/packages/flutter_tools/test/general.shard/windows/migrations/show_window_migration_test.dart
index 85db407..fba7db8 100644
--- a/packages/flutter_tools/test/general.shard/windows/migrations/show_window_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows/migrations/show_window_migration_test.dart
@@ -31,12 +31,12 @@
       mockProject = FakeWindowsProject(flutterWindowFile);
     });
 
-    testWithoutContext('skipped if Flutter window file is missing', () {
+    testWithoutContext('skipped if Flutter window file is missing', () async {
       final ShowWindowMigration migration = ShowWindowMigration(
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.existsSync(), isFalse);
 
@@ -50,7 +50,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to migrate', () {
+    testWithoutContext('skipped if nothing to migrate', () async {
       const String flutterWindowContents = 'Nothing to migrate';
 
       flutterWindowFile.writeAsStringSync(flutterWindowContents);
@@ -60,7 +60,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.lastModifiedSync(), updatedAt);
       expect(flutterWindowFile.readAsStringSync(), flutterWindowContents);
@@ -68,7 +68,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated', () {
+    testWithoutContext('skipped if already migrated', () async {
       const String flutterWindowContents =
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\n'
         '    this->Show();\n'
@@ -88,7 +88,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.lastModifiedSync(), updatedAt);
       expect(flutterWindowFile.readAsStringSync(), flutterWindowContents);
@@ -96,7 +96,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated (CRLF)', () {
+    testWithoutContext('skipped if already migrated (CRLF)', () async {
       const String flutterWindowContents =
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\r\n'
         '    this->Show();\r\n'
@@ -116,7 +116,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.lastModifiedSync(), updatedAt);
       expect(flutterWindowFile.readAsStringSync(), flutterWindowContents);
@@ -124,7 +124,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('migrates project to ensure window is shown', () {
+    testWithoutContext('migrates project to ensure window is shown', () async {
       flutterWindowFile.writeAsStringSync(
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\n'
         '    this->Show();\n'
@@ -137,7 +137,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.readAsStringSync(),
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\n'
@@ -155,7 +155,7 @@
       expect(testLogger.statusText, contains('windows/runner/flutter_window.cpp does not ensure the show window callback is called, updating.'));
     });
 
-    testWithoutContext('migrates project to ensure window is shown (CRLF)', () {
+    testWithoutContext('migrates project to ensure window is shown (CRLF)', () async {
       flutterWindowFile.writeAsStringSync(
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\r\n'
         '    this->Show();\r\n'
@@ -168,7 +168,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
 
       expect(flutterWindowFile.readAsStringSync(),
         '  flutter_controller_->engine()->SetNextFrameCallback([&]() {\r\n'
diff --git a/packages/flutter_tools/test/general.shard/windows/migrations/version_migration_test.dart b/packages/flutter_tools/test/general.shard/windows/migrations/version_migration_test.dart
index ed972a8..0b0772b 100644
--- a/packages/flutter_tools/test/general.shard/windows/migrations/version_migration_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows/migrations/version_migration_test.dart
@@ -33,7 +33,7 @@
       mockProject = FakeWindowsProject(cmakeFile, resourceFile);
     });
 
-    testWithoutContext('skipped if CMake file is missing', () {
+    testWithoutContext('skipped if CMake file is missing', () async {
       const String resourceFileContents = 'Hello world';
 
       resourceFile.writeAsStringSync(resourceFileContents);
@@ -41,7 +41,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
       expect(cmakeFile.existsSync(), isFalse);
       expect(resourceFile.existsSync(), isTrue);
 
@@ -50,7 +50,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if resource file is missing', () {
+    testWithoutContext('skipped if resource file is missing', () async {
       const String cmakeFileContents = 'Hello world';
 
       cmakeFile.writeAsStringSync(cmakeFileContents);
@@ -58,7 +58,7 @@
         mockProject,
         testLogger,
       );
-      migration.migrate();
+      await migration.migrate();
       expect(cmakeFile.existsSync(), isTrue);
       expect(resourceFile.existsSync(), isFalse);
 
@@ -67,7 +67,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if nothing to migrate', () {
+    testWithoutContext('skipped if nothing to migrate', () async {
       const String cmakeFileContents = 'Nothing to migrate';
       const String resourceFileContents = 'Nothing to migrate';
 
@@ -81,7 +81,7 @@
         mockProject,
         testLogger,
       );
-      versionMigration.migrate();
+      await versionMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
@@ -91,7 +91,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated', () {
+    testWithoutContext('skipped if already migrated', () async {
       const String cmakeFileContents =
         '# Apply the standard set of build settings. This can be removed for applications\n'
         '# that need different build settings.\n'
@@ -129,7 +129,7 @@
         mockProject,
         testLogger,
       );
-      versionMigration.migrate();
+      await versionMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
@@ -139,7 +139,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('skipped if already migrated (CRLF)', () {
+    testWithoutContext('skipped if already migrated (CRLF)', () async {
       const String cmakeFileContents =
         '# Apply the standard set of build settings. This can be removed for applications\r\n'
         '# that need different build settings.\r\n'
@@ -177,7 +177,7 @@
         mockProject,
         testLogger,
       );
-      versionMigration.migrate();
+      await versionMigration.migrate();
 
       expect(cmakeFile.lastModifiedSync(), cmakeUpdatedAt);
       expect(cmakeFile.readAsStringSync(), cmakeFileContents);
@@ -187,7 +187,7 @@
       expect(testLogger.statusText, isEmpty);
     });
 
-    testWithoutContext('migrates project to set version information', () {
+    testWithoutContext('migrates project to set version information', () async {
       cmakeFile.writeAsStringSync(
         '# Apply the standard set of build settings. This can be removed for applications\n'
         '# that need different build settings.\n'
@@ -214,7 +214,7 @@
         mockProject,
         testLogger,
       );
-      versionMigration.migrate();
+      await versionMigration.migrate();
 
       expect(cmakeFile.readAsStringSync(),
         '# Apply the standard set of build settings. This can be removed for applications\n'
@@ -249,7 +249,7 @@
       expect(testLogger.statusText, contains('windows/runner/Runner.rc does not use Flutter version information, updating.'));
     });
 
-    testWithoutContext('migrates project to set version information (CRLF)', () {
+    testWithoutContext('migrates project to set version information (CRLF)', () async {
       cmakeFile.writeAsStringSync(
         '# Apply the standard set of build settings. This can be removed for applications\r\n'
         '# that need different build settings.\r\n'
@@ -276,7 +276,7 @@
         mockProject,
         testLogger,
       );
-      versionMigration.migrate();
+      await versionMigration.migrate();
 
       expect(cmakeFile.readAsStringSync(),
         '# Apply the standard set of build settings. This can be removed for applications\r\n'