Reland "Add flag controlling creation of `.packages` file." (#3413)

diff --git a/lib/src/command/add.dart b/lib/src/command/add.dart
index 0980b81..0556434 100644
--- a/lib/src/command/add.dart
+++ b/lib/src/command/add.dart
@@ -94,6 +94,8 @@
         help: 'Build executables in immediate dependencies.');
     argParser.addOption('directory',
         abbr: 'C', help: 'Run this in the directory <dir>.', valueHelp: 'dir');
+    argParser.addFlag('legacy-packages-file',
+        help: 'Generate the legacy ".packages" file', negatable: false);
   }
 
   @override
@@ -165,7 +167,8 @@
           .acquireDependencies(SolveType.get,
               dryRun: true,
               precompile: argResults['precompile'],
-              analytics: analytics);
+              analytics: analytics,
+              generateDotPackages: false);
     } else {
       /// Update the `pubspec.yaml` before calling [acquireDependencies] to
       /// ensure that the modification timestamp on `pubspec.lock` and
@@ -180,6 +183,7 @@
         SolveType.get,
         precompile: argResults['precompile'],
         analytics: analytics,
+        generateDotPackages: argResults['legacy-packages-file'],
       );
 
       if (argResults['example'] && entrypoint.example != null) {
@@ -188,6 +192,7 @@
           precompile: argResults['precompile'],
           onlyReportSuccessOrFailure: true,
           analytics: analytics,
+          generateDotPackages: argResults['legacy-packages-file'],
         );
       }
     }
diff --git a/lib/src/command/downgrade.dart b/lib/src/command/downgrade.dart
index 274ab48..fce5ef3 100644
--- a/lib/src/command/downgrade.dart
+++ b/lib/src/command/downgrade.dart
@@ -42,6 +42,8 @@
 
     argParser.addOption('directory',
         abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir');
+    argParser.addFlag('legacy-packages-file',
+        help: 'Generate the legacy ".packages" file', negatable: false);
   }
 
   @override
@@ -57,6 +59,7 @@
       unlock: argResults.rest,
       dryRun: dryRun,
       analytics: analytics,
+      generateDotPackages: argResults['legacy-packages-file'],
     );
     var example = entrypoint.example;
     if (argResults['example'] && example != null) {
@@ -66,6 +69,7 @@
         dryRun: dryRun,
         onlyReportSuccessOrFailure: true,
         analytics: analytics,
+        generateDotPackages: argResults['legacy-packages-file'],
       );
     }
 
diff --git a/lib/src/command/get.dart b/lib/src/command/get.dart
index 302bb93..7b8906c 100644
--- a/lib/src/command/get.dart
+++ b/lib/src/command/get.dart
@@ -33,6 +33,9 @@
 
     argParser.addFlag('packages-dir', hide: true);
 
+    argParser.addFlag('legacy-packages-file',
+        help: 'Generate the legacy ".packages" file', negatable: false);
+
     argParser.addFlag(
       'example',
       help: 'Also run in `example/` (if it exists).',
@@ -53,16 +56,20 @@
       SolveType.get,
       dryRun: argResults['dry-run'],
       precompile: argResults['precompile'],
+      generateDotPackages: argResults['legacy-packages-file'],
       analytics: analytics,
     );
 
     var example = entrypoint.example;
     if (argResults['example'] && example != null) {
-      await example.acquireDependencies(SolveType.get,
-          dryRun: argResults['dry-run'],
-          precompile: argResults['precompile'],
-          onlyReportSuccessOrFailure: true,
-          analytics: analytics);
+      await example.acquireDependencies(
+        SolveType.get,
+        dryRun: argResults['dry-run'],
+        precompile: argResults['precompile'],
+        generateDotPackages: argResults['legacy-packages-file'],
+        analytics: analytics,
+        onlyReportSuccessOrFailure: true,
+      );
     }
   }
 }
diff --git a/lib/src/command/remove.dart b/lib/src/command/remove.dart
index f3b27bd..82a9547 100644
--- a/lib/src/command/remove.dart
+++ b/lib/src/command/remove.dart
@@ -50,6 +50,9 @@
 
     argParser.addOption('directory',
         abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir');
+
+    argParser.addFlag('legacy-packages-file',
+        help: 'Generate the legacy ".packages" file', negatable: false);
   }
 
   @override
@@ -69,7 +72,8 @@
           .acquireDependencies(SolveType.get,
               precompile: argResults['precompile'],
               dryRun: true,
-              analytics: null);
+              analytics: null,
+              generateDotPackages: false);
     } else {
       /// Update the pubspec.
       _writeRemovalToPubspec(packages);
@@ -81,6 +85,7 @@
         SolveType.get,
         precompile: argResults['precompile'],
         analytics: analytics,
+        generateDotPackages: argResults['legacy-packages-file'],
       );
 
       var example = entrypoint.example;
@@ -90,6 +95,7 @@
           precompile: argResults['precompile'],
           onlyReportSuccessOrFailure: true,
           analytics: analytics,
+          generateDotPackages: argResults['legacy-packages-file'],
         );
       }
     }
diff --git a/lib/src/command/upgrade.dart b/lib/src/command/upgrade.dart
index 927d849..af0c6e1 100644
--- a/lib/src/command/upgrade.dart
+++ b/lib/src/command/upgrade.dart
@@ -56,6 +56,9 @@
 
     argParser.addFlag('packages-dir', hide: true);
 
+    argParser.addFlag('legacy-packages-file',
+        help: 'Generate the legacy ".packages" file', negatable: false);
+
     argParser.addFlag(
       'major-versions',
       help: 'Upgrades packages to their latest resolvable versions, '
@@ -80,6 +83,8 @@
 
   bool get _precompile => argResults['precompile'];
 
+  bool get _packagesFile => argResults['legacy-packages-file'];
+
   bool get _upgradeNullSafety =>
       argResults['nullsafety'] || argResults['null-safety'];
 
@@ -126,6 +131,7 @@
       dryRun: _dryRun,
       precompile: _precompile,
       onlyReportSuccessOrFailure: onlySummary,
+      generateDotPackages: _packagesFile,
       analytics: analytics,
     );
     _showOfflineWarning();
@@ -237,6 +243,7 @@
         dryRun: true,
         precompile: _precompile,
         analytics: null, // No analytics for dry-run
+        generateDotPackages: false,
       );
     } else {
       if (changes.isNotEmpty) {
@@ -249,6 +256,7 @@
         SolveType.get,
         precompile: _precompile,
         analytics: analytics,
+        generateDotPackages: argResults['legacy-packages-file'],
       );
     }
 
@@ -333,6 +341,7 @@
         dryRun: true,
         precompile: _precompile,
         analytics: null,
+        generateDotPackages: false,
       );
     } else {
       if (changes.isNotEmpty) {
@@ -345,6 +354,7 @@
         SolveType.upgrade,
         precompile: _precompile,
         analytics: analytics,
+        generateDotPackages: argResults['legacy-packages-file'],
       );
     }
 
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart
index b4a01a6..ac7ff51 100644
--- a/lib/src/entrypoint.dart
+++ b/lib/src/entrypoint.dart
@@ -224,13 +224,17 @@
   Entrypoint? _example;
 
   /// Writes .packages and .dart_tool/package_config.json
-  Future<void> writePackagesFiles() async {
+  Future<void> writePackagesFiles({bool generateDotPackages = false}) async {
     final entrypointName = isGlobal ? null : root.name;
-    writeTextFile(
-        packagesFile,
-        lockFile.packagesFile(cache,
-            entrypoint: entrypointName,
-            relativeFrom: isGlobal ? null : root.dir));
+    if (generateDotPackages) {
+      writeTextFile(
+          packagesFile,
+          lockFile.packagesFile(cache,
+              entrypoint: entrypointName,
+              relativeFrom: isGlobal ? null : root.dir));
+    } else {
+      tryDeleteEntry(packagesFile);
+    }
     ensureDir(p.dirname(packageConfigFile));
     writeTextFile(
         packageConfigFile,
@@ -268,6 +272,7 @@
     Iterable<String>? unlock,
     bool dryRun = false,
     bool precompile = false,
+    required bool generateDotPackages,
     required PubAnalytics? analytics,
     bool onlyReportSuccessOrFailure = false,
   }) async {
@@ -341,7 +346,7 @@
       /// have to reload and reparse all the pubspecs.
       _packageGraph = PackageGraph.fromSolveResult(this, result);
 
-      await writePackagesFiles();
+      await writePackagesFiles(generateDotPackages: generateDotPackages);
 
       try {
         if (precompile) {
diff --git a/lib/src/executable.dart b/lib/src/executable.dart
index 5d8ea8b..3f8f6a9 100644
--- a/lib/src/executable.dart
+++ b/lib/src/executable.dart
@@ -308,6 +308,7 @@
         () => entrypoint.acquireDependencies(
           SolveType.get,
           analytics: analytics,
+          generateDotPackages: false,
         ),
       );
     } on ApplicationException catch (e) {
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart
index 82b1263..81c34f5 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -159,7 +159,11 @@
     var entrypoint = Entrypoint(path, cache);
 
     // Get the package's dependencies.
-    await entrypoint.acquireDependencies(SolveType.get, analytics: analytics);
+    await entrypoint.acquireDependencies(
+      SolveType.get,
+      analytics: analytics,
+      generateDotPackages: false,
+    );
     var name = entrypoint.root.name;
     _describeActive(name, cache);
 
diff --git a/lib/src/package_config.dart b/lib/src/package_config.dart
index 0493dcc..d64808b 100644
--- a/lib/src/package_config.dart
+++ b/lib/src/package_config.dart
@@ -2,6 +2,8 @@
 // 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:convert';
+
 import 'package:pub_semver/pub_semver.dart';
 
 import 'language_version.dart';
@@ -160,8 +162,6 @@
   /// Given as `<major>.<minor>` version, similar to the `// @dart = X.Y`
   /// comment. This is derived from the lower-bound on the Dart SDK requirement
   /// in the `pubspec.yaml` for the given package.
-  ///
-  /// `null` if not given.
   LanguageVersion? languageVersion;
 
   /// Additional properties not in the specification for the
@@ -173,10 +173,8 @@
     required this.rootUri,
     this.packageUri,
     this.languageVersion,
-    this.additionalProperties,
-  }) {
-    additionalProperties ??= {};
-  }
+    this.additionalProperties = const {},
+  });
 
   /// Create [PackageConfigEntry] from JSON [data].
   ///
