Remove all support for legacy .packages file (#3507)

diff --git a/lib/src/command/add.dart b/lib/src/command/add.dart
index d4c98ef..78b1e5d 100644
--- a/lib/src/command/add.dart
+++ b/lib/src/command/add.dart
@@ -94,8 +94,6 @@
         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
@@ -164,11 +162,12 @@
 
       await Entrypoint.inMemory(newRoot, cache,
               solveResult: solveResult, lockFile: entrypoint.lockFile)
-          .acquireDependencies(SolveType.get,
-              dryRun: true,
-              precompile: argResults['precompile'],
-              analytics: analytics,
-              generateDotPackages: false);
+          .acquireDependencies(
+        SolveType.get,
+        dryRun: true,
+        precompile: argResults['precompile'],
+        analytics: analytics,
+      );
     } else {
       /// Update the `pubspec.yaml` before calling [acquireDependencies] to
       /// ensure that the modification timestamp on `pubspec.lock` and
@@ -183,7 +182,6 @@
         SolveType.get,
         precompile: argResults['precompile'],
         analytics: analytics,
-        generateDotPackages: argResults['legacy-packages-file'],
       );
 
       if (argResults['example'] && entrypoint.example != null) {
@@ -192,7 +190,6 @@
           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 fce5ef3..274ab48 100644
--- a/lib/src/command/downgrade.dart
+++ b/lib/src/command/downgrade.dart
@@ -42,8 +42,6 @@
 
     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
@@ -59,7 +57,6 @@
       unlock: argResults.rest,
       dryRun: dryRun,
       analytics: analytics,
-      generateDotPackages: argResults['legacy-packages-file'],
     );
     var example = entrypoint.example;
     if (argResults['example'] && example != null) {
@@ -69,7 +66,6 @@
         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 7b8906c..0be67a0 100644
--- a/lib/src/command/get.dart
+++ b/lib/src/command/get.dart
@@ -33,9 +33,6 @@
 
     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).',
@@ -56,7 +53,6 @@
       SolveType.get,
       dryRun: argResults['dry-run'],
       precompile: argResults['precompile'],
-      generateDotPackages: argResults['legacy-packages-file'],
       analytics: analytics,
     );
 
@@ -66,7 +62,6 @@
         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 82a9547..7e7b17d 100644
--- a/lib/src/command/remove.dart
+++ b/lib/src/command/remove.dart
@@ -50,9 +50,6 @@
 
     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,11 +66,12 @@
       final newRoot = Package.inMemory(newPubspec);
 
       await Entrypoint.inMemory(newRoot, cache, lockFile: entrypoint.lockFile)
-          .acquireDependencies(SolveType.get,
-              precompile: argResults['precompile'],
-              dryRun: true,
-              analytics: null,
-              generateDotPackages: false);
+          .acquireDependencies(
+        SolveType.get,
+        precompile: argResults['precompile'],
+        dryRun: true,
+        analytics: null,
+      );
     } else {
       /// Update the pubspec.
       _writeRemovalToPubspec(packages);
@@ -85,7 +83,6 @@
         SolveType.get,
         precompile: argResults['precompile'],
         analytics: analytics,
-        generateDotPackages: argResults['legacy-packages-file'],
       );
 
       var example = entrypoint.example;
@@ -95,7 +92,6 @@
           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 d6043c3..25feb70 100644
--- a/lib/src/command/upgrade.dart
+++ b/lib/src/command/upgrade.dart
@@ -56,9 +56,6 @@
 
     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, '
@@ -83,8 +80,6 @@
 
   bool get _precompile => argResults['precompile'];
 
-  bool get _packagesFile => argResults['legacy-packages-file'];
-
   bool get _upgradeNullSafety =>
       argResults['nullsafety'] || argResults['null-safety'];
 
@@ -131,7 +126,6 @@
       dryRun: _dryRun,
       precompile: _precompile,
       onlyReportSuccessOrFailure: onlySummary,
-      generateDotPackages: _packagesFile,
       analytics: analytics,
     );
     _showOfflineWarning();
@@ -243,7 +237,6 @@
         dryRun: true,
         precompile: _precompile,
         analytics: null, // No analytics for dry-run
-        generateDotPackages: false,
       );
     } else {
       if (changes.isNotEmpty) {
@@ -256,7 +249,6 @@
         SolveType.get,
         precompile: _precompile,
         analytics: analytics,
-        generateDotPackages: argResults['legacy-packages-file'],
       );
     }
 
@@ -341,7 +333,6 @@
         dryRun: true,
         precompile: _precompile,
         analytics: null,
-        generateDotPackages: false,
       );
     } else {
       if (changes.isNotEmpty) {
@@ -354,7 +345,6 @@
         SolveType.upgrade,
         precompile: _precompile,
         analytics: analytics,
-        generateDotPackages: argResults['legacy-packages-file'],
       );
     }
 
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart
index 3a51b2f..eb643fe 100644
--- a/lib/src/entrypoint.dart
+++ b/lib/src/entrypoint.dart
@@ -27,7 +27,6 @@
 import 'package_config.dart' show PackageConfig;
 import 'package_graph.dart';
 import 'package_name.dart';
-import 'packages_file.dart' as packages_file;
 import 'pub_embeddable_command.dart';
 import 'pubspec.dart';
 import 'sdk.dart';
@@ -225,25 +224,18 @@
   Entrypoint? _example;
 
   /// Writes .packages and .dart_tool/package_config.json
-  Future<void> writePackagesFiles({bool generateDotPackages = false}) async {
+  Future<void> writePackageConfigFile() async {
     final entrypointName = isGlobal ? null : root.name;
-    if (generateDotPackages) {
-      writeTextFile(
-          packagesFile,
-          lockFile.packagesFile(cache,
-              entrypoint: entrypointName,
-              relativeFrom: isGlobal ? null : root.dir));
-    } else {
-      tryDeleteEntry(packagesFile);
-    }
     ensureDir(p.dirname(packageConfigFile));
     writeTextFile(
-        packageConfigFile,
-        await lockFile.packageConfigFile(cache,
-            entrypoint: entrypointName,
-            entrypointSdkConstraint:
-                root.pubspec.sdkConstraints[sdk.identifier],
-            relativeFrom: isGlobal ? null : root.dir));
+      packageConfigFile,
+      await lockFile.packageConfigFile(
+        cache,
+        entrypoint: entrypointName,
+        entrypointSdkConstraint: root.pubspec.sdkConstraints[sdk.identifier],
+        relativeFrom: isGlobal ? null : root.dir,
+      ),
+    );
   }
 
   /// Gets all dependencies of the [root] package.
