[flutter_tools] Add a timeout to another showBuildSettings command (#39579)
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart
index 21bb6c0..c44d739 100644
--- a/packages/flutter_tools/lib/src/base/logger.dart
+++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -279,6 +279,9 @@
String get traceText => _trace.toString();
@override
+ bool get hasTerminal => false;
+
+ @override
void printError(
String message, {
StackTrace stackTrace,
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index 83985e5..4bb99fd 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -32,6 +32,7 @@
import 'fuchsia/fuchsia_device.dart' show FuchsiaDeviceTools;
import 'fuchsia/fuchsia_sdk.dart' show FuchsiaSdk, FuchsiaArtifacts;
import 'fuchsia/fuchsia_workflow.dart' show FuchsiaWorkflow;
+import 'ios/devices.dart' show IOSDeploy;
import 'ios/ios_workflow.dart';
import 'ios/mac.dart';
import 'ios/simulators.dart';
@@ -90,6 +91,7 @@
GenSnapshot: () => const GenSnapshot(),
HotRunnerConfig: () => HotRunnerConfig(),
IMobileDevice: () => IMobileDevice(),
+ IOSDeploy: () => const IOSDeploy(),
IOSSimulatorUtils: () => IOSSimulatorUtils(),
IOSWorkflow: () => const IOSWorkflow(),
KernelCompilerFactory: () => const KernelCompilerFactory(),
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index 7fc3abe..b9734df 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -8,6 +8,7 @@
import '../application_package.dart';
import '../artifacts.dart';
+import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
@@ -28,6 +29,8 @@
class IOSDeploy {
const IOSDeploy();
+ static IOSDeploy get instance => context.get<IOSDeploy>();
+
/// Installs and runs the specified app bundle using ios-deploy, then returns
/// the exit code.
Future<int> runApp({
@@ -365,7 +368,7 @@
);
}
- final int installationResult = await const IOSDeploy().runApp(
+ final int installationResult = await IOSDeploy.instance.runApp(
deviceId: id,
bundlePath: bundle.path,
launchArguments: launchArguments,
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 053d9c9..b67b450 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -462,22 +462,41 @@
);
flutterUsage.sendTiming('build', 'xcode-ios', Duration(milliseconds: sw.elapsedMilliseconds));
- // Run -showBuildSettings again but with the exact same parameters as the build.
- final Map<String, String> buildSettings = parseXcodeBuildSettings(runCheckedSync(
- (List<String>
- .from(buildCommands)
- ..add('-showBuildSettings'))
- // Undocumented behavior: xcodebuild craps out if -showBuildSettings
- // is used together with -allowProvisioningUpdates or
- // -allowProvisioningDeviceRegistration and freezes forever.
- .where((String buildCommand) {
- return !const <String>[
- '-allowProvisioningUpdates',
- '-allowProvisioningDeviceRegistration',
- ].contains(buildCommand);
- }).toList(),
- workingDirectory: app.project.hostAppRoot.path,
- ));
+ // Run -showBuildSettings again but with the exact same parameters as the
+ // build. showBuildSettings is reported to ocassionally timeout. Here, we give
+ // it a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
+ // When there is a timeout, we retry once. See issue #35988.
+ final List<String> showBuildSettingsCommand = (List<String>
+ .from(buildCommands)
+ ..add('-showBuildSettings'))
+ // Undocumented behavior: xcodebuild craps out if -showBuildSettings
+ // is used together with -allowProvisioningUpdates or
+ // -allowProvisioningDeviceRegistration and freezes forever.
+ .where((String buildCommand) {
+ return !const <String>[
+ '-allowProvisioningUpdates',
+ '-allowProvisioningDeviceRegistration',
+ ].contains(buildCommand);
+ }).toList();
+ const Duration showBuildSettingsTimeout = Duration(minutes: 1);
+ Map<String, String> buildSettings;
+ try {
+ final RunResult showBuildSettingsResult = await runCheckedAsync(
+ showBuildSettingsCommand,
+ workingDirectory: app.project.hostAppRoot.path,
+ timeout: showBuildSettingsTimeout,
+ timeoutRetries: 1,
+ );
+ final String showBuildSettings = showBuildSettingsResult.stdout.trim();
+ buildSettings = parseXcodeBuildSettings(showBuildSettings);
+ } on ProcessException catch (e) {
+ if (e.toString().contains('timed out')) {
+ BuildEvent('xcode-show-build-settings-timeout',
+ command: showBuildSettingsCommand.join(' '),
+ ).send();
+ }
+ rethrow;
+ }
if (buildResult.exitCode != 0) {
printStatus('Failed to build iOS app');
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 5acc1c1..8c54c61 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -20,6 +20,7 @@
import '../cache.dart';
import '../globals.dart';
import '../project.dart';
+import '../reporting/reporting.dart';
final RegExp _settingExpr = RegExp(r'(\w+)\s*=\s*(.*)$');
final RegExp _varExpr = RegExp(r'\$\(([^)]*)\)');
@@ -278,18 +279,20 @@
final Status status = Status.withSpinner(
timeout: timeoutConfiguration.fastOperation,
);
+ final List<String> showBuildSettingsCommand = <String>[
+ _executable,
+ '-project',
+ fs.path.absolute(projectPath),
+ '-target',
+ target,
+ '-showBuildSettings',
+ ];
try {
// showBuildSettings is reported to ocassionally timeout. Here, we give it
// a lot of wiggle room (locally on Flutter Gallery, this takes ~1s).
// When there is a timeout, we retry once.
- final RunResult result = await runCheckedAsync(<String>[
- _executable,
- '-project',
- fs.path.absolute(projectPath),
- '-target',
- target,
- '-showBuildSettings',
- ],
+ final RunResult result = await runCheckedAsync(
+ showBuildSettingsCommand,
workingDirectory: projectPath,
timeout: timeout,
timeoutRetries: 1,
@@ -297,6 +300,11 @@
final String out = result.stdout.trim();
return parseXcodeBuildSettings(out);
} catch(error) {
+ if (error is ProcessException && error.toString().contains('timed out')) {
+ BuildEvent('xcode-show-build-settings-timeout',
+ command: showBuildSettingsCommand.join(' '),
+ ).send();
+ }
printTrace('Unexpected failure to get the build settings: $error.');
return const <String, String>{};
} finally {