@@ -249,7 +247,13 @@
   Map<String, Object?> toJson() => {
         'name': name,
         'rootUri': rootUri.toString(),
-        if (packageUri != null) 'packageUri': packageUri?.toString(),
+        if (packageUri != null) 'packageUri': packageUri.toString(),
         if (languageVersion != null) 'languageVersion': '$languageVersion',
       }..addAll(additionalProperties ?? {});
+
+  @override
+  String toString() {
+    // TODO: implement toString
+    return JsonEncoder.withIndent('  ').convert(toJson());
+  }
 }
diff --git a/test/add/common/add_test.dart b/test/add/common/add_test.dart
index 1a1e9df..82e098b 100644
--- a/test/add/common/add_test.dart
+++ b/test/add/common/add_test.dart
@@ -46,7 +46,9 @@
       await pubAdd(args: ['foo:1.2.3']);
 
       await d.cacheDir({'foo': '1.2.3'}).validate();
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
       await d.appDir({'foo': '1.2.3'}).validate();
     });
 
@@ -62,8 +64,11 @@
 
       await d.cacheDir(
           {'foo': '1.2.3', 'bar': '1.1.0', 'baz': '2.5.3'}).validate();
-      await d.appPackagesFile(
-          {'foo': '1.2.3', 'bar': '1.1.0', 'baz': '2.5.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+        d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+        d.packageConfigEntry(name: 'baz', version: '2.5.3'),
+      ]).validate();
       await d
           .appDir({'foo': '1.2.3', 'bar': '1.1.0', 'baz': '2.5.3'}).validate();
     });
@@ -90,7 +95,9 @@
       await pubAdd(args: ['foo:1.2.3']);
 
       await d.cacheDir({'foo': '1.2.3'}).validate();
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
 
       await d.dir(appPath, [
         d.pubspec({
@@ -136,7 +143,9 @@
       await pubAdd(args: ['foo:1.2.3']);
 
       await d.cacheDir({'foo': '1.2.3'}).validate();
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
       await d.appDir({'foo': '1.2.3'}).validate();
     });
 
@@ -217,7 +226,9 @@
               'adding it to dependencies instead.'));
 
       await d.cacheDir({'foo': '1.2.3'}).validate();
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
 
       await d.dir(appPath, [
         d.pubspec({
@@ -244,7 +255,9 @@
         await pubAdd(args: ['foo']);
 
         await d.cacheDir({'foo': '1.2.2'}).validate();
-        await d.appPackagesFile({'foo': '1.2.2'}).validate();
+        await d.appPackageConfigFile([
+          d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+        ]).validate();
         await d.dir(appPath, [
           d.pubspec({
             'name': 'myapp',
@@ -456,7 +469,9 @@
 
       await pubAdd(args: ['--dev', 'foo:1.2.3']);
 
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
 
       await d.dir(appPath, [
         d.pubspec({
@@ -566,7 +581,9 @@
         await pubAdd(args: ['foo', '--dev']);
 
         await d.cacheDir({'foo': '1.2.2'}).validate();
-        await d.appPackagesFile({'foo': '1.2.2'}).validate();
+        await d.appPackageConfigFile([
+          d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+        ]).validate();
         await d.dir(appPath, [
           d.pubspec({
             'name': 'myapp',
diff --git a/test/add/common/version_constraint_test.dart b/test/add/common/version_constraint_test.dart
index 546642f..f058082 100644
--- a/test/add/common/version_constraint_test.dart
+++ b/test/add/common/version_constraint_test.dart
@@ -22,7 +22,9 @@
     await pubAdd(args: ['foo']);
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'foo': '^1.2.3'}).validate();
   });
 
@@ -35,7 +37,9 @@
     await pubAdd(args: ['foo:1.2.3']);
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'foo': '1.2.3'}).validate();
   });
 
@@ -48,7 +52,9 @@
     await pubAdd(args: ['foo:1.2.3-dev']);
 
     await d.cacheDir({'foo': '1.2.3-dev'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3-dev'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3-dev'),
+    ]).validate();
     await d.appDir({'foo': '1.2.3-dev'}).validate();
   });
 
@@ -65,7 +71,9 @@
     await pubAdd(args: ['foo:any']);
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'foo': 'any'}).validate();
   });
 
@@ -78,7 +86,9 @@
     await pubAdd(args: ['foo:>1.2.0 <2.0.0']);
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'foo': '>1.2.0 <2.0.0'}).validate();
   });
 
@@ -98,7 +108,10 @@
     await d.appDir({'foo': '^0.1.0', 'bar': '2.0.3'}).validate();
 
     await d.cacheDir({'foo': '0.1.0', 'bar': '2.0.3'}).validate();
-    await d.appPackagesFile({'foo': '0.1.0', 'bar': '2.0.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '0.1.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.0.3'),
+    ]).validate();
   });
 
   group('does not update pubspec if no available version found', () {
diff --git a/test/add/common/version_resolution_test.dart b/test/add/common/version_resolution_test.dart
index 64b393a..0f44d2b 100644
--- a/test/add/common/version_resolution_test.dart
+++ b/test/add/common/version_resolution_test.dart
@@ -32,7 +32,10 @@
 
     await d.appDir({'foo': '^3.5.0', 'bar': '1.0.0'}).validate();
     await d.cacheDir({'foo': '3.5.0', 'bar': '1.0.0'}).validate();
-    await d.appPackagesFile({'foo': '3.5.0', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '3.5.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
   });
 
   test('chooses the appropriate version to not break other dependencies',
@@ -54,7 +57,10 @@
 
     await d.appDir({'foo': '^3.2.1', 'bar': '1.0.0'}).validate();
     await d.cacheDir({'foo': '3.2.1', 'bar': '1.0.0'}).validate();
-    await d.appPackagesFile({'foo': '3.2.1', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '3.2.1'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
   });
 
   test('may upgrade other packages if they allow a later version to be chosen',
@@ -78,6 +84,9 @@
 
     await d.appDir({'foo': '^4.0.0', 'bar': '^1.0.0'}).validate();
     await d.cacheDir({'foo': '4.0.0', 'bar': '1.5.0'}).validate();
-    await d.appPackagesFile({'foo': '4.0.0', 'bar': '1.5.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '4.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.5.0'),
+    ]).validate();
   });
 }
diff --git a/test/add/git/git_test.dart b/test/add/git/git_test.dart
index 00bd334..d976172 100644
--- a/test/add/git/git_test.dart
+++ b/test/add/git/git_test.dart
@@ -173,7 +173,9 @@
     await pubAdd(args: ['foo', '--git-url', '../foo.git']);
 
     await d.cacheDir({'foo': '1.2.2'}).validate();
-    await d.appPackagesFile({'foo': '1.2.2'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+    ]).validate();
     await d.dir(appPath, [
       d.pubspec({
         'name': 'myapp',
diff --git a/test/add/git/subdir_test.dart b/test/add/git/subdir_test.dart
index 0f78069..8e8c39c 100644
--- a/test/add/git/subdir_test.dart
+++ b/test/add/git/subdir_test.dart
@@ -30,10 +30,11 @@
         ])
       ])
     ]).validate();