@@ -273,7 +265,6 @@
     Iterable<String>? unlock,
     bool dryRun = false,
     bool precompile = false,
-    required bool generateDotPackages,
     required PubAnalytics? analytics,
     bool onlyReportSuccessOrFailure = false,
   }) async {
@@ -347,7 +338,7 @@
       /// have to reload and reparse all the pubspecs.
       _packageGraph = PackageGraph.fromSolveResult(this, result);
 
-      await writePackagesFiles(generateDotPackages: generateDotPackages);
+      await writePackageConfigFile();
 
       try {
         if (precompile) {
@@ -568,16 +559,6 @@
       }
     }
 
-    if (fileExists(packagesFile)) {
-      var packagesModified = File(packagesFile).lastModifiedSync();
-      if (packagesModified.isBefore(lockFileModified)) {
-        _checkPackagesFileUpToDate();
-        touch(packagesFile);
-      } else if (touchedLockFile) {
-        touch(packagesFile);
-      }
-    }
-
     var packageConfigModified = File(packageConfigFile).lastModifiedSync();
     if (packageConfigModified.isBefore(lockFileModified) ||
         hasPathDependencies) {
@@ -731,39 +712,6 @@
     });
   }
 
-  /// Checks whether or not the `.packages` file is out of date with respect
-  /// to the [lockfile].
-  ///
-  /// This will throw a [DataError] if [lockfile] contains dependencies that
-  /// are not in the `.packages` or that don't match what's in there.
-  void _checkPackagesFileUpToDate() {
-    void outOfDate() {
-      dataError('The $lockFilePath file has changed since the .packages file '
-          'was generated, please run "$topLevelProgram pub get" again.');
-    }
-
-    var packages = packages_file.parse(
-        File(packagesFile).readAsBytesSync(), p.toUri(packagesFile));
-
-    final packagePathsMapping = <String, String>{};
-    for (final package in packages.keys) {
-      final packageUri = packages[package]!;
-
-      // Pub only generates "file:" and relative URIs.
-      if (packageUri.scheme != 'file' && packageUri.scheme.isNotEmpty) {
-        outOfDate();
-      }
-
-      // Get the dirname of the .packages path, since it's pointing to lib/.
-      final packagePath = p.dirname(p.join(root.dir, p.fromUri(packageUri)));
-      packagePathsMapping[package] = packagePath;
-    }
-
-    if (!_isPackagePathsMappingUpToDateWithLockfile(packagePathsMapping)) {
-      outOfDate();
-    }
-  }
-
   /// Checks whether or not the `.dart_tool/package_config.json` file is
   /// out of date with respect to the lockfile.
   ///
diff --git a/lib/src/executable.dart b/lib/src/executable.dart
index 3f8f6a9..5d8ea8b 100644
--- a/lib/src/executable.dart
+++ b/lib/src/executable.dart
@@ -308,7 +308,6 @@
         () => 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 8bfe7cf..366dcd2 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -162,7 +162,6 @@
     await entrypoint.acquireDependencies(
       SolveType.get,
       analytics: analytics,
-      generateDotPackages: false,
     );
     var name = entrypoint.root.name;
     _describeActive(name, cache);
@@ -253,7 +252,7 @@
         solveResult: result,
       );
 
-      await entrypoint.writePackagesFiles();
+      await entrypoint.writePackageConfigFile();
 
       await entrypoint.precompileExecutables();
 
diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart
index 215ab92..46be2bf 100644
--- a/lib/src/lock_file.dart
+++ b/lib/src/lock_file.dart
@@ -14,7 +14,6 @@
 import 'language_version.dart';
 import 'package_config.dart';
 import 'package_name.dart';
-import 'packages_file.dart' as packages_file;
 import 'sdk.dart' show sdk;
 import 'system_cache.dart';
 import 'utils.dart';
@@ -214,41 +213,6 @@
         _devDependencies, _overriddenDependencies);
   }
 
-  /// Returns the contents of the `.packages` file generated from this lockfile.
-  ///
-  /// If [entrypoint] is passed, a relative entry is added for its "lib/"
-  /// directory.
-  String packagesFile(
-    SystemCache cache, {
-    String? entrypoint,
-    String? relativeFrom,
-  }) {
-    var header = '''
-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 ${DateTime.now()}.''';
-
-    var map = Map<String, Uri>.fromIterable(ordered<String>(packages.keys),
-        value: (name) {
-      var id = packages[name]!;
-      return p.toUri(
-        p.join(
-          cache.getDirectory(id, relativeFrom: relativeFrom),
-          'lib',
-        ),
-      );
-    });
-
-    if (entrypoint != null) map[entrypoint] = Uri.parse('lib/');
-
-    var text = StringBuffer();
-    packages_file.write(text, map, comment: header);
-    return text.toString();
-  }
-
   /// Returns the contents of the `.dart_tool/package_config` file generated
   /// from this lockfile.
   ///
