Add support for writing defaultPackageName (#54)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index db4bb00..048eedf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 1.2.0
+ - Added support for writing default-package entries.
+
 ## 1.1.0
 
 - Allow parsing files with default-package entries and metadata.
diff --git a/lib/packages_file.dart b/lib/packages_file.dart
index 284d8e9..1fa18e7 100644
--- a/lib/packages_file.dart
+++ b/lib/packages_file.dart
@@ -106,10 +106,15 @@
 /// If [baseUri] is provided, package locations will be made relative
 /// to the base URI, if possible, before writing.
 ///
+/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
+/// empty string mapping to the _default package name_.
+///
 /// All the keys of [packageMapping] must be valid package names,
 /// and the values must be URIs that do not have the `package:` scheme.
 void write(StringSink output, Map<String, Uri> packageMapping,
-    {Uri baseUri, String comment}) {
+    {Uri baseUri, String comment, bool allowDefaultPackage = false}) {
+  ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage');
+
   if (baseUri != null && !baseUri.isAbsolute) {
     throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
   }
@@ -128,6 +133,21 @@
   }
 
   packageMapping.forEach((String packageName, Uri uri) {
+    // If [packageName] is empty then [uri] is the _default package name_.
+    if (allowDefaultPackage && packageName.isEmpty) {
+      final defaultPackageName = uri.toString();
+      if (!isValidPackageName(defaultPackageName)) {
+        throw ArgumentError.value(
+          defaultPackageName,
+          'defaultPackageName',
+          '"$defaultPackageName" is not a valid package name',
+        );
+      }
+      output.write(':');
+      output.write(defaultPackageName);
+      output.writeln();
+      return;
+    }
     // Validate packageName.
     if (!isValidPackageName(packageName)) {
       throw new ArgumentError('"$packageName" is not a valid package name');
diff --git a/pubspec.yaml b/pubspec.yaml
index b51932e..72d299b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: package_config
-version: 1.1.0
+version: 1.2.0
 description: Support for working with Package Resolution config files.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/package_config
diff --git a/test/parse_write_test.dart b/test/parse_write_test.dart
index b963eb5..415b479 100644
--- a/test/parse_write_test.dart
+++ b/test/parse_write_test.dart
@@ -4,6 +4,7 @@
 
 library package_config.parse_write_test;
 
+import "dart:convert" show utf8;
 import "package:package_config/packages_file.dart";
 import "package:test/test.dart";
 
@@ -32,6 +33,40 @@
             var resultMap = parse(content, packagesFile);
             expect(resultMap, map);
           });
+
+          test("write with defaultPackageName", () {
+            var content = writeToString(
+              {'': Uri.parse('my_pkg')}..addAll(map),
+              allowDefaultPackage: true,
+            ).codeUnits;
+            var resultMap = parse(
+              content,
+              packagesFile,
+              allowDefaultPackage: true,
+            );
+            expect(resultMap[''].toString(), 'my_pkg');
+            expect(
+              resultMap,
+              {'': Uri.parse('my_pkg')}..addAll(map),
+            );
+          });
+
+          test("write with defaultPackageName (utf8)", () {
+            var content = utf8.encode(writeToString(
+              {'': Uri.parse('my_pkg')}..addAll(map),
+              allowDefaultPackage: true,
+            ));
+            var resultMap = parse(
+              content,
+              packagesFile,
+              allowDefaultPackage: true,
+            );
+            expect(resultMap[''].toString(), 'my_pkg');
+            expect(
+              resultMap,
+              {'': Uri.parse('my_pkg')}..addAll(map),
+            );
+          });
         });
       }
 
@@ -82,8 +117,16 @@
   });
 }
 
-String writeToString(Map<String, Uri> map, {Uri baseUri, String comment}) {
+String writeToString(
+  Map<String, Uri> map, {
+  Uri baseUri,
+  String comment,
+  bool allowDefaultPackage = false,
+}) {
   var buffer = new StringBuffer();
-  write(buffer, map, baseUri: baseUri, comment: comment);
+  write(buffer, map,
+      baseUri: baseUri,
+      comment: comment,
+      allowDefaultPackage: allowDefaultPackage);
   return buffer.toString();
 }