-
-    await d.appPackagesFile({
-      'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub',
+          path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')),
+    ]).validate();
 
     await d.appDir({
       'sub': {
@@ -68,9 +69,11 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub',
+          path: pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir')),
+    ]).validate();
 
     await d.appDir({
       'sub': {
diff --git a/test/add/hosted/non_default_pub_server_test.dart b/test/add/hosted/non_default_pub_server_test.dart
index c3f7afa..787bf32 100644
--- a/test/add/hosted/non_default_pub_server_test.dart
+++ b/test/add/hosted/non_default_pub_server_test.dart
@@ -27,7 +27,9 @@
 
     await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate();
 
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+    ]).validate();
 
     await d.appDir({
       'foo': {
@@ -60,8 +62,11 @@
     await d.cacheDir({'foo': '1.2.3', 'bar': '3.2.3', 'baz': '1.3.5'},
         port: server.port).validate();
 
-    await d.appPackagesFile(
-        {'foo': '1.2.3', 'bar': '3.2.3', 'baz': '1.3.5'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+      d.packageConfigEntry(name: 'bar', version: '3.2.3', server: server),
+      d.packageConfigEntry(name: 'baz', version: '1.3.5', server: server),
+    ]).validate();
 
     await d.appDir({
       'foo': {
@@ -121,7 +126,9 @@
     await pubAdd(args: ['foo', '--hosted-url', url]);
 
     await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+    ]).validate();
     await d.appDir({
       'foo': {
         'version': '^1.2.3',
@@ -148,7 +155,9 @@
     await pubAdd(args: ['foo', '--hosted-url', url]);
 
     await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+    ]).validate();
     await d.appDir({
       'foo': {
         'version': '^1.2.3',
@@ -176,7 +185,9 @@
     await pubAdd(args: ['foo:any', '--hosted-url', url]);
 
     await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+    ]).validate();
     await d.appDir({
       'foo': {
         'version': 'any',
diff --git a/test/add/path/absolute_path_test.dart b/test/add/path/absolute_path_test.dart
index b15ec2d..5e63679 100644
--- a/test/add/path/absolute_path_test.dart
+++ b/test/add/path/absolute_path_test.dart
@@ -20,7 +20,9 @@
 
     await pubAdd(args: ['foo', '--path', absolutePath]);
 
-    await d.appPackagesFile({'foo': absolutePath}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: absolutePath),
+    ]).validate();
 
     await d.appDir({
       'foo': {'path': absolutePath}
@@ -127,7 +129,9 @@
     await pubAdd(args: ['foo', '--path', absolutePath]);
 
     await d.cacheDir({'foo': '1.2.2'}).validate();
-    await d.appPackagesFile({'foo': '1.2.2'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+    ]).validate();
     await d.dir(appPath, [
       d.pubspec({
         'name': 'myapp',
diff --git a/test/add/path/relative_path_test.dart b/test/add/path/relative_path_test.dart
index c02b644..e08ba3c 100644
--- a/test/add/path/relative_path_test.dart
+++ b/test/add/path/relative_path_test.dart
@@ -19,7 +19,9 @@
 
     await pubAdd(args: ['foo', '--path', '../foo']);
 
-    await d.appPackagesFile({'foo': '../foo'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+    ]).validate();
 
     await d.appDir({
       'foo': {'path': '../foo'}
@@ -38,7 +40,9 @@
       output: contains('Changed 1 dependency in myapp!'),
     );
 
-    await d.appPackagesFile({'foo': '../foo'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+    ]).validate();
 
     await d.appDir({
       'foo': {'path': '../foo'}
@@ -118,7 +122,9 @@
     await pubAdd(args: ['foo', '--path', '../foo']);
 
     await d.cacheDir({'foo': '1.2.2'}).validate();
-    await d.appPackagesFile({'foo': '1.2.2'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+    ]).validate();
     await d.dir(appPath, [
       d.pubspec({
         'name': 'myapp',
diff --git a/test/add/sdk/sdk_test.dart b/test/add/sdk/sdk_test.dart
index 1a98b78..7c81727 100644
--- a/test/add/sdk/sdk_test.dart
+++ b/test/add/sdk/sdk_test.dart
@@ -42,11 +42,12 @@
           'foo': {'sdk': 'flutter'}
         }
       }),
-      d.packagesFile({
-        'myapp': '.',
-        'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'),
-        'bar': '1.0.0'
-      })
+    ]).validate();
+
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
     ]).validate();
   });
 
@@ -65,11 +66,11 @@
           'foo': {'sdk': 'flutter', 'version': '0.0.1'}
         }
       }),
-      d.packagesFile({
-        'myapp': '.',
-        'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'),
-        'bar': '1.0.0'
-      })
+    ]).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
     ]).validate();
   });
 
@@ -79,11 +80,10 @@
         args: ['baz', '--sdk', 'flutter'],
         environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});
 
-    await d.dir(appPath, [
-      d.packagesFile({
-        'myapp': '.',
-        'baz': p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz')
-      })
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'baz',
+          path: p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz'))
     ]).validate();
   });
 
diff --git a/test/dependency_override_test.dart b/test/dependency_override_test.dart
index dd8dc0d..59f59e4 100644
--- a/test/dependency_override_test.dart
+++ b/test/dependency_override_test.dart
@@ -27,7 +27,9 @@
 
       await pubCommand(command);
 
-      await d.appPackagesFile({'foo': '2.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+      ]).validate();
     });
 
     test('treats override as implicit dependency', () async {
@@ -43,7 +45,9 @@
 
       await pubCommand(command);
 
-      await d.appPackagesFile({'foo': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      ]).validate();
     });
 
     test('ignores other constraints on overridden package', () async {
@@ -65,7 +69,10 @@
 
       await pubCommand(command);
 
-      await d.appPackagesFile({'foo': '2.0.0', 'bar': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      ]).validate();
     });
 
     test('ignores SDK constraints', () async {
@@ -82,8 +89,9 @@
       ]).create();
 
       await pubCommand(command);
-
-      await d.appPackagesFile({'foo': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      ]).validate();
     });
 
     test('warns about overridden dependencies', () async {
diff --git a/test/descriptor.dart b/test/descriptor.dart
index 2491df4..b3f8a55 100644
--- a/test/descriptor.dart
+++ b/test/descriptor.dart
@@ -287,6 +287,23 @@
 }) =>
     PackageConfigFileDescriptor(packages, generatorVersion);
 
+Descriptor appPackageConfigFile(
+  List<PackageConfigEntry> packages, {
+  String generatorVersion = '0.1.2+3',
+}) =>
+    dir(
+      appPath,
+      [
+        packageConfigFile(
+          [
+            packageConfigEntry(name: 'myapp', path: '.'),
+            ...packages,
+          ],
+          generatorVersion: generatorVersion,
+        ),
+      ],
+    );
+
 /// Create a [PackageConfigEntry] which assumes package with [name] is either
 /// a cached package with given [version] or a path dependency at given [path].
 PackageConfigEntry packageConfigEntry({
@@ -294,6 +311,7 @@
   String? version,
   String? path,
   String? languageVersion,
+  PackageServer? server,
 }) {
   if (version != null && path != null) {
     throw ArgumentError.value(
@@ -305,7 +323,7 @@
   }
   Uri rootUri;
   if (version != null) {
-    rootUri = p.toUri(globalServer.pathInCache(name, version));
+    rootUri = p.toUri((server ?? globalServer).pathInCache(name, version));
   } else {
     rootUri = p.toUri(p.join('..', path));
   }
diff --git a/test/descriptor/packages.dart b/test/descriptor/packages.dart
index de52a80..b670322 100644
--- a/test/descriptor/packages.dart
+++ b/test/descriptor/packages.dart
@@ -156,10 +156,20 @@
 
     // Compare packages as sets to ignore ordering.
     expect(
-      config.packages.map((e) => e.toJson()).toSet(),
-      equals(_packages.map((e) => e.toJson()).toSet()),
-      reason:
-          '"packages" property in "$packageConfigFile" does not expected values',
+      config.packages,
+      _packages
+          .map(
+            (p) => isA<PackageConfigEntry>()
+                .having((p0) => p0.name, 'name', p.name)
+                .having(
+                    (p0) => p0.languageVersion,
+                    'languageVersion',
+                    // If the expected entry has no language-version we don't check it.
+                    p.languageVersion ?? anything)
+                .having((p0) => p0.rootUri, 'rootUri', p.rootUri)
+                .having((p0) => p0.packageUri, 'packageUri', p.packageUri),
+          )
+          .toSet(),
     );
 
     final expected = PackageConfig.fromJson(_config.toJson());
diff --git a/test/dev_dependency_test.dart b/test/dev_dependency_test.dart
index 88f321b..b192444 100644
--- a/test/dev_dependency_test.dart
+++ b/test/dev_dependency_test.dart
@@ -27,7 +27,10 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '../foo', 'bar': '../bar'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+      d.packageConfigEntry(name: 'bar', path: '../bar'),
+    ]).validate();
   });
 
   test("includes dev dependency's transitive dependencies", () async {
@@ -52,7 +55,10 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '../foo', 'bar': '../bar'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+      d.packageConfigEntry(name: 'bar', path: '../bar'),
+    ]).validate();
   });
 
   test("ignores transitive dependency's dev dependencies", () async {
@@ -78,6 +84,8 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '../foo'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+    ]).validate();
   });
 }
diff --git a/test/downgrade/unlock_if_necessary_test.dart b/test/downgrade/unlock_if_necessary_test.dart
index 0299e27..c8b55af 100644
--- a/test/downgrade/unlock_if_necessary_test.dart
+++ b/test/downgrade/unlock_if_necessary_test.dart
@@ -19,13 +19,19 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '2.0.0', 'foo_dep': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+      d.packageConfigEntry(name: 'foo_dep', version: '2.0.0'),
+    ]).validate();
 
     server.serve('foo', '1.0.0', deps: {'foo_dep': '<2.0.0'});
     server.serve('foo_dep', '1.0.0');
 
     await pubDowngrade(args: ['foo']);
 
-    await d.appPackagesFile({'foo': '1.0.0', 'foo_dep': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'foo_dep', version: '1.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/downgrade/unlock_single_package_test.dart b/test/downgrade/unlock_single_package_test.dart
index cfd315d..1188e41 100644
--- a/test/downgrade/unlock_single_package_test.dart
+++ b/test/downgrade/unlock_single_package_test.dart
@@ -16,22 +16,34 @@
     await d.appDir({'foo': 'any', 'bar': 'any'}).create();
 
     await pubGet();
-    await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.1.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.1.0'),
+    ]).validate();
 
     server.serve('foo', '1.0.0', deps: {'bar': 'any'});
     server.serve('bar', '1.0.0');
 
     await pubDowngrade(args: ['bar']);