diff --git a/lib/src/packages_file.dart b/lib/src/packages_file.dart
deleted file mode 100644
index d5c7989..0000000
--- a/lib/src/packages_file.dart
+++ /dev/null
@@ -1,487 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// 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.
-
-// ignore_for_file: prefer_single_quotes
-
-// This code is copied from an older version of package:package_config - and
-// kept here until we completely abandon the old .packages file.
-// See: https://github.com/dart-lang/package_config/blob/04b9abec2627dfaf9b7ec39c31a3b03f06ed9be7/lib/packages_file.dart
-
-/// Parses a `.packages` file into a map from package name to base URI.
-///
-/// The [source] is the byte content of a `.packages` file, assumed to be
-/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII,
-/// so Latin-1 or Windows-1252 encoding will also work fine.
-///
-/// If the file content is available as a string, its [String.codeUnits] can
-/// be used as the `source` argument of this function.
-///
-/// The [baseLocation] is used as a base URI to resolve all relative
-/// URI references against.
-/// If the content was read from a file, `baseLocation` should be the
-/// location of that file.
-///
-/// If [allowDefaultPackage] is set to true, an entry with an empty package name
-/// is accepted. This entry does not correspond to a package, but instead
-/// represents a *default package* which non-package libraries may be considered
-/// part of in some cases. The value of that entry must be a valid package name.
-///
-/// Returns a simple mapping from package name to package location.
-/// If default package is allowed, the map maps the empty string to the default package's name.
-Map<String, Uri> parse(List<int> source, Uri baseLocation,
-    {bool allowDefaultPackage = false}) {
-  var index = 0;
-  var result = <String, Uri>{};
-  while (index < source.length) {
-    var isComment = false;
-    var start = index;
-    var separatorIndex = -1;
-    var end = source.length;
-    var char = source[index++];
-    if (char == $cr || char == $lf) {
-      continue;
-    }
-    if (char == $colon) {
-      if (!allowDefaultPackage) {
-        throw FormatException("Missing package name", source, index - 1);
-      }
-      separatorIndex = index - 1;
-    }
-    isComment = char == $hash;
-    while (index < source.length) {
-      char = source[index++];
-      if (char == $colon && separatorIndex < 0) {
-        separatorIndex = index - 1;
-      } else if (char == $cr || char == $lf) {
-        end = index - 1;
-        break;
-      }
-    }
-    if (isComment) continue;
-    if (separatorIndex < 0) {
-      throw FormatException("No ':' on line", source, index - 1);
-    }
-    var packageName = String.fromCharCodes(source, start, separatorIndex);
-    if (packageName.isEmpty
-        ? !allowDefaultPackage
-        : !isValidPackageName(packageName)) {
-      throw FormatException("Not a valid package name", packageName, 0);
-    }
-    var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
-    Uri packageLocation;
-    if (packageName.isEmpty) {
-      if (!isValidPackageName(packageValue)) {
-        throw FormatException(
-            "Default package entry value is not a valid package name");
-      }
-      packageLocation = Uri(path: packageValue);
-    } else {
-      packageLocation = baseLocation.resolve(packageValue);
-      if (!packageLocation.path.endsWith('/')) {
-        packageLocation =
-            packageLocation.replace(path: "${packageLocation.path}/");
-      }
-    }
-    if (result.containsKey(packageName)) {
-      if (packageName.isEmpty) {
-        throw FormatException(
-            "More than one default package entry", source, start);
-      }
-      throw FormatException("Same package name occured twice", source, start);
-    }
-    result[packageName] = packageLocation;
-  }
-  return result;
-}
-
-/// Writes the mapping to a [StringSink].
-///
-/// If [comment] is provided, the output will contain this comment
-/// with `# ` in front of each line.
-/// Lines are defined as ending in line feed (`'\n'`). If the final
-/// line of the comment doesn't end in a line feed, one will be added.
-///
-/// If [baseUri] is provided, package locations will be made relative
-/// to the base URI, if possible, before writing.
-///
-/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an
-/// empty string mapping to the _default package name_.
-///
-/// All the keys of [packageMapping] must be valid package names,
-/// and the values must be URIs that do not have the `package:` scheme.
-void write(StringSink output, Map<String, Uri> packageMapping,
-    {Uri? baseUri, String? comment, bool allowDefaultPackage = false}) {
-  ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage');
-
-  if (baseUri != null && !baseUri.isAbsolute) {
-    throw ArgumentError.value(baseUri, "baseUri", "Must be absolute");
-  }
-
-  if (comment != null) {
-    var lines = comment.split('\n');
-    if (lines.last.isEmpty) lines.removeLast();
-    for (var commentLine in lines) {
-      output.write('# ');
-      output.writeln(commentLine);
-    }
-  } else {
-    output.write("# generated by package:package_config at ");
-    output.write(DateTime.now());
-    output.writeln();
-  }
-
-  packageMapping.forEach((String packageName, Uri uri) {
-    // If [packageName] is empty then [uri] is the _default package name_.
-    if (allowDefaultPackage && packageName.isEmpty) {
-      final defaultPackageName = uri.toString();
-      if (!isValidPackageName(defaultPackageName)) {
-        throw ArgumentError.value(
-          defaultPackageName,
-          'defaultPackageName',
-          '"$defaultPackageName" is not a valid package name',
-        );
-      }
-      output.write(':');
-      output.write(defaultPackageName);
-      output.writeln();
-      return;
-    }
-    // Validate packageName.
-    if (!isValidPackageName(packageName)) {
-      throw ArgumentError('"$packageName" is not a valid package name');
-    }
-    if (uri.scheme == "package") {
-      throw ArgumentError.value(
-          "Package location must not be a package: URI", uri.toString());
-    }
-    output.write(packageName);
-    output.write(':');
-    // If baseUri provided, make uri relative.
-    if (baseUri != null) {
-      uri = _relativize(uri, baseUri);
-    }
-    if (!uri.path.endsWith('/')) {
-      uri = uri.replace(path: '${uri.path}/');
-    }
-    output.write(uri);
-    output.writeln();
-  });
-}
-
-// All ASCII characters that are valid in a package name, with space
-// for all the invalid ones (including space).
-const String _validPackageNameCharacters =
-    r"                                 !  $ &'()*+,-. 0123456789 ; =  "
-    r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ abcdefghijklmnopqrstuvwxyz   ~ ";
-
-/// Tests whether something is a valid Dart package name.
-bool isValidPackageName(String string) {
-  return checkPackageName(string) < 0;
-}
-
-/// Check if a string is a valid package name.
-///
-/// Valid package names contain only characters in [_validPackageNameCharacters]
-/// and must contain at least one non-'.' character.
-///
-/// Returns `-1` if the string is valid.
-/// Otherwise returns the index of the first invalid character,
-/// or `string.length` if the string contains no non-'.' character.
-int checkPackageName(String string) {
-  // Becomes non-zero if any non-'.' character is encountered.
-  var nonDot = 0;
-  for (var i = 0; i < string.length; i++) {
-    var c = string.codeUnitAt(i);
-    if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) {
-      return i;
-    }
-    nonDot += c ^ $dot;
-  }
-  if (nonDot == 0) return string.length;
-  return -1;
-}
-
-/// Validate that a [Uri] is a valid `package:` URI.
-///
-/// Used to validate user input.
-///
-/// Returns the package name extracted from the package URI,
-/// which is the path segment between `package:` and the first `/`.
-String checkValidPackageUri(Uri packageUri, String name) {
-  if (packageUri.scheme != "package") {
-    throw PackageConfigArgumentError(packageUri, name, "Not a package: URI");
-  }
-  if (packageUri.hasAuthority) {
-    throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a host part");
-  }
-  if (packageUri.hasQuery) {
-    // A query makes no sense if resolved to a file: URI.
-    throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a query part");
-  }
-  if (packageUri.hasFragment) {
-    // We could leave the fragment after the URL when resolving,
-    // but it would be odd if "package:foo/foo.dart#1" and
-    // "package:foo/foo.dart#2" were considered different libraries.
-    // Keep the syntax open in case we ever get multiple libraries in one file.
-    throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a fragment part");
-  }
-  if (packageUri.path.startsWith('/')) {
-    throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not start with a '/'");
-  }
-  var firstSlash = packageUri.path.indexOf('/');
-  if (firstSlash == -1) {
-    throw PackageConfigArgumentError(packageUri, name,
-        "Package URIs must start with the package name followed by a '/'");
-  }
-  var packageName = packageUri.path.substring(0, firstSlash);
-  var badIndex = checkPackageName(packageName);
-  if (badIndex >= 0) {
-    if (packageName.isEmpty) {
-      throw PackageConfigArgumentError(
-          packageUri, name, "Package names mus be non-empty");
-    }
-    if (badIndex == packageName.length) {
-      throw PackageConfigArgumentError(packageUri, name,
-          "Package names must contain at least one non-'.' character");
-    }
-    assert(badIndex < packageName.length);
-    var badCharCode = packageName.codeUnitAt(badIndex);
-    var badChar = "U+${badCharCode.toRadixString(16).padLeft(4, '0')}";
-    if (badCharCode >= 0x20 && badCharCode <= 0x7e) {
-      // Printable character.
-      badChar = "'${packageName[badIndex]}' ($badChar)";
-    }
-    throw PackageConfigArgumentError(
-        packageUri, name, "Package names must not contain $badChar");
-  }
-  return packageName;
-}
-
-/// Checks whether URI is just an absolute directory.
-///
-/// * It must have a scheme.
-/// * It must not have a query or fragment.
-/// * The path must end with `/`.
-bool isAbsoluteDirectoryUri(Uri uri) {
-  if (uri.hasQuery) return false;
-  if (uri.hasFragment) return false;
-  if (!uri.hasScheme) return false;
-  var path = uri.path;
-  if (!path.endsWith("/")) return false;
-  return true;
-}
-
-/// Whether the former URI is a prefix of the latter.
-bool isUriPrefix(Uri prefix, Uri path) {
-  assert(!prefix.hasFragment);
-  assert(!prefix.hasQuery);
-  assert(!path.hasQuery);
-  assert(!path.hasFragment);
-  assert(prefix.path.endsWith('/'));
-  return path.toString().startsWith(prefix.toString());
-}
-
-/// Finds the first non-JSON-whitespace character in a file.
-///
-/// Used to heuristically detect whether a file is a JSON file or an .ini file.
-int firstNonWhitespaceChar(List<int> bytes) {
-  for (var i = 0; i < bytes.length; i++) {
-    var char = bytes[i];
-    if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) {
-      return char;
-    }
-  }
-  return -1;
-}
-
-/// Attempts to return a relative path-only URI for [uri].
-///
-/// First removes any query or fragment part from [uri].
-///
-/// If [uri] is already relative (has no scheme), it's returned as-is.
-/// If that is not desired, the caller can pass `baseUri.resolveUri(uri)`
-/// as the [uri] instead.
-///
-/// If the [uri] has a scheme or authority part which differs from
-/// the [baseUri], or if there is no overlap in the paths of the
-/// two URIs at all, the [uri] is returned as-is.
-///
-/// Otherwise the result is a path-only URI which satsifies
-/// `baseUri.resolveUri(result) == uri`,
-///
-/// The `baseUri` must be absolute.
-Uri relativizeUri(Uri uri, Uri? baseUri) {
-  if (baseUri == null) return uri;
-  assert(baseUri.isAbsolute);
-  if (uri.hasQuery || uri.hasFragment) {
-    uri = Uri(
-        scheme: uri.scheme,
-        userInfo: uri.hasAuthority ? uri.userInfo : null,
-        host: uri.hasAuthority ? uri.host : null,
-        port: uri.hasAuthority ? uri.port : null,
-        path: uri.path);
-  }
-
-  // Already relative. We assume the caller knows what they are doing.
-  if (!uri.isAbsolute) return uri;
-
-  if (baseUri.scheme != uri.scheme) {
-    return uri;
-  }
-
-  // If authority differs, we could remove the scheme, but it's not worth it.
-  if (uri.hasAuthority != baseUri.hasAuthority) return uri;
-  if (uri.hasAuthority) {
-    if (uri.userInfo != baseUri.userInfo ||
-        uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
-        uri.port != baseUri.port) {
-      return uri;
-    }
-  }
-
-  baseUri = baseUri.normalizePath();
-  var base = [...baseUri.pathSegments];
-  if (base.isNotEmpty) base.removeLast();
-  uri = uri.normalizePath();
-  var target = [...uri.pathSegments];
-  if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
-  var index = 0;
-  while (index < base.length && index < target.length) {
-    if (base[index] != target[index]) {
-      break;
-    }
-    index++;
-  }
-  if (index == base.length) {
-    if (index == target.length) {
-      return Uri(path: "./");
-    }
-    return Uri(path: target.skip(index).join('/'));
-  } else if (index > 0) {
-    var buffer = StringBuffer();
-    for (var n = base.length - index; n > 0; --n) {
-      buffer.write("../");
-    }
-    buffer.writeAll(target.skip(index), "/");
-    return Uri(path: buffer.toString());
-  } else {
-    return uri;
-  }
-}
-
-/// Attempts to return a relative URI for [uri].
-///
-/// The result URI satisfies `baseUri.resolveUri(result) == uri`,
-/// but may be relative.
-/// The `baseUri` must be absolute.
-Uri _relativize(Uri uri, Uri baseUri) {
-  assert(baseUri.isAbsolute);
-  if (uri.hasQuery || uri.hasFragment) {
-    uri = Uri(
-        scheme: uri.scheme,
-        userInfo: uri.hasAuthority ? uri.userInfo : null,
-        host: uri.hasAuthority ? uri.host : null,
-        port: uri.hasAuthority ? uri.port : null,
-        path: uri.path);
-  }
-
-  // Already relative. We assume the caller knows what they are doing.
-  if (!uri.isAbsolute) return uri;
-
-  if (baseUri.scheme != uri.scheme) {
-    return uri;
-  }
-
-  // If authority differs, we could remove the scheme, but it's not worth it.
-  if (uri.hasAuthority != baseUri.hasAuthority) return uri;
-  if (uri.hasAuthority) {
-    if (uri.userInfo != baseUri.userInfo ||
-        uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
-        uri.port != baseUri.port) {
-      return uri;
-    }
-  }
-
-  baseUri = baseUri.normalizePath();
-  var base = baseUri.pathSegments.toList();
-  if (base.isNotEmpty) {
-    base = List<String>.from(base)..removeLast();
-  }
-  uri = uri.normalizePath();
-  var target = uri.pathSegments.toList();
-  if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
-  var index = 0;
-  while (index < base.length && index < target.length) {
-    if (base[index] != target[index]) {
-      break;
-    }
-    index++;
-  }
-  if (index == base.length) {
-    if (index == target.length) {
-      return Uri(path: "./");
-    }
-    return Uri(path: target.skip(index).join('/'));
-  } else if (index > 0) {
-    return Uri(
-        path: '../' * (base.length - index) + target.skip(index).join('/'));
-  } else {
-    return uri;
-  }
-}
-
-// Character constants used by this package.
-/// "Line feed" control character.
-const int $lf = 0x0a;
-
-/// "Carriage return" control character.
-const int $cr = 0x0d;
-
-/// Space character.
-const int $space = 0x20;
-
-/// Character `#`.
-const int $hash = 0x23;
-
-/// Character `.`.
-const int $dot = 0x2e;
-
-/// Character `:`.
-const int $colon = 0x3a;
-
-/// Character `?`.
-const int $question = 0x3f;
-
-/// Character `{`.
-const int $lbrace = 0x7b;
-
-/// General superclass of most errors and exceptions thrown by this package.
-///
-/// Only covers errors thrown while parsing package configuration files.
-/// Programming errors and I/O exceptions are not covered.
-abstract class PackageConfigError {
-  PackageConfigError._();
-}
-
-class PackageConfigArgumentError extends ArgumentError
-    implements PackageConfigError {
-  PackageConfigArgumentError(Object? value, String name, String message)
-      : super.value(value, name, message);
-
-  PackageConfigArgumentError.from(ArgumentError error)
-      : super.value(error.invalidValue, error.name, error.message);
-}
-
-class PackageConfigFormatException extends FormatException
-    implements PackageConfigError {
-  PackageConfigFormatException(String message, Object? source, [int? offset])
-      : super(message, source, offset);
-
-  PackageConfigFormatException.from(FormatException exception)
-      : super(exception.message, exception.source, exception.offset);
-}
diff --git a/test/descriptor.dart b/test/descriptor.dart
index b3f8a55..9248ad4 100644
--- a/test/descriptor.dart
+++ b/test/descriptor.dart
@@ -12,7 +12,7 @@
 import 'package:test_descriptor/test_descriptor.dart';
 
 import 'descriptor/git.dart';
