Merge pull request #1481 from devoncarew/patch_ios_logs

fix a regex in the ios logs command
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index 3fb4b23..bc9b8c8 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -21,26 +21,20 @@
     cmd.sublist(1),
     workingDirectory: workingDirectory
   );
-  process.stdout.transform(UTF8.decoder).listen((String data) {
-    List<String> dataLines = data.trimRight().split('\n');
-    if (filter != null) {
-      // TODO(ianh): This doesn't handle IO buffering (where the data might be split half-way through a line)
-      dataLines = dataLines.where((String s) => filter.hasMatch(s)).toList();
-    }
-    if (dataLines.length > 0) {
-      printStatus('$prefix${dataLines.join('\n$prefix')}');
-    }
-  });
-  process.stderr.transform(UTF8.decoder).listen((String data) {
-    List<String> dataLines = data.trimRight().split('\n');
-    if (filter != null) {
-      // TODO(ianh): This doesn't handle IO buffering (where the data might be split half-way through a line)
-      dataLines = dataLines.where((String s) => filter.hasMatch(s));
-    }
-    if (dataLines.length > 0) {
-      printError('$prefix${dataLines.join('\n$prefix')}');
-    }
-  });
+  process.stdout
+    .transform(UTF8.decoder)
+    .transform(const LineSplitter())
+    .where((String line) => filter == null ? true : filter.hasMatch(line))
+    .listen((String line) {
+      printStatus('$prefix$line');
+    });
+  process.stderr
+    .transform(UTF8.decoder)
+    .transform(const LineSplitter())
+    .where((String line) => filter == null ? true : filter.hasMatch(line))
+    .listen((String line) {
+      printError('$prefix$line');
+    });
   return await process.exitCode;
 }
 
diff --git a/packages/flutter_tools/lib/src/commands/start.dart b/packages/flutter_tools/lib/src/commands/start.dart
index 0cd836f..121104a 100644
--- a/packages/flutter_tools/lib/src/commands/start.dart
+++ b/packages/flutter_tools/lib/src/commands/start.dart
@@ -137,7 +137,7 @@
     if (clearLogs != null)
       platformArgs['clear-logs'] = clearLogs;
 
-    printStatus('Starting $mainPath on ${device.name}...');
+    printStatus('Starting ${_getDisplayPath(mainPath)} on ${device.name}...');
 
     bool result = await device.startApp(
       package,
@@ -149,7 +149,7 @@
     );
 
     if (!result) {
-      printError('Could not start \'${package.name}\' on \'${device.id}\'');
+      printError('Error starting application on ${device.name}.');
     } else {
       startedSomething = true;
     }
@@ -165,3 +165,12 @@
 
   return startedSomething ? 0 : 2;
 }
+
+/// Return a relative path if [fullPath] is contained by the cwd, else return an
+/// absolute path.
+String _getDisplayPath(String fullPath) {
+  String cwd = Directory.current.path + Platform.pathSeparator;
+  if (fullPath.startsWith(cwd))
+    return fullPath.substring(cwd.length);
+  return fullPath;
+}
diff --git a/packages/flutter_tools/lib/src/ios/device_ios.dart b/packages/flutter_tools/lib/src/ios/device_ios.dart
index 5a2d2a0..0b9e549 100644
--- a/packages/flutter_tools/lib/src/ios/device_ios.dart
+++ b/packages/flutter_tools/lib/src/ios/device_ios.dart
@@ -131,7 +131,7 @@
         if (Platform.isMacOS) {
           printError('$command not found. $macInstructions');
         } else {
-          printError('Cannot control iOS devices or simulators.  $command is not available on your platform.');
+          printError('Cannot control iOS devices or simulators. $command is not available on your platform.');
         }
       }
       return command;
@@ -261,7 +261,7 @@
       return 2;
     }
     return await runCommandAndStreamOutput([loggerPath],
-        prefix: 'iOS: ', filter: new RegExp('FlutterRunner'));
+        prefix: 'iOS: ', filter: new RegExp(r'(FlutterRunner|flutter.runner.Runner)'));
   }
 }
 
@@ -315,8 +315,8 @@
           'which is not supposed to happen.');
       for (Match match in matches) {
         if (match.groupCount > 0) {
-          // TODO: We're killing simulator devices inside an accessor method;
-          // we probably shouldn't be changing state here.
+          // TODO(devoncarew): We're killing simulator devices inside an accessor
+          // method; we probably shouldn't be changing state here.
           printError('Killing simulator ${match.group(1)}');
           runSync([xcrunPath, 'simctl', 'shutdown', match.group(2)]);
         }
@@ -518,12 +518,21 @@
     String logFilePath = path.join(
       homeDirectory, 'Library', 'Logs', 'CoreSimulator', simulatorDeviceID, 'system.log'
     );
+
     if (clear)
       runSync(['rm', logFilePath]);
+
+    // TODO(devoncarew): The log message prefix could be shortened or removed.
+    // Jan 29 01:31:44 devoncarew-macbookpro3 SpringBoard[96648]:
+    // TODO(devoncarew): This truncates multi-line messages like:
+    // Jan 29 01:31:43 devoncarew-macbookpro3 CoreSimulatorBridge[96656]: Requesting... {
+    //     environment =     {
+    //     };
+    //   }
     return await runCommandAndStreamOutput(
       ['tail', '-f', logFilePath],
-      prefix: 'iOS sim: ',
-      filter: new RegExp(r'.*SkyShell.*')
+      prefix: 'iOS: ',
+      filter: new RegExp(r'(FlutterRunner|flutter.runner.Runner)')
     );
   }
 }