Merge branch 'master' into new-package-config
diff --git a/.travis.yml b/.travis.yml
index 9ce0790..5cccfe5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
 language: dart
 
 dart:
-  - 2.6.0
+  - 2.7.0
   - dev
 
 install:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea509ae..c3d28d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.13.8 - 2020-03-02
+
+* Update to package_config `1.9.0` which supports package_config.json
+  files and should be forwards compatible with `2.0.0`.
+* Deprecate the `packageRoot` argument on `Resolver`.
+
 ## 0.13.7 - 2020-02-28
 
 * Loosen the dependency on the `vm_service` package from `>=1.0.0 <3.0.0` to
diff --git a/bin/format_coverage.dart b/bin/format_coverage.dart
index 0b15899..3e2b659 100644
--- a/bin/format_coverage.dart
+++ b/bin/format_coverage.dart
@@ -54,6 +54,7 @@
       ? BazelResolver(workspacePath: env.bazelWorkspace)
       : Resolver(
           packagesPath: env.packagesPath,
+          // ignore_for_file: deprecated_member_use_from_same_package
           packageRoot: env.pkgRoot,
           sdkRoot: env.sdkRoot);
   final loader = Loader();
diff --git a/lib/src/resolver.dart b/lib/src/resolver.dart
index 446b930..03ae6ef 100644
--- a/lib/src/resolver.dart
+++ b/lib/src/resolver.dart
@@ -3,16 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
-// TODO(#289): Remove
-// ignore: deprecated_member_use
-import 'package:package_config/packages_file.dart' as packages_file;
+import 'package:package_config/package_config.dart';
 import 'package:path/path.dart' as p;
 
 /// [Resolver] resolves imports with respect to a given environment.
 class Resolver {
-  Resolver({String packagesPath, this.packageRoot, this.sdkRoot})
+  // ignore_for_file: deprecated_member_use_from_same_package
+  Resolver({String packagesPath, @deprecated this.packageRoot, this.sdkRoot})
       : packagesPath = packagesPath,
         _packages = packagesPath != null ? _parsePackages(packagesPath) : null;
 
@@ -91,8 +91,32 @@
   }
 
   static Map<String, Uri> _parsePackages(String packagesPath) {
-    final source = File(packagesPath).readAsBytesSync();
-    return packages_file.parse(source, Uri.file(packagesPath));
+    final content = File(packagesPath).readAsStringSync();
+    try {
+      final parsed =
+          PackageConfig.parseString(content, Uri.base.resolve(packagesPath));
+      return {
+        for (var package in parsed.packages)
+          package.name: package.packageUriRoot
+      };
+    } on FormatException catch (_) {
+      // It was probably an old style .packages file
+      final lines = LineSplitter.split(content);
+      final packageMap = <String, Uri>{};
+      for (var line in lines) {
+        if (line.startsWith('#')) continue;
+        final firstColon = line.indexOf(':');
+        if (firstColon == -1) {
+          throw FormatException(
+              'Unexpected package config format, expected an old style '
+              '.packages file or new style package_config.json file.',
+              content);
+        }
+        packageMap[line.substring(0, firstColon)] =
+            Uri.parse(line.substring(firstColon + 1, line.length));
+      }
+      return packageMap;
+    }
   }
 }
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 9e6d63f..5401403 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,15 +1,15 @@
 name: coverage
-version: 0.13.7
+version: 0.13.8
 description: Coverage data manipulation and formatting
 homepage: https://github.com/dart-lang/coverage
 
 environment:
-  sdk: '>=2.6.0 <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
-  args: '>=1.4.0 <2.0.0'
+  args: ^1.4.0
   logging: '>=0.9.0 <0.12.0'
-  package_config: '>=0.1.5 <2.0.0'
+  package_config: ^1.9.0
   path: '>=0.9.0 <2.0.0'
   source_maps: ^0.10.8
   stack_trace: ^1.3.0
@@ -18,6 +18,7 @@
 dev_dependencies:
   pedantic: ^1.0.0
   test: ^1.0.0
+  test_descriptor: ^1.2.0
 
 executables:
   collect_coverage:
diff --git a/test/resolver_test.dart b/test/resolver_test.dart
index fce793e..cd718ea 100644
--- a/test/resolver_test.dart
+++ b/test/resolver_test.dart
@@ -2,10 +2,66 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+import 'dart:isolate';
+
 import 'package:coverage/src/resolver.dart';
+import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
 
 void main() {
+  group('Default Resolver', () {
+    setUp(() async {
+      await d.dir('foo', [
+        d.file('.packages', '''
+# Fake for testing!
+foo:file:///${d.sandbox}/foo/lib
+'''),
+        d.file('.bad.packages', 'thisIsntAPackagesFile!'),
+        d.dir('.dart_tool', [
+          d.file('package_config.json', '''
+{
+  "configVersion": 2,
+  "packages": [
+    {
+      "name": "foo",
+      "rootUri": "file:///${d.sandbox}/foo",
+      "packageUri": "lib/"
+    }
+  ]
+}
+'''),
+        ]),
+        d.dir('lib', [
+          d.file('foo.dart', 'final foo = "bar";'),
+        ]),
+      ]).create();
+    });
+
+    test('can be created from a package_config.json', () async {
+      final resolver = Resolver(
+          packagesPath:
+              p.join(d.sandbox, 'foo', '.dart_tool', 'package_config.json'));
+      expect(resolver.resolve('package:foo/foo.dart'),
+          '${d.sandbox}/foo/lib/foo.dart');
+    });
+
+    test('can be created from a .packages file', () async {
+      final resolver =
+          Resolver(packagesPath: p.join(d.sandbox, 'foo', '.packages'));
+      expect(resolver.resolve('package:foo/foo.dart'),
+          '${d.sandbox}/foo/lib/foo.dart');
+    });
+
+    test('errors if the packagesFile is an unknown format', () async {
+      expect(
+          () =>
+              Resolver(packagesPath: p.join(d.sandbox, 'foo', '.bad.packages')),
+          throwsA(isA<FormatException>()));
+    });
+  });
+
   group('Bazel resolver', () {
     const workspace = 'foo';
     final resolver = BazelResolver(workspacePath: workspace);