-import 'descriptor/packages.dart';
+import 'descriptor/package_config.dart';
 import 'descriptor/tar.dart';
 import 'descriptor/yaml.dart';
 import 'test_pub.dart';
@@ -20,7 +20,7 @@
 export 'package:test_descriptor/test_descriptor.dart';
 
 export 'descriptor/git.dart';
-export 'descriptor/packages.dart';
+export 'descriptor/package_config.dart';
 export 'descriptor/tar.dart';
 
 /// Creates a new [GitRepoDescriptor] with [name] and [contents].
@@ -260,20 +260,6 @@
 DirectoryDescriptor appDir([Map? dependencies]) =>
     dir(appPath, [appPubspec(dependencies)]);
 
-/// Describes a `.packages` file.
-///
-/// [dependencies] maps package names to strings describing where the packages
-/// are located on disk. If the strings are semantic versions, then the packages
-/// are located in the system cache; otherwise, the strings are interpreted as
-/// relative `file:` URLs.
-///
-/// Validation checks that the `.packages` file exists, has the expected
-/// entries (one per key in [dependencies]), each with a path that contains
-/// either the version string (for a reference to the pub cache) or a
-/// path to a path dependency, relative to the application directory.
-Descriptor packagesFile(Map<String, String> dependencies) =>
-    PackagesFileDescriptor(dependencies);
-
 /// Describes a `.dart_tools/package_config.json` file.
 ///
 /// [dependencies] is a list of packages included in the file.
