Merge pull request #683 from srawlins/docs

Document protobuf installation a bit more
diff --git a/README.md b/README.md
index ee172b5..9de89cc 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,14 @@
 $ pub global activate grinder
 ```
 
-The dart-services v2 API is defined in terms of Protobuf, which requires
-the installation of the Protobuf `protoc` compiler. Please see
-[Protocol Buffers](https://developers.google.com/protocol-buffers/)
-for detailed instalation instructions.
+The dart-services v2 API is defined in terms of Protobuf, which requires the
+installation of the Protobuf `protoc` compiler. Please see [Protocol
+Buffers](https://developers.google.com/protocol-buffers/) for detailed
+installation instructions. On macOS, you may also install with Homebrew via:
+
+```bash
+$ brew install protobuf
+```
 
 The Dart protoc plugin is also required for the above `protoc` compiler
 to generate Dart code. To install, please run:
diff --git a/tool/grind.dart b/tool/grind.dart
index d2d8bf4..8bca75a 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -315,6 +315,9 @@
   await runWithLogging(
     'protoc',
     arguments: ['--dart_out=lib/src', 'protos/dart_services.proto'],
+    onErrorMessage:
+        'Error running "protoc"; make sure the Protocol Buffer compiler is '
+        'installed (see README.md)',
   );
 
   // reformat generated classes so travis dart format test doesn't fail
@@ -336,16 +339,25 @@
 Future<void> runWithLogging(String executable,
     {List<String> arguments = const [],
     RunOptions runOptions,
-    String workingDirectory}) async {
+    String workingDirectory,
+    String onErrorMessage}) async {
   runOptions = mergeWorkingDirectory(workingDirectory, runOptions);
   log("$executable ${arguments.join(' ')}");
   runOptions ??= RunOptions();
 
-  final proc = await Process.start(executable, arguments,
-      workingDirectory: runOptions.workingDirectory,
-      environment: runOptions.environment,
-      includeParentEnvironment: runOptions.includeParentEnvironment,
-      runInShell: runOptions.runInShell);
+  Process proc;
+  try {
+    proc = await Process.start(executable, arguments,
+        workingDirectory: runOptions.workingDirectory,
+        environment: runOptions.environment,
+        includeParentEnvironment: runOptions.includeParentEnvironment,
+        runInShell: runOptions.runInShell);
+  } catch (e) {
+    if (onErrorMessage != null) {
+      print(onErrorMessage);
+    }
+    rethrow;
+  }
 
   proc.stdout.listen((out) => log(runOptions.stdoutEncoding.decode(out)));
   proc.stderr.listen((err) => log(runOptions.stdoutEncoding.decode(err)));