From eedc5d9f583924a8fae611f8d8e281d53c3f6f38 Mon Sep 17 00:00:00 2001 From: Jakob Andersen Date: Mon, 27 Mar 2017 09:30:36 +0200 Subject: [PATCH] Make pod install a long-running step. (#8999) The very first time `pod install` is invoked, CocoaPods downloads the master spec repository, which takes quite a while. Before this change, the build appeared to have stalled. With this change, at least the spinner is moving. Added `pod setup` to the install instructions for CocoaPods, so the spec repo is downloaded while setting up Flutter, instead of during the first build. --- .../flutter_tools/lib/src/base/process.dart | 21 +++++++++++++++++-- .../lib/src/commands/build_ios.dart | 5 +---- .../lib/src/ios/ios_workflow.dart | 6 ++++-- packages/flutter_tools/lib/src/ios/mac.dart | 11 +++++++--- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart index 04a3c6fcc1201..8ded4f6955828 100644 --- a/packages/flutter_tools/lib/src/base/process.dart +++ b/packages/flutter_tools/lib/src/base/process.dart @@ -182,19 +182,36 @@ Future runDetached(List cmd) { Future runAsync(List cmd, { String workingDirectory, - bool allowReentrantFlutter: false + bool allowReentrantFlutter: false, + Map environment }) async { _traceCommand(cmd, workingDirectory: workingDirectory); final ProcessResult results = await processManager.run( cmd, workingDirectory: workingDirectory, - environment: _environment(allowReentrantFlutter), + environment: _environment(allowReentrantFlutter, environment), ); final RunResult runResults = new RunResult(results); printTrace(runResults.toString()); return runResults; } +Future runCheckedAsync(List cmd, { + String workingDirectory, + bool allowReentrantFlutter: false, + Map environment +}) async { + final RunResult result = await runAsync( + cmd, + workingDirectory: workingDirectory, + allowReentrantFlutter: allowReentrantFlutter, + environment: environment + ); + if (result.exitCode != 0) + throw 'Exit code ${result.exitCode} from: ${cmd.join(' ')}'; + return result; +} + bool exitsHappy(List cli) { _traceCommand(cli); try { diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index 1bf1a6cab4374..93792eca58419 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -6,7 +6,6 @@ import 'dart:async'; import '../application_package.dart'; import '../base/common.dart'; -import '../base/logger.dart'; import '../base/utils.dart'; import '../build_info.dart'; import '../globals.dart'; @@ -64,8 +63,7 @@ class BuildIOSCommand extends BuildSubCommand { final String logTarget = forSimulator ? 'simulator' : 'device'; final String typeName = artifacts.getEngineType(TargetPlatform.ios, getBuildMode()); - final Status status = logger.startProgress('Building $app for $logTarget ($typeName)...', - expectSlowOperation: true); + printStatus('Building $app for $logTarget ($typeName)...'); final XcodeBuildResult result = await buildXcodeProject( app: app, mode: getBuildMode(), @@ -73,7 +71,6 @@ class BuildIOSCommand extends BuildSubCommand { buildForDevice: !forSimulator, codesign: shouldCodesign ); - status.stop(); if (!result.success) { await diagnoseXcodeBuildFailure(result); diff --git a/packages/flutter_tools/lib/src/ios/ios_workflow.dart b/packages/flutter_tools/lib/src/ios/ios_workflow.dart index 8156a73df30a1..bdae6fdc9a72c 100644 --- a/packages/flutter_tools/lib/src/ios/ios_workflow.dart +++ b/packages/flutter_tools/lib/src/ios/ios_workflow.dart @@ -185,13 +185,15 @@ class IOSWorkflow extends DoctorValidator implements Workflow { messages.add(new ValidationMessage.error( 'CocoaPods not installed. To install:\n' 'brew update\n' - 'brew install cocoapods' + 'brew install cocoapods\n' + 'pod setup' )); } else { messages.add(new ValidationMessage.error( 'CocoaPods out of date ($cocoaPodsMinimumVersion is required). To upgrade:\n' 'brew update\n' - 'brew upgrade cocoapods' + 'brew upgrade cocoapods\n' + 'pod setup' )); } } diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index e26e0d71c824f..030de20b6561c 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -11,6 +11,7 @@ import '../application_package.dart'; import '../base/context.dart'; import '../base/common.dart'; import '../base/file_system.dart'; +import '../base/logger.dart'; import '../base/io.dart'; import '../base/platform.dart'; import '../base/process.dart'; @@ -130,7 +131,7 @@ Future buildXcodeProject({ await _addServicesToBundle(appDirectory); writeFlutterPluginsList(); - _runPodInstall(appDirectory, flutterFrameworkDir(mode)); + await _runPodInstall(appDirectory, flutterFrameworkDir(mode)); final List commands = [ '/usr/bin/env', @@ -170,11 +171,13 @@ Future buildXcodeProject({ ); } + final Status status = logger.startProgress('Running Xcode build...', expectSlowOperation: true); final RunResult result = await runAsync( commands, workingDirectory: app.appDirectory, allowReentrantFlutter: true ); + status.stop(); if (result.exitCode != 0) { printStatus('Failed to build iOS app'); @@ -321,7 +324,7 @@ bool _checkXcodeVersion() { return true; } -void _runPodInstall(Directory bundle, String engineDirectory) { +Future _runPodInstall(Directory bundle, String engineDirectory) async { if (fs.file(fs.path.join(bundle.path, 'Podfile')).existsSync()) { if (!doctor.iosWorkflow.cocoaPodsInstalledAndMeetsVersionCheck) { final String minimumVersion = doctor.iosWorkflow.cocoaPodsMinimumVersion; @@ -329,11 +332,13 @@ void _runPodInstall(Directory bundle, String engineDirectory) { return; } try { - runCheckedSync( + final Status status = logger.startProgress('Running pod install...', expectSlowOperation: true); + await runCheckedAsync( ['pod', 'install'], workingDirectory: bundle.path, environment: {'FLUTTER_FRAMEWORK_DIR': engineDirectory}, ); + status.stop(); } catch (e) { throwToolExit('Error running pod install: $e'); }