@@ -335,11 +321,3 @@
         languageVersion != null ? LanguageVersion.parse(languageVersion) : null,
   );
 }
-
-/// Describes a `.packages` file in the application directory, including the
-/// implicit entry for the app itself.
-Descriptor appPackagesFile(Map<String, String> dependencies) {
-  var copied = Map<String, String>.from(dependencies);
-  copied['myapp'] = '.';
-  return dir(appPath, [packagesFile(copied)]);
-}
diff --git a/test/descriptor/package_config.dart b/test/descriptor/package_config.dart
new file mode 100644
index 0000000..5c84a82
--- /dev/null
+++ b/test/descriptor/package_config.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// 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:async' show Future;
+import 'dart:convert' show JsonEncoder, json;
+import 'dart:io' show File;
+
+import 'package:path/path.dart' as p;
+import 'package:pub/src/package_config.dart';
+import 'package:pub_semver/pub_semver.dart';
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart';
+
+/// Describes a `.dart_tools/package_config.json` file and its contents.
+class PackageConfigFileDescriptor extends Descriptor {
+  final String _generatorVersion;
+
+  /// A map describing the packages in this `package_config.json` file.
+  final List<PackageConfigEntry> _packages;
+
+  PackageConfig get _config {
+    return PackageConfig(
+      configVersion: 2,
+      packages: _packages,
+      generatorVersion: Version.parse(_generatorVersion),
+      generator: 'pub',
+      generated: DateTime.now().toUtc(),
+    );
+  }
+
+  /// Describes a `.packages` file with the given dependencies.
+  ///
+  /// [dependencies] maps package names to strings describing where the packages
+  /// are located on disk.
+  PackageConfigFileDescriptor(this._packages, this._generatorVersion)
+      : super('.dart_tool/package_config.json');
+
+  @override
+  Future<void> create([String? parent]) async {
+    final packageConfigFile = File(p.join(parent ?? sandbox, name));
+    await packageConfigFile.parent.create();
+    await packageConfigFile.writeAsString(
+      '${const JsonEncoder.withIndent('  ').convert(_config.toJson())}\n',
+    );
+  }
+
+  @override
+  Future<void> validate([String? parent]) async {
+    final packageConfigFile = p.join(parent ?? sandbox, name);
+    if (!await File(packageConfigFile).exists()) {
+      fail("File not found: '$packageConfigFile'.");
+    }
+
+    Map<String, dynamic> rawJson = json.decode(
+      await File(packageConfigFile).readAsString(),
+    );
+    PackageConfig config;
+    try {
+      config = PackageConfig.fromJson(rawJson);
+    } on FormatException catch (e) {
+      fail('File "$packageConfigFile" is not valid: $e');
+    }
+
+    // Compare packages as sets to ignore ordering.
+    expect(
+      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());
+    // omit generated date-time and packages
+    expected.generated = null; // comparing timestamps is unnecessary.
+    config.generated = null;
+    expected.packages = []; // Already compared packages (ignoring ordering)
+    config.packages = [];
+    expect(config.toJson(), equals(expected.toJson()),
+        reason: '"$packageConfigFile" does not match expected values');
+  }
+
+  @override
+  String describe() => name;
+}
diff --git a/test/descriptor/packages.dart b/test/descriptor/packages.dart
deleted file mode 100644
index e728f7c..0000000
--- a/test/descriptor/packages.dart
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// 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:async' show Future;
-import 'dart:convert' show JsonEncoder, json, utf8;
-import 'dart:io' show File;
-
-import 'package:path/path.dart' as p;
-import 'package:pub/src/package_config.dart';
-import 'package:pub/src/packages_file.dart' as packages_file;
-import 'package:pub_semver/pub_semver.dart';
-import 'package:test/test.dart';
-import 'package:test_descriptor/test_descriptor.dart';
-
-import '../test_pub.dart';
-
-// Resolve against a dummy URL so that we can test whether the URLs in
-// the package file are themselves relative. We can't resolve against just
-// "." due to sdk#23809.
-const _base = '/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p';
-
-/// Describes a `.packages` file and its contents.
-class PackagesFileDescriptor extends Descriptor {
-  /// A map from package names to either version strings or path to the package.
-  final Map<String, String>? _dependencies;
-
-  /// Describes a `.packages` file with the given dependencies.
-  ///
-  /// [dependencies] maps package names to strings describing where the packages
-  /// are located on disk.
-  PackagesFileDescriptor([this._dependencies]) : super('.packages');
-
-  @override
-  Future create([String? parent]) {
-    var contents = const <int>[];
-    var dependencies = _dependencies;
-    if (dependencies != null) {
-      var mapping = <String, Uri>{};
-      dependencies.forEach((package, version) {
-        String packagePath;
-        if (_isSemver(version)) {
-          // It's a cache reference.
-          packagePath = p.join(cachePath, '$package-$version');
-        } else {
-          // Otherwise it's a path relative to the pubspec file,
-          // which is also relative to the .packages file.
-          packagePath = version;
-        }
-        mapping[package] = p.toUri(p.join(packagePath, 'lib', ''));
-      });
-      var buffer = StringBuffer();
-      packages_file.write(buffer, mapping);
-      contents = utf8.encode(buffer.toString());
-    }
-    return File(p.join(parent ?? sandbox, name)).writeAsBytes(contents);
-  }
-
-  @override
-  Future validate([String? parent]) async {
-    var fullPath = p.join(parent ?? sandbox, name);
-    if (!await File(fullPath).exists()) {
-      fail("File not found: '$fullPath'.");
-    }
-
-    var bytes = await File(fullPath).readAsBytes();
-
-    var map = packages_file.parse(bytes, Uri.parse(_base));
-
-    var dependencies = _dependencies!;
-
-    for (var package in dependencies.keys) {
-      if (!map.containsKey(package)) {
-        fail('.packages does not contain $package entry');
-      }
-
-      var description = dependencies[package]!;
-      if (_isSemver(description)) {
-        if (!map[package]!.path.contains(description)) {
-          fail('.packages of $package has incorrect version. '
-              'Expected $description, found location: ${map[package]}.');
-        }
-      } else {
-        var expected = p.normalize(p.join(description, 'lib'));
-        var actual = p.normalize(p.fromUri(
-            p.url.relative(map[package].toString(), from: p.dirname(_base))));
-
-        if (expected != actual) {
-          fail('Relative path: Expected $expected, found $actual');
-        }
-      }
-    }
-
-    if (map.length != dependencies.length) {
-      for (var key in map.keys) {
-        if (!dependencies.containsKey(key)) {
-          fail('.packages file contains unexpected entry: $key');
-        }
-      }
-    }
-  }
-
-  @override
-  String describe() => name;
-}
-
-/// Describes a `.dart_tools/package_config.json` file and its contents.
-class PackageConfigFileDescriptor extends Descriptor {
-  final String _generatorVersion;
-
-  /// A map describing the packages in this `package_config.json` file.
-  final List<PackageConfigEntry> _packages;
-
-  PackageConfig get _config {
-    return PackageConfig(
-      configVersion: 2,
-      packages: _packages,
-      generatorVersion: Version.parse(_generatorVersion),
-      generator: 'pub',
-      generated: DateTime.now().toUtc(),
-    );
-  }
-
-  /// Describes a `.packages` file with the given dependencies.
-  ///
-  /// [dependencies] maps package names to strings describing where the packages
-  /// are located on disk.
-  PackageConfigFileDescriptor(this._packages, this._generatorVersion)
-      : super('.dart_tool/package_config.json');
-
-  @override
-  Future<void> create([String? parent]) async {
-    final packageConfigFile = File(p.join(parent ?? sandbox, name));
-    await packageConfigFile.parent.create();
-    await packageConfigFile.writeAsString(
-      '${const JsonEncoder.withIndent('  ').convert(_config.toJson())}\n',
-    );
-  }
-
-  @override
-  Future<void> validate([String? parent]) async {
-    final packageConfigFile = p.join(parent ?? sandbox, name);
-    if (!await File(packageConfigFile).exists()) {
-      fail("File not found: '$packageConfigFile'.");
-    }
-
-    Map<String, dynamic> rawJson = json.decode(
-      await File(packageConfigFile).readAsString(),
-    );
-    PackageConfig config;
-    try {
-      config = PackageConfig.fromJson(rawJson);
-    } on FormatException catch (e) {
-      fail('File "$packageConfigFile" is not valid: $e');
-    }
-
-    // Compare packages as sets to ignore ordering.
-    expect(
-      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());
-    // omit generated date-time and packages
-    expected.generated = null; // comparing timestamps is unnecessary.
-    config.generated = null;
-    expected.packages = []; // Already compared packages (ignoring ordering)
-    config.packages = [];
-    expect(config.toJson(), equals(expected.toJson()),
-        reason: '"$packageConfigFile" does not match expected values');
-  }
-
-  @override
-  String describe() => name;
-}
-
-/// Returns `true` if [text] is a valid semantic version number string.
-bool _isSemver(String text) {
-  try {
-    // See if it's a semver.
-    Version.parse(text);
-    return true;
-  } on FormatException catch (_) {
-    // Do nothing.
-  }
-  return false;
-}
diff --git a/test/must_pub_get_test.dart b/test/must_pub_get_test.dart
index 71d9c16..e7b0064 100644
--- a/test/must_pub_get_test.dart
+++ b/test/must_pub_get_test.dart
@@ -205,97 +205,6 @@
           'pubspec.lock file was generated, please run "dart pub get" again.');
     });
 