-    await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.1.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.1.0'),
+    ]).validate();
 
     server.serve('foo', '2.0.0', deps: {'bar': 'any'});
     server.serve('bar', '2.0.0');
 
     await pubDowngrade(args: ['bar']);
-    await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.1.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.0.0'),
+    ]).validate();
 
     await pubDowngrade();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
   });
 
   test('will not downgrade below constraint #2629', () async {
@@ -43,11 +55,14 @@
     await d.appDir({'foo': '^2.0.0'}).create();
 
     await pubGet();
-
-    await d.appPackagesFile({'foo': '2.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.1.0'),
+    ]).validate();
 
     await pubDowngrade(args: ['foo']);
 
-    await d.appPackagesFile({'foo': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/git/path_test.dart b/test/get/git/path_test.dart
index d26d9cb..d9c9195 100644
--- a/test/get/git/path_test.dart
+++ b/test/get/git/path_test.dart
@@ -39,9 +39,11 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub',
+          path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')),
+    ]).validate();
   });
 
   test('depends on a package in a deep subdirectory', () async {
@@ -73,9 +75,12 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub',
+          path:
+              pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')),
+    ]).validate();
 
     final lockFile = LockFile.load(
         p.join(d.sandbox, appPath, 'pubspec.lock'), SystemCache().sources);
@@ -198,9 +203,12 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub',
+          path:
+              pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')),
+    ]).validate();
 
     final lockFile = LockFile.load(
         p.join(d.sandbox, appPath, 'pubspec.lock'), SystemCache().sources);
@@ -244,10 +252,14 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub1': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir1'),
-      'sub2': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir2')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub1',
+          path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir1')),
+      d.packageConfigEntry(
+          name: 'sub2',
+          path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir2')),
+    ]).validate();
   });
 
   test('depends on packages in the same subdirectory at different revisions',
@@ -292,9 +304,11 @@
       ])
     ]).validate();
 
-    await d.appPackagesFile({
-      'sub1': pathInCache('git/foo-$oldRevision/subdir'),
-      'sub2': pathInCache('git/foo-$newRevision/subdir')
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(
+          name: 'sub1', path: pathInCache('git/foo-$oldRevision/subdir')),
+      d.packageConfigEntry(
+          name: 'sub2', path: pathInCache('git/foo-$newRevision/subdir')),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/avoid_network_requests_test.dart b/test/get/hosted/avoid_network_requests_test.dart
index 8778ae6..c62fa7c 100644
--- a/test/get/hosted/avoid_network_requests_test.dart
+++ b/test/get/hosted/avoid_network_requests_test.dart
@@ -31,8 +31,10 @@
 
     // Run the solver again.
     await pubGet();
-
-    await d.appPackagesFile({'foo': '1.2.0', 'bar': '1.2.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.2.0'),
+    ]).validate();
 
     // The get should not have done any network requests since the lock file is
     // up to date.
diff --git a/test/get/hosted/cached_pubspec_test.dart b/test/get/hosted/cached_pubspec_test.dart
index beb4e16..fa9decc 100644
--- a/test/get/hosted/cached_pubspec_test.dart
+++ b/test/get/hosted/cached_pubspec_test.dart
@@ -22,7 +22,9 @@
     server.requestedPaths.clear();
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
 
     // Run the solver again now that it's cached.
     await pubGet();
diff --git a/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart b/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart
index 00b2444..44fe075 100644
--- a/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart
+++ b/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart
@@ -21,13 +21,19 @@
 
     await pubGet();
 
-    await d.appPackagesFile(
-        {'foo': '1.0.0', 'bar': '1.0.0', 'shared_dep': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'),
+    ]).validate();
 
     await d.appDir({'foo': 'any'}).create();
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0', 'shared_dep': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/does_no_network_requests_when_possible_test.dart b/test/get/hosted/does_no_network_requests_when_possible_test.dart
index ea1f4a7..4324776 100644
--- a/test/get/hosted/does_no_network_requests_when_possible_test.dart
+++ b/test/get/hosted/does_no_network_requests_when_possible_test.dart
@@ -27,7 +27,9 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.2.0'}).validate();
-    await d.appPackagesFile({'foo': '1.2.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.0'),
+    ]).validate();
 
     // The get should not have done any network requests since the lock file is
     // up to date.
diff --git a/test/get/hosted/get_stress_test.dart b/test/get/hosted/get_stress_test.dart
index 86a8da9..026c0c1 100644
--- a/test/get/hosted/get_stress_test.dart
+++ b/test/get/hosted/get_stress_test.dart
@@ -26,10 +26,10 @@
       'foo': '1.2.3',
       for (var i = 0; i < 20; i++) 'pkg$i': '1.$i.0',
     }).validate();
-
-    await d.appPackagesFile({
-      'foo': '1.2.3',
-      for (var i = 0; i < 20; i++) 'pkg$i': '1.$i.0',
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      for (var i = 0; i < 20; i++)
+        d.packageConfigEntry(name: 'pkg$i', version: '1.$i.0')
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/get_test.dart b/test/get/hosted/get_test.dart
index 30dd4b8..f0270a3 100644
--- a/test/get/hosted/get_test.dart
+++ b/test/get/hosted/get_test.dart
@@ -21,7 +21,9 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
   });
 
   test('URL encodes the package name', () async {
@@ -57,7 +59,9 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server),
+    ]).validate();
   });
 
   group('categorizes dependency types in the lockfile', () {
diff --git a/test/get/hosted/get_transitive_test.dart b/test/get/hosted/get_transitive_test.dart
index 74635bc..0ae18ac 100644
--- a/test/get/hosted/get_transitive_test.dart
+++ b/test/get/hosted/get_transitive_test.dart
@@ -20,6 +20,9 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.2.3', 'bar': '2.0.4'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3', 'bar': '2.0.4'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      d.packageConfigEntry(name: 'bar', version: '2.0.4'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart b/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart
index 0d75f95..585cfba 100644
--- a/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart
+++ b/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart
@@ -24,6 +24,8 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.2.3'}).validate();
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/resolve_constraints_test.dart b/test/get/hosted/resolve_constraints_test.dart
index c9c73d2..466902e 100644
--- a/test/get/hosted/resolve_constraints_test.dart
+++ b/test/get/hosted/resolve_constraints_test.dart
@@ -22,8 +22,10 @@
 
     await d
         .cacheDir({'foo': '1.2.3', 'bar': '2.3.4', 'baz': '2.0.4'}).validate();
-
-    await d.appPackagesFile(
-        {'foo': '1.2.3', 'bar': '2.3.4', 'baz': '2.0.4'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      d.packageConfigEntry(name: 'bar', version: '2.3.4'),
+      d.packageConfigEntry(name: 'baz', version: '2.0.4'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/resolve_with_retracted_package_versions_test.dart b/test/get/hosted/resolve_with_retracted_package_versions_test.dart
index efd3a0a..d9b33a4 100644
--- a/test/get/hosted/resolve_with_retracted_package_versions_test.dart
+++ b/test/get/hosted/resolve_with_retracted_package_versions_test.dart
@@ -23,7 +23,10 @@
     await pubGet();
 
     await d.cacheDir({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
   });
 
   test('Error when the only available package version is retracted', () async {
@@ -53,22 +56,34 @@
 
     await pubGet();
     await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+    ]).validate();
 
     server.retractPackageVersion('bar', '1.1.0');
     await pubUpgrade();
     await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+    ]).validate();
 
     server.serve('bar', '2.0.0');
     await pubUpgrade();
     await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+    ]).validate();
 
     server.serve('bar', '1.2.0');
     await pubUpgrade();
     await d.cacheDir({'foo': '1.0.0', 'bar': '1.2.0'}).validate();
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.2.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.2.0'),
+    ]).validate();
   });
 
   test('Offline versions of pub commands also handle retracted packages',
@@ -102,7 +117,10 @@
     await pubUpgrade(args: ['--offline']);
 
     // We choose bar 1.1.0 since we already have it in pubspec.lock
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+    ]).validate();
 
     // Delete lockfile so that retracted versions are not considered.
     final lockFile = p.join(d.sandbox, appPath, 'pubspec.lock');
