diff --git a/packages/flutter_tools/lib/src/commands/ios.dart b/packages/flutter_tools/lib/src/commands/ios.dart index cc6ba2b4618..d3bea131ef3 100644 --- a/packages/flutter_tools/lib/src/commands/ios.dart +++ b/packages/flutter_tools/lib/src/commands/ios.dart @@ -8,6 +8,8 @@ import "dart:io"; import "package:path/path.dart" as path; import "../artifacts.dart"; +import "../base/logging.dart"; +import "../base/process.dart"; import "../runner/flutter_command.dart"; import "../runner/flutter_command_runner.dart"; @@ -23,7 +25,6 @@ class IOSCommand extends FlutterCommand { static Uri _xcodeProjectUri(String revision) { String uriString = "https://storage.googleapis.com/flutter_infra/flutter/$revision/ios/FlutterXcode.zip"; - print("Downloading $uriString ..."); return Uri.parse(uriString); } @@ -32,7 +33,9 @@ class IOSCommand extends FlutterCommand { HttpClient client = new HttpClient(); - HttpClientRequest request = await client.getUrl(_xcodeProjectUri(ArtifactStore.engineRevision)); + Uri xcodeProjectUri = _xcodeProjectUri(ArtifactStore.engineRevision); + logging.info("Downloading $xcodeProjectUri..."); + HttpClientRequest request = await client.getUrl(xcodeProjectUri); HttpClientResponse response = await request.close(); if (response.statusCode != 200) @@ -48,27 +51,23 @@ class IOSCommand extends FlutterCommand { Future _inflateXcodeArchive(String directory, List archiveBytes) async { print("Unzipping Xcode project to local directory..."); - if (archiveBytes.isEmpty) - return false; - - // We cannot use ArchiveFile because this archive contains file that are exectuable + // We cannot use ArchiveFile because this archive contains files that are exectuable // and there is currently no provision to modify file permissions during - // or after creation. See https://github.com/dart-lang/sdk/issues/15078 + // or after creation. See https://github.com/dart-lang/sdk/issues/15078. // So we depend on the platform to unzip the archive for us. Directory tempDir = await Directory.systemTemp.create(); - File tempFile = await new File(path.join(tempDir.path, "FlutterXcode.zip")).create(); - IOSink writeSink = tempFile.openWrite(); - writeSink.add(archiveBytes); - await writeSink.close(); + File tempFile = new File(path.join(tempDir.path, "FlutterXcode.zip"))..createSync(); + tempFile.writeAsBytesSync(archiveBytes); - ProcessResult result = await Process.run('/usr/bin/unzip', [tempFile.path, '-d', directory]); + try { + runCheckedSync(['/usr/bin/unzip', tempFile.path, '-d', directory]); + } catch (error) { + return false; + } // Cleanup the temp directory after unzipping - await Process.run('/bin/rm', ['rf', tempDir.path]); - - if (result.exitCode != 0) - return false; + runSync(['/bin/rm', '-rf', tempDir.path]); Directory flutterDir = new Directory(path.join(directory, 'Flutter')); bool flutterDirExists = await flutterDir.exists(); @@ -78,24 +77,24 @@ class IOSCommand extends FlutterCommand { // Move contents of the Flutter directory one level up // There is no dart:io API to do this. See https://github.com/dart-lang/sdk/issues/8148 - bool moveFailed = false; for (FileSystemEntity file in flutterDir.listSync()) { - ProcessResult result = await Process.run('/bin/mv', [file.path, directory]); - moveFailed = result.exitCode != 0; - if (moveFailed) - break; + try { + runCheckedSync(['/bin/mv', file.path, directory]); + } catch (error) { + return false; + } } - ProcessResult rmResult = await Process.run('/bin/rm', ["-rf", flutterDir.path]); + runSync(['/bin/rm', '-rf', flutterDir.path]); - return !moveFailed && rmResult.exitCode == 0; + return true; } - Future _setupXcodeProjXcconfig(String filePath) async { + void _setupXcodeProjXcconfig(String filePath) { StringBuffer localsBuffer = new StringBuffer(); - localsBuffer.writeln("// Generated. Do not edit or check into version control!!"); - localsBuffer.writeln("// Recreate using `flutter ios`"); + localsBuffer.writeln("// Generated. Do not edit or check into version control!"); + localsBuffer.writeln("// Recreate using `flutter ios`."); String flutterRoot = path.normalize(Platform.environment[kFlutterRootEnvironmentVariableName]); localsBuffer.writeln("FLUTTER_ROOT=$flutterRoot"); @@ -108,10 +107,8 @@ class IOSCommand extends FlutterCommand { localsBuffer.writeln("DART_SDK_PATH=$dartSDKPath"); File localsFile = new File(filePath); - await localsFile.create(recursive: true); - await localsFile.writeAsString(localsBuffer.toString()); - - return true; + localsFile.createSync(recursive: true); + localsFile.writeAsStringSync(localsBuffer.toString()); } Future _runInitCommand() async { @@ -119,23 +116,24 @@ class IOSCommand extends FlutterCommand { String xcodeprojPath = path.join(Directory.current.path, "ios"); List archiveBytes = await _fetchXcodeArchive(); + if (archiveBytes.isEmpty) { + print("Error: No archive bytes received."); + return 1; + } + // Step 2: Inflate the archive into the user project directory bool result = await _inflateXcodeArchive(xcodeprojPath, archiveBytes); if (!result) { print("Error: Could not init the Xcode project: the 'ios' directory already exists."); print("To proceed, remove the 'ios' directory and try again."); print("Warning: You may have made manual changes to files in the 'ios' directory."); - return -1; + return 1; } // Step 3: Populate the Local.xcconfig with project specific paths - result = await _setupXcodeProjXcconfig(path.join(xcodeprojPath, "Local.xcconfig")); - if (!result) { - print("Could not setup local properties file"); - return -1; - } + _setupXcodeProjXcconfig(path.join(xcodeprojPath, "Local.xcconfig")); - // Step 4: Launch Xcode and let the user edit plist, resources, provisioning, etc. + // Step 4: Tell the user the location of the generated project. print("An Xcode project has been placed in 'ios/'."); print("You may edit it to modify iOS specific configuration."); return 0; @@ -145,13 +143,13 @@ class IOSCommand extends FlutterCommand { Future runInProject() async { if (!Platform.isMacOS) { print("iOS specific commands may only be run on a Mac."); - return -1; + return 1; } if (argResults['init']) return await _runInitCommand(); - print("No flags specified..."); - return -1; + print("No flags specified."); + return 1; } } diff --git a/packages/flutter_tools/lib/src/ios/device_ios.dart b/packages/flutter_tools/lib/src/ios/device_ios.dart index 337eaf53ff5..b7929965aa6 100644 --- a/packages/flutter_tools/lib/src/ios/device_ios.dart +++ b/packages/flutter_tools/lib/src/ios/device_ios.dart @@ -200,7 +200,7 @@ class IOSDevice extends Device { // Step 2: Check that the application exists at the specified path Directory bundle = new Directory(path.join(app.localPath, 'build', 'Release-iphoneos', 'Runner.app')); - bool bundleExists = await bundle.exists(); + bool bundleExists = bundle.existsSync(); if (!bundleExists) { logging.severe('Could not find the built application bundle at ${bundle.path}'); return false; @@ -572,7 +572,7 @@ Future _buildIOSXcodeProject(ApplicationPackage app, bool isDevice) async command.addAll(['-sdk', 'iphonesimulator']); } - ProcessResult result = await Process.runSync('/usr/bin/env', command, + ProcessResult result = Process.runSync('/usr/bin/env', command, workingDirectory: app.localPath); return result.exitCode == 0; }