-    group(
-        'the lockfile is pointing to an unavailable package with an older '
-        '.packages', () {
-      setUp(() async {
-        await d.dir(appPath, [
-          d.appPubspec({'foo': '1.0.0'})
-        ]).create();
-
-        await pubGet(args: ['--legacy-packages-file']);
-
-        deleteEntry(p.join(d.sandbox, cachePath));
-
-        // Ensure that the lockfile looks newer than the .packages file.
-        await _touch('pubspec.lock');
-      });
-
-      _requiresPubGet('The pubspec.lock file has changed since the .packages '
-          'file was generated, please run "dart pub get" again.');
-    });
-
-    group("the lockfile has a package that the .packages file doesn't", () {
-      setUp(() async {
-        await d.dir('foo', [d.libPubspec('foo', '1.0.0')]).create();
-
-        await d.dir(appPath, [
-          d.appPubspec({
-            'foo': {'path': '../foo'}
-          })
-        ]).create();
-
-        await pubGet(args: ['--legacy-packages-file']);
-
-        await createPackagesFile(appPath);
-
-        // Ensure that the pubspec looks newer than the lockfile.
-        await _touch('pubspec.lock');
-      });
-
-      _requiresPubGet('The pubspec.lock file has changed since the .packages '
-          'file was generated, please run "dart pub get" again.');
-    });
-
-    group('the .packages file has a package with a non-file URI', () {
-      setUp(() async {
-        await d.dir('foo', [d.libPubspec('foo', '1.0.0')]).create();
-
-        await d.dir(appPath, [
-          d.appPubspec({
-            'foo': {'path': '../foo'}
-          })
-        ]).create();
-
-        await pubGet(args: ['--legacy-packages-file']);
-
-        await d.dir(appPath, [
-          d.file('.packages', '''
-myapp:lib
-foo:http://example.com/
-''')
-        ]).create();
-
-        // Ensure that the pubspec looks newer than the lockfile.
-        await _touch('pubspec.lock');
-      });
-
-      _requiresPubGet('The pubspec.lock file has changed since the .packages '
-          'file was generated, please run "dart pub get" again.');
-    });
-
-    group('the .packages file points to the wrong place', () {
-      setUp(() async {
-        await d.dir('bar', [d.libPubspec('foo', '1.0.0')]).create();
-
-        await d.dir(appPath, [
-          d.appPubspec({
-            'foo': {'path': '../bar'}
-          })
-        ]).create();
-
-        await pubGet(args: ['--legacy-packages-file']);
-
-        await createPackagesFile(appPath, dependenciesInSandBox: ['foo']);
-
-        // Ensure that the pubspec looks newer than the lockfile.
-        await _touch('pubspec.lock');
-      });
-
-      _requiresPubGet('The pubspec.lock file has changed since the .packages '
-          'file was generated, please run "dart pub get" again.');
-    });
-
     group('the package_config.json file points to the wrong place', () {
       setUp(() async {
         await d.dir('bar', [d.libPubspec('foo', '1.0.0')]).create();
diff --git a/test/packages_file_test.dart b/test/packages_file_test.dart
deleted file mode 100644
index c245a9a..0000000
--- a/test/packages_file_test.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// 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 'package:pub/src/exit_codes.dart' as exit_codes;
-
-import 'package:test/test.dart';
-
-import 'descriptor.dart' as d;
-import 'test_pub.dart';
-
-void main() {
-  forBothPubGetAndUpgrade((command) {
-    test('.packages file is created with flag', () async {
-      await servePackages()
-        ..serve('foo', '1.2.3',
-            deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])])
-        ..serve('bar', '3.2.1', contents: [d.dir('lib', [])])
-        ..serve('baz', '2.2.2',
-            deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]);
-
-      await d.dir(appPath, [
-        d.appPubspec({'foo': '1.2.3'}),
-        d.dir('lib')
-      ]).create();
-
-      await pubCommand(command, args: ['--legacy-packages-file']);
-
-      await d.dir(appPath, [
-        d.packagesFile(
-            {'foo': '1.2.3', 'bar': '3.2.1', 'baz': '2.2.2', 'myapp': '.'}),
-      ]).validate();
-    });
-
-    test('.packages file is overwritten with flag', () async {
-      await servePackages()
-        ..serve('foo', '1.2.3',
-            deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])])
-        ..serve('bar', '3.2.1', contents: [d.dir('lib', [])])
-        ..serve('baz', '2.2.2',
-            deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]);
-
-      await d.dir(appPath, [
-        d.appPubspec({'foo': '1.2.3'}),
-        d.dir('lib')
-      ]).create();
-
-      var oldFile = d.dir(appPath, [
-        d.packagesFile({'notFoo': '9.9.9'})
-      ]);
-      await oldFile.create();
-      await oldFile.validate(); // Sanity-check that file was created correctly.
-
-      await pubCommand(command, args: ['--legacy-packages-file']);
-
-      await d.dir(appPath, [
-        d.packagesFile(
-            {'foo': '1.2.3', 'bar': '3.2.1', 'baz': '2.2.2', 'myapp': '.'})
-      ]).validate();
-    });
-
-    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', '--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);
-
-      await d.dir(appPath, [d.nothing('.packages')]).validate();
-    });
-
-    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', [])])
-        ..serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]);
-
-      await d.dir('local_baz', [
-        d.libDir('baz', 'baz 3.2.1'),
-        d.libPubspec('baz', '3.2.1')
-      ]).create();
-
-      await d.dir(appPath, [
-        d.pubspec({
-          'name': 'myapp',
-          'dependencies': {
-            'foo': '^1.2.3',
-          },
-          'dependency_overrides': {
-            'baz': {'path': '../local_baz'},
-          }
-        }),
-        d.dir('lib')
-      ]).create();
-
-      await pubCommand(command, args: ['--legacy-packages-file']);
-
-      await d.dir(appPath, [
-        d.packagesFile({'myapp': '.', 'baz': '../local_baz', 'foo': '1.2.3'}),
-      ]).validate();
-    });
-  });
-}
diff --git a/test/test_pub.dart b/test/test_pub.dart
index 3c2f102..99f5655 100644
--- a/test/test_pub.dart
+++ b/test/test_pub.dart
@@ -624,36 +624,7 @@
       _createLockFile(cache, sandbox: dependenciesInSandBox, hosted: hosted);
 
   await d.dir(package, [
-    d.file('pubspec.lock', lockFile.serialize(p.join(d.sandbox, package))),
-    d.file(
-      '.packages',
-      lockFile.packagesFile(
-        cache,
-        entrypoint: package,
-        relativeFrom: p.join(d.sandbox, package),
-      ),
-    )
-  ]).create();
-}
-
-/// Like [createLockFile], but creates only a `.packages` file without a
-/// lockfile.
-Future<void> createPackagesFile(String package,
-    {Iterable<String>? dependenciesInSandBox,
-    Map<String, String>? hosted}) async {
-  var cache = SystemCache(rootDir: _pathInSandbox(cachePath));
-  var lockFile =
-      _createLockFile(cache, sandbox: dependenciesInSandBox, hosted: hosted);
-
-  await d.dir(package, [
-    d.file(
-      '.packages',
-      lockFile.packagesFile(
-        cache,
-        entrypoint: package,
-        relativeFrom: d.sandbox,
-      ),
-    )
+    d.file('pubspec.lock', lockFile.serialize(p.join(d.sandbox, package)))
   ]).create();
 }
 
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 bdc0165..2d9306e 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
@@ -23,13 +23,13 @@
 [E]    | user-agent: Dart pub 0.1.2+3
 [E] IO  : HTTP response 200 OK for GET http://localhost:$PORT/api/packages/foo
 [E]    | took: $TIME