@@ -110,7 +128,10 @@
     deleteEntry(lockFile);
 
     await pubGet(args: ['--offline']);
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
   });
 
   test('Allow retracted version when pinned in dependency_overrides', () async {
@@ -130,7 +151,9 @@
     server.retractPackageVersion('foo', '2.0.0');
 
     await pubGet();
-    await d.appPackagesFile({'foo': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+    ]).validate();
   });
 
   test('Prefer retracted version in dependency_overrides over pubspec.lock',
@@ -147,7 +170,9 @@
     server.retractPackageVersion('foo', '3.0.0');
 
     await pubUpgrade();
-    await d.appPackagesFile({'foo': '3.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '3.0.0'),
+    ]).validate();
 
     await d.dir(appPath, [
       d.pubspec({
@@ -158,6 +183,8 @@
     ]).create();
 
     await pubUpgrade();
-    await d.appPackagesFile({'foo': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/stay_locked_if_compatible_test.dart b/test/get/hosted/stay_locked_if_compatible_test.dart
index bb5e63a..df04579 100644
--- a/test/get/hosted/stay_locked_if_compatible_test.dart
+++ b/test/get/hosted/stay_locked_if_compatible_test.dart
@@ -17,8 +17,9 @@
     await d.appDir({'foo': 'any'}).create();
 
     await pubGet();
-
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
 
     server.serve('foo', '1.0.1');
 
@@ -26,6 +27,8 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart b/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart
index dbe6039..c75c435 100644
--- a/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart
+++ b/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart
@@ -19,9 +19,11 @@
     await d.appDir({'foo': 'any'}).create();
 
     await pubGet();
-
-    await d.appPackagesFile(
-        {'foo': '1.0.0', 'bar': '1.0.0', 'baz': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      d.packageConfigEntry(name: 'baz', version: '1.0.0'),
+    ]).validate();
 
     server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'});
     server.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'});
@@ -32,11 +34,11 @@
 
     await pubGet();
 
-    await d.appPackagesFile({
-      'foo': '1.0.0',
-      'bar': '1.0.0',
-      'baz': '1.0.0',
-      'newdep': '2.0.0'
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      d.packageConfigEntry(name: 'baz', version: '1.0.0'),
+      d.packageConfigEntry(name: 'newdep', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/stay_locked_test.dart b/test/get/hosted/stay_locked_test.dart
index 134e8b5..8b819ea 100644
--- a/test/get/hosted/stay_locked_test.dart
+++ b/test/get/hosted/stay_locked_test.dart
@@ -20,8 +20,9 @@
 
     // This should lock the foo dependency to version 1.0.0.
     await pubGet();
-
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
 
     // Delete the .dart_tool/package_config.json file to simulate a new checkout of the application.
     deleteEntry(path.join(d.sandbox, packageConfigFilePath));
@@ -32,6 +33,8 @@
     // This shouldn't upgrade the foo dependency due to the lockfile.
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/unlock_if_incompatible_test.dart b/test/get/hosted/unlock_if_incompatible_test.dart
index 11bf909..007231e 100644
--- a/test/get/hosted/unlock_if_incompatible_test.dart
+++ b/test/get/hosted/unlock_if_incompatible_test.dart
@@ -18,12 +18,16 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
     server.serve('foo', '1.0.1');
     await d.appDir({'foo': '>1.0.0'}).create();
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.1'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.1'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart b/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart
index 1cedc5a..ae6a4e6 100644
--- a/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart
+++ b/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart
@@ -22,12 +22,12 @@
 
     await pubGet();
 
-    await d.appPackagesFile({
-      'foo': '1.0.0',
-      'bar': '1.0.0',
-      'baz': '1.0.0',
-      'qux': '1.0.0'
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      d.packageConfigEntry(name: 'baz', version: '1.0.0'),
+      d.packageConfigEntry(name: 'qux', version: '1.0.0'),
+    ]).validate();
 
     server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'});
     server.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'});
@@ -39,12 +39,12 @@
 
     await pubGet();
 
-    await d.appPackagesFile({
-      'foo': '2.0.0',
-      'bar': '2.0.0',
-      'baz': '2.0.0',
-      'qux': '1.0.0',
-      'newdep': '2.0.0'
-    }).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.0.0'),
+      d.packageConfigEntry(name: 'baz', version: '2.0.0'),
+      d.packageConfigEntry(name: 'qux', version: '1.0.0'),
+      d.packageConfigEntry(name: 'newdep', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/get/hosted/unlock_if_version_doesnt_exist_test.dart b/test/get/hosted/unlock_if_version_doesnt_exist_test.dart
index 7eb4246..e4cc01b 100644
--- a/test/get/hosted/unlock_if_version_doesnt_exist_test.dart
+++ b/test/get/hosted/unlock_if_version_doesnt_exist_test.dart
@@ -17,7 +17,9 @@
 
     await d.appDir({'foo': 'any'}).create();
     await pubGet();
-    await d.appPackagesFile({'foo': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+    ]).validate();
 
     deleteEntry(p.join(d.sandbox, cachePath));
 
@@ -25,6 +27,8 @@
     server.serve('foo', '1.0.1');
 
     await pubGet();
-    await d.appPackagesFile({'foo': '1.0.1'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.1'),
+    ]).validate();
   });
 }
diff --git a/test/get/package_name_test.dart b/test/get/package_name_test.dart
index 46ca386..b1328cc 100644
--- a/test/get/package_name_test.dart
+++ b/test/get/package_name_test.dart
@@ -56,7 +56,8 @@
     await pubGet();
 
     await d.dir(appPath, [
-      d.packagesFile({'foo.bar.baz': '.'}),
+      d.packageConfigFile(
+          [d.packageConfigEntry(name: 'foo.bar.baz', path: '.')])
     ]).validate();
   });
 }
diff --git a/test/get/path/absolute_path_test.dart b/test/get/path/absolute_path_test.dart
index 0fc987a..e1897e9 100644
--- a/test/get/path/absolute_path_test.dart
+++ b/test/get/path/absolute_path_test.dart
@@ -21,6 +21,8 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': path.join(d.sandbox, 'foo')}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: path.join(d.sandbox, 'foo')),
+    ]).validate();
   });
 }
diff --git a/test/get/path/absolute_symlink_test.dart b/test/get/path/absolute_symlink_test.dart
index 1a2d912..83d3433 100644
--- a/test/get/path/absolute_symlink_test.dart
+++ b/test/get/path/absolute_symlink_test.dart
@@ -24,8 +24,8 @@
 
     await pubGet();
 
-    await d.dir(appPath, [
-      d.packagesFile({'myapp': '.', 'foo': fooPath})
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: fooPath),
     ]).validate();
 
     await d.dir('moved').create();
@@ -35,9 +35,9 @@
     renameInSandbox(appPath, path.join('moved', appPath));
 
     await d.dir('moved', [
-      d.dir(appPath, [
-        d.packagesFile({'myapp': '.', 'foo': fooPath})
-      ])
+      d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', path: fooPath),
+      ]),
     ]).validate();
   });
 }
diff --git a/test/get/path/relative_path_test.dart b/test/get/path/relative_path_test.dart
index ff19c6f..3a7fb8f 100644
--- a/test/get/path/relative_path_test.dart
+++ b/test/get/path/relative_path_test.dart
@@ -27,7 +27,9 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '../foo'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+    ]).validate();
   });
 
   test('path is relative to containing pubspec', () async {
@@ -49,8 +51,10 @@
 
     await pubGet();
 
-    await d.appPackagesFile(
-        {'foo': '../relative/foo', 'bar': '../relative/bar'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../relative/foo'),
+      d.packageConfigEntry(name: 'bar', path: '../relative/bar'),
+    ]).validate();
   });
 
   test('path is relative to containing pubspec when using --directory',
@@ -76,9 +80,10 @@
         workingDirectory: d.sandbox,
         output: contains('Changed 2 dependencies in myapp!'));
 
-    await d.appPackagesFile(
-      {'foo': '../relative/foo', 'bar': '../relative/bar'},
-    ).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../relative/foo'),
+      d.packageConfigEntry(name: 'bar', path: '../relative/bar'),
+    ]).validate();
   });
 
   test('relative path preserved in the lockfile', () async {
diff --git a/test/get/path/relative_symlink_test.dart b/test/get/path/relative_symlink_test.dart
index af7185b..9136a34 100644
--- a/test/get/path/relative_symlink_test.dart
+++ b/test/get/path/relative_symlink_test.dart
@@ -28,8 +28,8 @@
 
     await pubGet();
 
-    await d.dir(appPath, [
-      d.packagesFile({'myapp': '.', 'foo': '../foo'})
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
     ]).validate();
 
     await d.dir('moved').create();
@@ -41,8 +41,8 @@
     renameInSandbox(appPath, path.join('moved', appPath));
 
     await d.dir('moved', [
-      d.dir(appPath, [
-        d.packagesFile({'myapp': '.', 'foo': '../foo'})
+      d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', path: '../foo'),
       ])
     ]).validate();
   });
diff --git a/test/get/path/shared_dependency_symlink_test.dart b/test/get/path/shared_dependency_symlink_test.dart
index 46a78c6..d450838 100644
--- a/test/get/path/shared_dependency_symlink_test.dart
+++ b/test/get/path/shared_dependency_symlink_test.dart
@@ -40,13 +40,10 @@
 
     await pubGet();
 
-    await d.dir(appPath, [
-      d.packagesFile({
-        'myapp': '.',
-        'foo': '../foo',
-        'bar': '../bar',
-        'shared': '../shared'
-      })
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+      d.packageConfigEntry(name: 'bar', path: '../bar'),
+      d.packageConfigEntry(name: 'shared', path: '../shared'),
     ]).validate();
   });
 }
diff --git a/test/get/path/shared_dependency_test.dart b/test/get/path/shared_dependency_test.dart
index 7072221..3ef91ae 100644
--- a/test/get/path/shared_dependency_test.dart
+++ b/test/get/path/shared_dependency_test.dart
@@ -35,8 +35,11 @@
 
     await pubGet();
 
-    await d.appPackagesFile(
-        {'foo': '../foo', 'bar': '../bar', 'shared': '../shared'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+      d.packageConfigEntry(name: 'bar', path: '../bar'),
+      d.packageConfigEntry(name: 'shared', path: '../shared'),
+    ]).validate();
   });
 
   test('shared dependency with paths that normalize the same', () async {
@@ -66,7 +69,10 @@
 
     await pubGet();
 
-    await d.appPackagesFile(
-        {'foo': '../foo', 'bar': '../bar', 'shared': '../shared'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+      d.packageConfigEntry(name: 'bar', path: '../bar'),
+      d.packageConfigEntry(name: 'shared', path: '../shared'),
+    ]).validate();
   });
 }
