Bump to 0.2.1.

Also update the script used to validate and bump versions.

R=jakemac@google.com

Review URL: https://codereview.chromium.org//1505723004 .
diff --git a/bin/format.dart b/bin/format.dart
index 8867f18..8d179c1 100644
--- a/bin/format.dart
+++ b/bin/format.dart
@@ -14,7 +14,7 @@
 import 'package:dart_style/src/source_code.dart';
 
 // Note: The following line of code is modified by tool/grind.dart.
-const version = "0.2.0+1";
+const version = "0.2.1";
 
 void main(List<String> args) {
   var parser = new ArgParser(allowTrailingOptions: true);
diff --git a/lib/src/chunk_builder.dart b/lib/src/chunk_builder.dart
index 61beea3..3aa95a5 100644
--- a/lib/src/chunk_builder.dart
+++ b/lib/src/chunk_builder.dart
@@ -98,8 +98,8 @@
   /// token pair.
   bool get needsToPreserveNewlines =>
       _pendingWhitespace == Whitespace.oneOrTwoNewlines ||
-          _pendingWhitespace == Whitespace.spaceOrNewline ||
-          _pendingWhitespace == Whitespace.splitOrNewline;
+      _pendingWhitespace == Whitespace.spaceOrNewline ||
+      _pendingWhitespace == Whitespace.splitOrNewline;
 
   /// The number of characters of code that can fit in a single line.
   int get pageWidth => _formatter.pageWidth;
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 6c9f013..a34b367 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -2071,7 +2071,8 @@
 
   /// Returns `true` if [node] is immediately contained within an anonymous
   /// [FunctionExpression].
-  bool _isInLambda(AstNode node) => node.parent is FunctionExpression &&
+  bool _isInLambda(AstNode node) =>
+      node.parent is FunctionExpression &&
       node.parent.parent is! FunctionDeclaration;
 
   /// Writes the string literal [string] to the output.
diff --git a/pubspec.yaml b/pubspec.yaml
index 5e44437..c165eb8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart_style
-version: 0.2.1-dev
+version: 0.2.1
 author: Dart Team <misc@dartlang.org>
 description: Opinionated, automatic Dart source code formatter.
 homepage: https://github.com/dart-lang/dart_style
@@ -14,6 +14,7 @@
   async: '>=1.0.0 <=2.0.0'
   browser: '>=0.10.0 <0.11.0'
   grinder: '^0.7.2'
+  pub_semver: '^1.2.3'
   scheduled_test: '>=0.12.0 <0.13.0'
   test: '>=0.12.0 <0.13.0'
   yaml: '^2.0.0'
diff --git a/tool/grind.dart b/tool/grind.dart
index 6690404..5a9b1c6 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -3,23 +3,34 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:grinder/grinder.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart' as yaml;
 
+/// Matches the version line in dart_style's pubspec.
+final _versionPattern = new RegExp(r"^version: .*$", multiLine: true);
+
 main(args) => grind(args);
 
 @DefaultTask()
 @Task()
 validate() async {
+  // Test it.
   await new TestRunner().testAsync();
+
+  // Make sure it's warning clean.
   Analyzer.analyze("bin/format.dart", fatalWarnings: true);
-  DartFmt.format(".");
+
+  // Format it.
+  Dart.run("bin/format.dart", arguments: ["-w", "."]);
 }
 
 /// Gets ready to publish a new version of the package.
 ///
 /// To publish a version, you need to:
 ///
-///   1. Bump the version in the pubspec to a non-dev number.
+///   1. Make sure the version in the pubspec is a "-dev" number. This should
+///      already be the case since you've already landed patches that change
+///      the formatter and bumped to that as a consequence.
 ///
 ///   2. Run this task:
 ///
@@ -47,16 +58,27 @@
 @Depends(validate)
 bump() async {
   // Read the version from the pubspec.
-  var pubspec = yaml.loadYaml(getFile("pubspec.yaml").readAsStringSync());
-  var version = pubspec["version"];
-  print(version);
+  var pubspecFile = getFile("pubspec.yaml");
+  var pubspec = pubspecFile.readAsStringSync();
+  var version = new Version.parse(yaml.loadYaml(pubspec)["version"]);
 
-  if (version.contains("-dev")) throw "Cannot publish a dev version.";
+  // Require a "-dev" version since we don't otherwise know what to bump it to.
+  if (!version.isPreRelease) throw "Cannot publish non-dev version $version.";
+
+  // Don't allow versions like "1.2.3-dev+4" because it's not clear if the
+  // user intended the "+4" to be discarded or not.
+  if (version.build.isNotEmpty) throw "Cannot publish build version $version.";
+
+  var bumped = new Version(version.major, version.minor, version.patch);
+
+  // Update the version in the pubspec.
+  pubspec = pubspec.replaceAll(_versionPattern, "version: $bumped");
+  pubspecFile.writeAsStringSync(pubspec);
 
   // Update the version constant in bin/format.dart.
   var binFormatFile = getFile("bin/format.dart");
   var binFormat = binFormatFile.readAsStringSync().replaceAll(
-      new RegExp(r'const version = "[^"]+";'), 'const version = "$version";');
+      new RegExp(r'const version = "[^"]+";'), 'const version = "$bumped";');
   binFormatFile.writeAsStringSync(binFormat);
-  print("Updated version constant to '$version'.");
+  log("Updated version to '$bumped'.");
 }