+[E]    | x-powered-by: Dart with package:shelf
 [E]    | date: $TIME
 [E]    | content-length: 197
 [E]    | x-frame-options: SAMEORIGIN
 [E]    | content-type: text/plain; charset=utf-8
 [E]    | x-xss-protection: 1; mode=block
 [E]    | x-content-type-options: nosniff
-[E]    | server: dart:io with Shelf
 [E] IO  : Writing $N characters to text file $SANDBOX/cache/hosted/localhost%58$PORT/.cache/foo-versions.json.
 [E] FINE: Contents:
 [E]    | {"name":"foo","uploaders":["nweiz@google.com"],"versions":[{"pubspec":{"name":"foo","version":"1.0.0"},"version":"1.0.0","archive_url":"http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz"}],"_fetchedAt": "$TIME"}
@@ -48,13 +48,13 @@
 [E]    | user-agent: Dart pub 0.1.2+3
 [E] IO  : HTTP response 200 OK for GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz
 [E]    | took: $TIME
+[E]    | x-powered-by: Dart with package:shelf
 [E]    | transfer-encoding: chunked
 [E]    | date: $TIME
 [E]    | x-frame-options: SAMEORIGIN
 [E]    | content-type: text/plain; charset=utf-8
 [E]    | x-xss-protection: 1; mode=block
 [E]    | x-content-type-options: nosniff