diff --git a/test/get/sdk_constraint_required_test.dart b/test/get/sdk_constraint_required_test.dart
index 1b6fbc5..3f1e5c0 100644
--- a/test/get/sdk_constraint_required_test.dart
+++ b/test/get/sdk_constraint_required_test.dart
@@ -25,8 +25,8 @@
       d.nothing('pubspec.lock'),
       // The "packages" directory should not have been generated.
       d.nothing('packages'),
-      // The ".packages" file should not have been created.
-      d.nothing('.packages'),
+      // The package config file should not have been created.
+      d.nothing('.dart_tool/package_config.json'),
     ]).validate();
   });
 }
diff --git a/test/get/switch_source_test.dart b/test/get/switch_source_test.dart
index ffbf8b4..7e56652 100644
--- a/test/get/switch_source_test.dart
+++ b/test/get/switch_source_test.dart
@@ -21,11 +21,15 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '../foo'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', path: '../foo'),
+    ]).validate();
     await d.appDir({'foo': 'any'}).create();
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+    ]).validate();
   });
 }
diff --git a/test/hosted/offline_test.dart b/test/hosted/offline_test.dart
index 6482656..ca3dc80 100644
--- a/test/hosted/offline_test.dart
+++ b/test/hosted/offline_test.dart
@@ -44,8 +44,10 @@
       }
 
       await pubCommand(command, args: ['--offline'], warning: warning);
-
-      await d.appPackagesFile({'foo': '1.2.3', 'bar': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+        d.packageConfigEntry(name: 'bar', version: '1.2.3'),
+      ]).validate();
     });
 
     test('supports prerelease versions', () async {
@@ -66,7 +68,9 @@
 
       await pubCommand(command, args: ['--offline'], warning: warning);
 
-      await d.appPackagesFile({'foo': '1.2.3-alpha.1'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3-alpha.1'),
+      ]).validate();
     });
 
     test('fails gracefully if a dependency is not cached', () async {
@@ -143,7 +147,9 @@
 
       await pubCommand(command, args: ['--offline']);
 
-      await d.appPackagesFile({'foo': '1.2.3'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.3'),
+      ]).validate();
     });
 
     test('skips invalid cached versions', () async {
@@ -164,7 +170,9 @@
 
       await pubCommand(command, args: ['--offline']);
 
-      await d.appPackagesFile({'foo': '1.2.2'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+      ]).validate();
     });
 
     test('skips invalid locked versions', () async {
@@ -186,7 +194,9 @@
 
       await pubCommand(command, args: ['--offline']);
 
-      await d.appPackagesFile({'foo': '1.2.2'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.2.2'),
+      ]).validate();
     });
   });
 }
diff --git a/test/hosted/remove_removed_dependency_test.dart b/test/hosted/remove_removed_dependency_test.dart
index bb2e091..a0446c0 100644
--- a/test/hosted/remove_removed_dependency_test.dart
+++ b/test/hosted/remove_removed_dependency_test.dart
@@ -17,14 +17,18 @@
       await d.appDir({'foo': 'any', 'bar': 'any'}).create();
 
       await pubCommand(command);
-
-      await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      ]).validate();
 
       await d.appDir({'foo': 'any'}).create();
 
       await pubCommand(command);
 
-      await d.appPackagesFile({'foo': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      ]).validate();
     });
   });
 }
diff --git a/test/hosted/remove_removed_transitive_dependency_test.dart b/test/hosted/remove_removed_transitive_dependency_test.dart
index ac3a452..182ec3f 100644
--- a/test/hosted/remove_removed_transitive_dependency_test.dart
+++ b/test/hosted/remove_removed_transitive_dependency_test.dart
@@ -21,20 +21,21 @@
       await d.appDir({'foo': 'any', 'bar': 'any'}).create();
 
       await pubCommand(command);
-
-      await d.appPackagesFile({
-        'foo': '1.0.0',
-        'bar': '1.0.0',
-        'shared_dep': '1.0.0',
-        'bar_dep': '1.0.0',
-      }).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+        d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'),
+        d.packageConfigEntry(name: 'bar_dep', version: '1.0.0'),
+      ]).validate();
 
       await d.appDir({'foo': 'any'}).create();
 
       await pubCommand(command);
 
-      await d
-          .appPackagesFile({'foo': '1.0.0', 'shared_dep': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+        d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'),
+      ]).validate();
     });
   });
 }
diff --git a/test/must_pub_get_test.dart b/test/must_pub_get_test.dart
index dfc09d7..71d9c16 100644
--- a/test/must_pub_get_test.dart
+++ b/test/must_pub_get_test.dart
@@ -213,7 +213,7 @@
           d.appPubspec({'foo': '1.0.0'})
         ]).create();
 
-        await pubGet();
+        await pubGet(args: ['--legacy-packages-file']);
 
         deleteEntry(p.join(d.sandbox, cachePath));
 
@@ -235,7 +235,7 @@
           })
         ]).create();
 
-        await pubGet();
+        await pubGet(args: ['--legacy-packages-file']);
 
         await createPackagesFile(appPath);
 
@@ -257,7 +257,7 @@
           })
         ]).create();
 