-[E]    | server: dart:io with Shelf
 [E] IO  : Creating $FILE from stream
 [E] FINE: Created $FILE from stream
 [E] IO  : Created temp directory $DIR
@@ -159,13 +159,13 @@
    | user-agent: Dart pub 0.1.2+3
 IO  : HTTP response 200 OK for GET http://localhost:$PORT/api/packages/foo
    | took: $TIME
+   | x-powered-by: Dart with package:shelf
    | date: $TIME
    | content-length: 197
    | x-frame-options: SAMEORIGIN
    | content-type: text/plain; charset=utf-8
    | x-xss-protection: 1; mode=block
    | x-content-type-options: nosniff
-   | server: dart:io with Shelf
 IO  : Writing $N characters to text file $SANDBOX/cache/hosted/localhost%58$PORT/.cache/foo-versions.json.
 FINE: Contents:
    | {"name":"foo","uploaders":["nweiz@google.com"],"versions":[{"pubspec":{"name":"foo","version":"1.0.0"},"version":"1.0.0","archive_url":"http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz"}],"_fetchedAt": "$TIME"}
@@ -186,13 +186,13 @@
    | user-agent: Dart pub 0.1.2+3
 IO  : HTTP response 200 OK for GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz
    | took: $TIME
+   | x-powered-by: Dart with package:shelf
    | transfer-encoding: chunked
    | date: $TIME
    | x-frame-options: SAMEORIGIN
    | content-type: text/plain; charset=utf-8
    | x-xss-protection: 1; mode=block
    | x-content-type-options: nosniff
-   | server: dart:io with Shelf
 IO  : Creating $FILE from stream
 FINE: Created $FILE from stream
 IO  : Created temp directory $DIR
diff --git a/test/testdata/goldens/help_test/pub add --help.txt b/test/testdata/goldens/help_test/pub add --help.txt
index 3d1f429..2a37c21 100644
--- a/test/testdata/goldens/help_test/pub add --help.txt
+++ b/test/testdata/goldens/help_test/pub add --help.txt
@@ -5,22 +5,20 @@
 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>.
-    --legacy-packages-file    Generate the legacy ".packages" file
+-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>.
 
 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 ddf71e7..4497da2 100644
--- a/test/testdata/goldens/help_test/pub downgrade --help.txt
+++ b/test/testdata/goldens/help_test/pub downgrade --help.txt
@@ -7,13 +7,11 @@
 
 
 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>.
-    --legacy-packages-file    Generate the legacy ".packages" file
+-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>.
 
 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 104f69c..74648a2 100644
--- a/test/testdata/goldens/help_test/pub get --help.txt
+++ b/test/testdata/goldens/help_test/pub get --help.txt
@@ -5,14 +5,12 @@
 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.
-    --legacy-packages-file    Generate the legacy ".packages" file
--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.
+-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 b82f9b6..7d14ed0 100644
--- a/test/testdata/goldens/help_test/pub remove --help.txt
+++ b/test/testdata/goldens/help_test/pub remove --help.txt
@@ -5,14 +5,12 @@
 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>.
-    --legacy-packages-file    Generate the legacy ".packages" file
+-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>.
 
 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 c787951..d1a29b9 100644
--- a/test/testdata/goldens/help_test/pub upgrade --help.txt
+++ b/test/testdata/goldens/help_test/pub upgrade --help.txt
@@ -5,18 +5,16 @@
 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
-    --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>.
+-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>.
 
 Run "pub help" to see global options.
 See https://dart.dev/tools/pub/cmd/pub-upgrade for detailed documentation.