-        await pubGet();
+        await pubGet(args: ['--legacy-packages-file']);
 
         await d.dir(appPath, [
           d.file('.packages', '''
@@ -284,7 +284,7 @@
           })
         ]).create();
 
-        await pubGet();
+        await pubGet(args: ['--legacy-packages-file']);
 
         await createPackagesFile(appPath, dependenciesInSandBox: ['foo']);
 
@@ -452,7 +452,7 @@
   group("doesn't require the user to run pub get first if", () {
     group(
         'the pubspec is older than the lockfile which is older than the '
-        'packages file, even if the contents are wrong', () {
+        'package-config, even if the contents are wrong', () {
       setUp(() async {
         await d.dir(appPath, [
           d.appPubspec({'foo': '1.0.0'})
@@ -461,7 +461,6 @@
         await _touch('pubspec.yaml');
 
         await _touch('pubspec.lock');
-        await _touch('.packages');
         await _touch('.dart_tool/package_config.json');
       });
 
@@ -600,14 +599,11 @@
           File(p.join(d.sandbox, 'myapp/pubspec.yaml')).lastModifiedSync();
       var lockFileModified =
           File(p.join(d.sandbox, 'myapp/pubspec.lock')).lastModifiedSync();
-      var packagesModified =
-          File(p.join(d.sandbox, 'myapp/.packages')).lastModifiedSync();
       var packageConfigModified =
           File(p.join(d.sandbox, 'myapp/.dart_tool/package_config.json'))
               .lastModifiedSync();
 
       expect(!pubspecModified.isAfter(lockFileModified), isTrue);
-      expect(!lockFileModified.isAfter(packagesModified), isTrue);
       expect(!lockFileModified.isAfter(packageConfigModified), isTrue);
     });
   }
diff --git a/test/packages_file_test.dart b/test/packages_file_test.dart
index e7736be..c245a9a 100644
--- a/test/packages_file_test.dart
+++ b/test/packages_file_test.dart
@@ -11,7 +11,7 @@
 
 void main() {
   forBothPubGetAndUpgrade((command) {
-    test('.packages file is created', () async {
+    test('.packages file is created with flag', () async {
       await servePackages()
         ..serve('foo', '1.2.3',
             deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])])
@@ -24,7 +24,7 @@
         d.dir('lib')
       ]).create();
 
-      await pubCommand(command);
+      await pubCommand(command, args: ['--legacy-packages-file']);
 
       await d.dir(appPath, [
         d.packagesFile(
@@ -32,7 +32,7 @@
       ]).validate();
     });
 
-    test('.packages file is overwritten', () async {
+    test('.packages file is overwritten with flag', () async {
       await servePackages()
         ..serve('foo', '1.2.3',
             deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])])
@@ -51,7 +51,7 @@
       await oldFile.create();
       await oldFile.validate(); // Sanity-check that file was created correctly.
 
-      await pubCommand(command);
+      await pubCommand(command, args: ['--legacy-packages-file']);
 
       await d.dir(appPath, [
         d.packagesFile(
@@ -59,24 +59,28 @@
       ]).validate();
     });
 
-    test('.packages file is not created if pub command fails', () async {
+    test('.packages file is not created if pub command fails with flag',
+        () async {
       await d.dir(appPath, [
         d.appPubspec({'foo': '1.2.3'}),
         d.dir('lib')
       ]).create();
 
       await pubCommand(command,
-          args: ['--offline'], error: equalsIgnoringWhitespace("""
+          args: ['--offline', '--legacy-packages-file'],
+          error: equalsIgnoringWhitespace("""
             Because myapp depends on foo any which doesn't exist (could not find
               package foo in cache), version solving failed.
 
             Try again without --offline!
-          """), exitCode: exit_codes.UNAVAILABLE);
+          """),
+          exitCode: exit_codes.UNAVAILABLE);
 
       await d.dir(appPath, [d.nothing('.packages')]).validate();
     });
 
-    test('.packages file has relative path to path dependency', () async {
+    test('.packages file has relative path to path dependency with flag',
+        () async {
       await servePackages()
         ..serve('foo', '1.2.3',
             deps: {'baz': 'any'}, contents: [d.dir('lib', [])])
@@ -100,7 +104,7 @@
         d.dir('lib')
       ]).create();
 
-      await pubCommand(command);
+      await pubCommand(command, args: ['--legacy-packages-file']);
 
       await d.dir(appPath, [
         d.packagesFile({'myapp': '.', 'baz': '../local_baz', 'foo': '1.2.3'}),
diff --git a/test/pub_get_and_upgrade_test.dart b/test/pub_get_and_upgrade_test.dart
index 62004a4..f64f93b 100644
--- a/test/pub_get_and_upgrade_test.dart
+++ b/test/pub_get_and_upgrade_test.dart
@@ -45,7 +45,8 @@
       await pubCommand(command);
 
       await d.dir('myapp', [
-        d.packagesFile({'myapp_name': '.'})
+        d.packageConfigFile(
+            [d.packageConfigEntry(name: 'myapp_name', path: '.')]),
       ]).validate();
     });
 
diff --git a/test/remove/remove_test.dart b/test/remove/remove_test.dart
index e369c85..8c82527 100644
--- a/test/remove/remove_test.dart
+++ b/test/remove/remove_test.dart
@@ -21,7 +21,7 @@
     await pubRemove(args: ['foo']);
 
     await d.cacheDir({}).validate();
-    await d.appPackagesFile({}).validate();
+    await d.appPackageConfigFile([]).validate();
     await d.appDir().validate();
   });
 
@@ -49,7 +49,9 @@
     await pubRemove(args: ['foo']);
 
     await d.cacheDir({'bar': '2.0.0'}).validate();
-    await d.appPackagesFile({'bar': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'bar', version: '2.0.0'),
+    ]).validate();
 
     await d.dir(appPath, [
       d.pubspec({
@@ -113,7 +115,7 @@
     await pubRemove(args: ['foo']);
 
     await d.cacheDir({}).validate();
-    await d.appPackagesFile({}).validate();
+    await d.appPackageConfigFile([]).validate();
 
     await d.dir(appPath, [
       d.pubspec({'name': 'myapp'})
@@ -140,7 +142,10 @@
     await pubRemove(args: ['foo', 'bar', 'baz']);
 
     await d.cacheDir({'jfj': '0.2.1'}).validate();
-    await d.appPackagesFile({'jfj': '0.2.1'}).validate();
+
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'jfj', version: '0.2.1'),
+    ]).validate();
 
     await d.dir(appPath, [
       d.pubspec({
@@ -170,7 +175,10 @@
     await pubGet();
 
     await pubRemove(args: ['foo']);
-    await d.appPackagesFile({'bar': '1.2.3'}).validate();
+
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'bar', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'bar': '1.2.3'}).validate();
   });
 
@@ -188,7 +196,9 @@
     await pubGet();
 
     await pubRemove(args: ['foo']);
-    await d.appPackagesFile({'bar': '1.2.3'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'bar', version: '1.2.3'),
+    ]).validate();
     await d.appDir({'bar': '1.2.3'}).validate();
   });
 
@@ -210,7 +220,9 @@
     await pubGet();
 
     await pubRemove(args: ['foo']);
-    await d.appPackagesFile({'bar': '2.0.1'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'bar', version: '2.0.1'),
+    ]).validate();
     await d.appDir({'bar': '2.0.1'}).validate();
   });
 
diff --git a/test/sdk_test.dart b/test/sdk_test.dart
index 6e50ff0..6165cd5 100644
--- a/test/sdk_test.dart
+++ b/test/sdk_test.dart
@@ -37,13 +37,10 @@
       }).create();
       await pubCommand(command,
           environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});
-
-      await d.dir(appPath, [
-        d.packagesFile({
-          'myapp': '.',
-          'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'),
-          'bar': '1.0.0'
-        })
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(
+            name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
       ]).validate();
     });
 
@@ -54,11 +51,10 @@
       await pubCommand(command,
           environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});
 
-      await d.dir(appPath, [
-        d.packagesFile({
-          'myapp': '.',
-          'baz': p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz')
-        })
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(
+            name: 'baz',
+            path: p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz')),
       ]).validate();
     });
 
@@ -93,10 +89,7 @@
       deleteEntry(p.join(d.sandbox, 'flutter', 'version'));
       await pubCommand(command,
           environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});
-
-      await d.dir(appPath, [
-        d.packagesFile({'myapp': '.'})
-      ]).validate();
+      await d.appPackageConfigFile([]).validate();
     });
 
     group('fails if', () {
@@ -169,13 +162,10 @@
       }).create();
       await pubCommand(command,
           environment: {'FUCHSIA_DART_SDK_ROOT': p.join(d.sandbox, 'fuchsia')});
-
-      await d.dir(appPath, [
-        d.packagesFile({
-          'myapp': '.',
-          'foo': p.join(d.sandbox, 'fuchsia', 'packages', 'foo'),
-          'bar': '1.0.0'
-        })
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(
+            name: 'foo', path: p.join(d.sandbox, 'fuchsia', 'packages', 'foo')),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
       ]).validate();
     });
   });
diff --git a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt b/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt
index 1d3a5f5..fc69b03 100644
--- a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt
+++ b/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt
@@ -81,16 +81,6 @@
 [E]    |   version: "1.0.0"
 [E]    | sdks:
 [E]    |   dart: ">=0.1.2 <1.0.0"
-[E] IO  : Writing $N characters to text file .packages.
-[E] FINE: Contents:
-[E]    | # This file is deprecated. Tools should instead consume 
-[E]    | # `.dart_tool/package_config.json`.
-[E]    | # 
-[E]    | # For more info see: https://dart.dev/go/dot-packages-deprecation
-[E]    | # 
-[E]    | # Generated by pub on $TIME
-[E]    | foo:file://$SANDBOX/cache/hosted/localhost%2558$PORT/foo-1.0.0/lib/
-[E]    | myapp:lib/
 [E] IO  : Writing $N characters to text file .dart_tool/package_config.json.
 [E] FINE: Contents:
 [E]    | {
@@ -230,16 +220,6 @@
    | sdks:
    |   dart: ">=0.1.2 <1.0.0"
 MSG : Changed 1 dependency!
-IO  : Writing $N characters to text file .packages.
-FINE: Contents:
-   | # This file is deprecated. Tools should instead consume 
-   | # `.dart_tool/package_config.json`.
-   | # 
-   | # For more info see: https://dart.dev/go/dot-packages-deprecation
-   | # 
-   | # Generated by pub on $TIME
-   | foo:file://$SANDBOX/cache/hosted/localhost%2558$PORT/foo-1.0.0/lib/
-   | myapp:lib/
 IO  : Writing $N characters to text file .dart_tool/package_config.json.
 FINE: Contents:
    | {
diff --git a/test/testdata/goldens/help_test/pub add --help.txt b/test/testdata/goldens/help_test/pub add --help.txt
index 2a37c21..3d1f429 100644
--- a/test/testdata/goldens/help_test/pub add --help.txt
+++ b/test/testdata/goldens/help_test/pub add --help.txt
@@ -5,20 +5,22 @@
 Add dependencies to pubspec.yaml.
 
 Usage: pub add <package>[:<constraint>] [<package2>[:<constraint2>]...] [options]
--h, --help               Print this usage information.
--d, --dev                Adds to the development dependencies instead.
-    --git-url            Git URL of the package
-    --git-ref            Git branch or commit to be retrieved
-    --git-path           Path of git package in repository
-    --hosted-url         URL of package host server
-    --path               Add package from local path
-    --sdk=<[flutter]>    add package from SDK source
-                         [flutter]
-    --[no-]offline       Use cached packages instead of accessing the network.
--n, --dry-run            Report what dependencies would change but don't change
-                         any.
-    --[no-]precompile    Build executables in immediate dependencies.
--C, --directory=<dir>    Run this in the directory <dir>.
+-h, --help                    Print this usage information.
+-d, --dev                     Adds to the development dependencies instead.
+    --git-url                 Git URL of the package
+    --git-ref                 Git branch or commit to be retrieved
+    --git-path                Path of git package in repository
+    --hosted-url              URL of package host server
+    --path                    Add package from local path
+    --sdk=<[flutter]>         add package from SDK source
+                              [flutter]
+    --[no-]offline            Use cached packages instead of accessing the
+                              network.
+-n, --dry-run                 Report what dependencies would change but don't
+                              change any.
+    --[no-]precompile         Build executables in immediate dependencies.
+-C, --directory=<dir>         Run this in the directory <dir>.
+    --legacy-packages-file    Generate the legacy ".packages" file
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-add for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub downgrade --help.txt b/test/testdata/goldens/help_test/pub downgrade --help.txt
index 4497da2..ddf71e7 100644
--- a/test/testdata/goldens/help_test/pub downgrade --help.txt
+++ b/test/testdata/goldens/help_test/pub downgrade --help.txt
@@ -7,11 +7,13 @@
 
 
 Usage: pub downgrade [dependencies...]
--h, --help               Print this usage information.
-    --[no-]offline       Use cached packages instead of accessing the network.
--n, --dry-run            Report what dependencies would change but don't change
-                         any.
--C, --directory=<dir>    Run this in the directory<dir>.
+-h, --help                    Print this usage information.
+    --[no-]offline            Use cached packages instead of accessing the
+                              network.
+-n, --dry-run                 Report what dependencies would change but don't
+                              change any.
+-C, --directory=<dir>         Run this in the directory<dir>.
+    --legacy-packages-file    Generate the legacy ".packages" file
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-downgrade for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub get --help.txt b/test/testdata/goldens/help_test/pub get --help.txt
index 74648a2..104f69c 100644
--- a/test/testdata/goldens/help_test/pub get --help.txt
+++ b/test/testdata/goldens/help_test/pub get --help.txt
@@ -5,12 +5,14 @@
 Get the current package's dependencies.
 
 Usage: pub get <subcommand> [arguments...]
--h, --help               Print this usage information.
-    --[no-]offline       Use cached packages instead of accessing the network.
--n, --dry-run            Report what dependencies would change but don't change
-                         any.
-    --[no-]precompile    Build executables in immediate dependencies.
--C, --directory=<dir>    Run this in the directory<dir>.
+-h, --help                    Print this usage information.
+    --[no-]offline            Use cached packages instead of accessing the
+                              network.
+-n, --dry-run                 Report what dependencies would change but don't
+                              change any.
+    --[no-]precompile         Build executables in immediate dependencies.
+    --legacy-packages-file    Generate the legacy ".packages" file
+-C, --directory=<dir>         Run this in the directory<dir>.
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-get for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub remove --help.txt b/test/testdata/goldens/help_test/pub remove --help.txt
index 7d14ed0..b82f9b6 100644
--- a/test/testdata/goldens/help_test/pub remove --help.txt
+++ b/test/testdata/goldens/help_test/pub remove --help.txt
@@ -5,12 +5,14 @@
 Removes a dependency from the current package.
 
 Usage: pub remove <package>
--h, --help               Print this usage information.
-    --[no-]offline       Use cached packages instead of accessing the network.
--n, --dry-run            Report what dependencies would change but don't change
-                         any.
-    --[no-]precompile    Precompile executables in immediate dependencies.
--C, --directory=<dir>    Run this in the directory<dir>.
+-h, --help                    Print this usage information.
+    --[no-]offline            Use cached packages instead of accessing the
+                              network.
+-n, --dry-run                 Report what dependencies would change but don't
+                              change any.
+    --[no-]precompile         Precompile executables in immediate dependencies.
+-C, --directory=<dir>         Run this in the directory<dir>.
+    --legacy-packages-file    Generate the legacy ".packages" file
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-remove for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub upgrade --help.txt b/test/testdata/goldens/help_test/pub upgrade --help.txt
index d1a29b9..c787951 100644
--- a/test/testdata/goldens/help_test/pub upgrade --help.txt
+++ b/test/testdata/goldens/help_test/pub upgrade --help.txt
@@ -5,16 +5,18 @@
 Upgrade the current package's dependencies to latest versions.
 
 Usage: pub upgrade [dependencies...]
--h, --help               Print this usage information.
-    --[no-]offline       Use cached packages instead of accessing the network.
--n, --dry-run            Report what dependencies would change but don't change
-                         any.
-    --[no-]precompile    Precompile executables in immediate dependencies.
-    --null-safety        Upgrade constraints in pubspec.yaml to null-safety
-                         versions
-    --major-versions     Upgrades packages to their latest resolvable versions,
-                         and updates pubspec.yaml.
--C, --directory=<dir>    Run this in the directory<dir>.
+-h, --help                    Print this usage information.
+    --[no-]offline            Use cached packages instead of accessing the
+                              network.
+-n, --dry-run                 Report what dependencies would change but don't
+                              change any.
+    --[no-]precompile         Precompile executables in immediate dependencies.
+    --null-safety             Upgrade constraints in pubspec.yaml to null-safety
+                              versions
+    --legacy-packages-file    Generate the legacy ".packages" file
+    --major-versions          Upgrades packages to their latest resolvable
+                              versions, and updates pubspec.yaml.
+-C, --directory=<dir>         Run this in the directory<dir>.
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-upgrade for detailed documentation.
diff --git a/test/unknown_source_test.dart b/test/unknown_source_test.dart
index fc53621..37591d0 100644
--- a/test/unknown_source_test.dart
+++ b/test/unknown_source_test.dart
@@ -72,7 +72,9 @@
       await pubCommand(command);
 
       // Should upgrade to the new one.
-      await d.appPackagesFile({'foo': '../foo'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', path: '../foo'),
+      ]).validate();
     });
   });
 }
diff --git a/test/upgrade/hosted/unlock_if_necessary_test.dart b/test/upgrade/hosted/unlock_if_necessary_test.dart
index c285e66..2707100 100644
--- a/test/upgrade/hosted/unlock_if_necessary_test.dart
+++ b/test/upgrade/hosted/unlock_if_necessary_test.dart
@@ -20,13 +20,19 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0', 'foo_dep': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'foo_dep', version: '1.0.0'),
+    ]).validate();
 
     server.serve('foo', '2.0.0', deps: {'foo_dep': '>1.0.0'});
     server.serve('foo_dep', '2.0.0');
 
     await pubUpgrade(args: ['foo']);
 
-    await d.appPackagesFile({'foo': '2.0.0', 'foo_dep': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+      d.packageConfigEntry(name: 'foo_dep', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/upgrade/hosted/unlock_single_package_test.dart b/test/upgrade/hosted/unlock_single_package_test.dart
index bc78a3d..e443a6a 100644
--- a/test/upgrade/hosted/unlock_single_package_test.dart
+++ b/test/upgrade/hosted/unlock_single_package_test.dart
@@ -18,7 +18,10 @@
 
     await pubGet();
 
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
 
     server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'});
     server.serve('bar', '2.0.0');
@@ -26,16 +29,23 @@
     // This can't upgrade 'bar'
     await pubUpgrade(args: ['bar']);
 
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
-
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+    ]).validate();
     // Introducing foo and bar 1.1.0, to show that only 'bar' will be upgraded
     server.serve('foo', '1.1.0', deps: {'bar': '<2.0.0'});
     server.serve('bar', '1.1.0');
 
     await pubUpgrade(args: ['bar']);
-    await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate();
-
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.1.0'),
+    ]).validate();
     await pubUpgrade();
-    await d.appPackagesFile({'foo': '2.0.0', 'bar': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/upgrade/hosted/upgrade_removed_constraints_test.dart b/test/upgrade/hosted/upgrade_removed_constraints_test.dart
index 248ac90..cf72c07 100644
--- a/test/upgrade/hosted/upgrade_removed_constraints_test.dart
+++ b/test/upgrade/hosted/upgrade_removed_constraints_test.dart
@@ -19,13 +19,19 @@
 
     await pubUpgrade();
 
-    await d.appPackagesFile(
-        {'foo': '1.0.0', 'bar': '1.0.0', 'shared_dep': '1.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'),
+    ]).validate();
 
     await d.appDir({'foo': 'any'}).create();
 
     await pubUpgrade();
 
-    await d.appPackagesFile({'foo': '1.0.0', 'shared_dep': '2.0.0'}).validate();
+    await d.appPackageConfigFile([
+      d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+      d.packageConfigEntry(name: 'shared_dep', version: '2.0.0'),
+    ]).validate();
   });
 }
diff --git a/test/upgrade/upgrade_major_versions_test.dart b/test/upgrade/upgrade_major_versions_test.dart
index 932ca17..c5f0994 100644
--- a/test/upgrade/upgrade_major_versions_test.dart
+++ b/test/upgrade/upgrade_major_versions_test.dart
@@ -41,12 +41,11 @@
         'bar': '^0.2.0',
         'baz': '^1.0.0',
       }).validate();
-
-      await d.appPackagesFile({
-        'foo': '2.0.0',
-        'bar': '0.2.0',
-        'baz': '1.0.1',
-      }).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '0.2.0'),
+        d.packageConfigEntry(name: 'baz', version: '1.0.1'),
+      ]).validate();
     });
 
     test('bumps dev_dependency constraints and shows summary report', () async {
@@ -92,11 +91,11 @@
         }),
       ]).validate();
 
-      await d.appPackagesFile({
-        'foo': '2.0.0',
-        'bar': '0.2.0',
-        'baz': '1.0.1',
-      }).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '0.2.0'),
+        d.packageConfigEntry(name: 'baz', version: '1.0.1'),
+      ]).validate();
     });
 
     test('upgrades only the selected package', () async {
@@ -128,7 +127,10 @@
         'bar': '^0.1.0',
       }).validate();
 
-      await d.appPackagesFile({'foo': '2.0.0', 'bar': '0.1.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '2.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '0.1.0'),
+      ]).validate();
     });
 
     test('chooses the latest version where possible', () async {
@@ -159,7 +161,9 @@
         d.file('pubspec.lock', contains('3.0.0'))
       ]).validate();
 
-      await d.appPackagesFile({'foo': '3.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '3.0.0'),
+      ]).validate();
     });
 
     test('overridden dependencies - no resolution', () async {
@@ -211,7 +215,10 @@
         })
       ]).validate();
 
-      await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '1.0.0'),
+      ]).validate();
     });
 
     test('upgrade should not downgrade any versions', () async {
@@ -249,10 +256,10 @@
         'bar': '^4.0.0',
       }).validate();
 
-      await d.appPackagesFile({
-        'foo': '1.0.0',
-        'bar': '4.0.0',
-      }).validate();
+      await d.appPackageConfigFile([
+        d.packageConfigEntry(name: 'foo', version: '1.0.0'),
+        d.packageConfigEntry(name: 'bar', version: '4.0.0'),
+      ]).validate();
     });
   });
 }