Fix .packages entries of relative path deps when using --directory (#2916)

diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart
index 3c949c3..bb3e3c6 100644
--- a/lib/src/entrypoint.dart
+++ b/lib/src/entrypoint.dart
@@ -186,15 +186,18 @@
 
   /// Writes .packages and .dart_tool/package_config.json
   Future<void> writePackagesFiles() async {
-    writeTextFile(packagesFile, lockFile.packagesFile(cache, root.name));
+    writeTextFile(
+        packagesFile,
+        lockFile.packagesFile(cache,
+            entrypoint: root.name, relativeFrom: root.dir));
     ensureDir(p.dirname(packageConfigFile));
     writeTextFile(
         packageConfigFile,
-        await lockFile.packageConfigFile(
-          cache,
-          entrypoint: root.name,
-          entrypointSdkConstraint: root.pubspec.sdkConstraints[sdk.identifier],
-        ));
+        await lockFile.packageConfigFile(cache,
+            entrypoint: root.name,
+            entrypointSdkConstraint:
+                root.pubspec.sdkConstraints[sdk.identifier],
+            relativeFrom: root.dir));
   }
 
   /// Gets all dependencies of the [root] package.
@@ -549,7 +552,8 @@
         // If we can't load the pubspec, the user needs to re-run "pub get".
       }
 
-      dataError('${p.join(source.getDirectory(id), 'pubspec.yaml')} has '
+      dataError(
+          '${p.join(source.getDirectory(id, relativeFrom: '.'), 'pubspec.yaml')} has '
           'changed since the pubspec.lock file was generated, please run "pub '
           'get" again.');
     }
@@ -576,7 +580,7 @@
       if (source is! CachedSource) return true;
 
       // Get the directory.
-      var dir = source.getDirectory(package);
+      var dir = source.getDirectory(package, relativeFrom: '.');
       // See if the directory is there and looks like a package.
       return dirExists(dir) && fileExists(p.join(dir, 'pubspec.yaml'));
     });
@@ -616,7 +620,9 @@
       }
 
       final source = cache.source(lockFileId.source);
-      final lockFilePackagePath = root.path(source.getDirectory(lockFileId));
+      final lockFilePackagePath = root.path(
+        source.getDirectory(lockFileId, relativeFrom: root.dir),
+      );
 
       // Make sure that the packagePath agrees with the lock file about the
       // path to the package.
@@ -765,7 +771,8 @@
           cache.load(id).pubspec.sdkConstraints[sdk.identifier],
         );
         if (pkg.languageVersion != languageVersion) {
-          dataError('${p.join(source.getDirectory(id), 'pubspec.yaml')} has '
+          dataError(
+              '${p.join(source.getDirectory(id, relativeFrom: '.'), 'pubspec.yaml')} has '
               'changed since the pubspec.lock file was generated, please run '
               '"pub get" again.');
         }
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart
index c9fc8b7..726a1a4 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -236,11 +236,14 @@
     // Load the package graph from [result] so we don't need to re-parse all
     // the pubspecs.
     final entrypoint = Entrypoint.global(
-        Package(result.pubspecs[dep.name],
-            cache.source(dep.source).getDirectory(id)),
-        lockFile,
-        cache,
-        solveResult: result);
+      Package(
+        result.pubspecs[dep.name],
+        (cache.source(dep.source) as CachedSource).getDirectoryInCache(id),
+      ),
+      lockFile,
+      cache,
+      solveResult: result,
+    );
     if (!sameVersions) {
       // Only precompile binaries if we have a new resolution.
       await entrypoint.precompileExecutables();
@@ -261,10 +264,12 @@
     // TODO(sigurdm): Use [Entrypoint.writePackagesFiles] instead.
     final packagesFilePath = _getPackagesFilePath(package);
     final packageConfigFilePath = _getPackageConfigFilePath(package);
-    writeTextFile(packagesFilePath, lockFile.packagesFile(cache));
-    ensureDir(p.dirname(packageConfigFilePath));
+    final dir = p.dirname(packagesFilePath);
     writeTextFile(
-        packageConfigFilePath, await lockFile.packageConfigFile(cache));
+        packagesFilePath, lockFile.packagesFile(cache, relativeFrom: dir));
+    ensureDir(p.dirname(packageConfigFilePath));
+    writeTextFile(packageConfigFilePath,
+        await lockFile.packageConfigFile(cache, relativeFrom: dir));
   }
 
   /// Finishes activating package [package] by saving [lockFile] in the cache.
@@ -355,7 +360,7 @@
     if (source is CachedSource) {
       // For cached sources, the package itself is in the cache and the
       // lockfile is the one we just loaded.
-      entrypoint = Entrypoint.global(cache.load(id), lockFile, cache);
+      entrypoint = Entrypoint.global(cache.loadCached(id), lockFile, cache);
     } else {
       // For uncached sources (i.e. path), the ID just points to the real
       // directory for the package.
@@ -515,8 +520,13 @@
           await _writePackageConfigFiles(id.name, entrypoint.lockFile);
           await entrypoint.precompileExecutables();
           var packageExecutables = executables.remove(id.name) ?? [];
-          _updateBinStubs(entrypoint, cache.load(id), packageExecutables,
-              overwriteBinStubs: true, suggestIfNotOnPath: false);
+          _updateBinStubs(
+            entrypoint,
+            cache.load(id),
+            packageExecutables,
+            overwriteBinStubs: true,
+            suggestIfNotOnPath: false,
+          );
           successes.add(id.name);
         } catch (error, stackTrace) {
           var message = 'Failed to reactivate '
diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart
index b51dd78..4902099 100644
--- a/lib/src/lock_file.dart
+++ b/lib/src/lock_file.dart
@@ -6,6 +6,7 @@
 import 'dart:convert';
 
 import 'package:collection/collection.dart' hide mapMap;
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as p;
 import 'package:pub_semver/pub_semver.dart';
 import 'package:source_span/source_span.dart';
@@ -218,7 +219,11 @@
   ///
   /// If [entrypoint] is passed, a relative entry is added for its "lib/"
   /// directory.
-  String packagesFile(SystemCache cache, [String entrypoint]) {
+  String packagesFile(
+    SystemCache cache, {
+    String entrypoint,
+    @required String relativeFrom,
+  }) {
     var header = '''
 This file is deprecated. Tools should instead consume 
 `.dart_tools/package_config.json`.
@@ -231,7 +236,8 @@
         Map<String, Uri>.fromIterable(ordered(packages.keys), value: (name) {
       var id = packages[name];
       var source = cache.source(id.source);
-      return p.toUri(p.join(source.getDirectory(id), 'lib'));
+      return p.toUri(
+          p.join(source.getDirectory(id, relativeFrom: relativeFrom), 'lib'));
     });
 
     if (entrypoint != null) map[entrypoint] = Uri.parse('lib/');
@@ -254,12 +260,13 @@
     SystemCache cache, {
     String entrypoint,
     VersionConstraint entrypointSdkConstraint,
+    @required String relativeFrom,
   }) async {
     final entries = <PackageConfigEntry>[];
     for (final name in ordered(packages.keys)) {
       final id = packages[name];
       final source = cache.source(id.source);
-      final rootPath = source.getDirectory(id);
+      final rootPath = source.getDirectory(id, relativeFrom: relativeFrom);
       Uri rootUri;
       if (p.isRelative(rootPath)) {
         // Relative paths are relative to the root project, we want them
diff --git a/lib/src/null_safety_analysis.dart b/lib/src/null_safety_analysis.dart
index 746999c..6f85887 100644
--- a/lib/src/null_safety_analysis.dart
+++ b/lib/src/null_safety_analysis.dart
@@ -118,7 +118,8 @@
     return nullSafetyComplianceOfPackages(
         result.packages.where((id) => id.name != fakeRootName),
         Package(rootPubspec,
-            packageId.source.bind(_systemCache).getDirectory(packageId)));
+            packageId.source.bind(_systemCache).getDirectory(packageId)),
+        containingPath);
   }
 
   /// Decides if all dependendencies (transitively) have a language version
@@ -133,7 +134,10 @@
   ///
   /// Assumes the root package is opted in.
   Future<NullSafetyAnalysisResult> nullSafetyComplianceOfPackages(
-      Iterable<PackageId> packages, Package rootPackage) async {
+    Iterable<PackageId> packages,
+    Package rootPackage,
+    String containingPath,
+  ) async {
     NullSafetyAnalysisResult firstBadPackage;
     for (final dependencyId in packages) {
       final packageInternalAnalysis =
diff --git a/lib/src/solver/package_lister.dart b/lib/src/solver/package_lister.dart
index 5851e0e..8679fad 100644
--- a/lib/src/solver/package_lister.dart
+++ b/lib/src/solver/package_lister.dart
@@ -448,5 +448,6 @@
   @override
   Future<Pubspec> doDescribe(PackageId id) => throw _unsupported;
   @override
-  String getDirectory(PackageId id) => throw _unsupported;
+  String getDirectory(PackageId id, {String relativeFrom}) =>
+      throw _unsupported;
 }
diff --git a/lib/src/source.dart b/lib/src/source.dart
index fcfe2fe..c2b9fbb 100644
--- a/lib/src/source.dart
+++ b/lib/src/source.dart
@@ -234,7 +234,10 @@
   /// Returns the directory where this package can (or could) be found locally.
   ///
   /// If the source is cached, this will be a path in the system cache.
-  String getDirectory(PackageId id);
+  ///
+  /// If id is a relative path id, the directory will be relative from
+  /// [relativeFrom]. Returns an absolute path if [relativeFrom] is not passed.
+  String getDirectory(PackageId id, {String relativeFrom});
 
   /// Returns metadata about a given package. Information about remotely hosted
   /// packages can be cached for up to [maxAge].
diff --git a/lib/src/source/cached.dart b/lib/src/source/cached.dart
index 0ec9b1f..0952472 100644
--- a/lib/src/source/cached.dart
+++ b/lib/src/source/cached.dart
@@ -31,7 +31,7 @@
   /// Otherwise, defers to the subclass.
   @override
   Future<Pubspec> doDescribe(PackageId id) async {
-    var packageDir = getDirectory(id);
+    var packageDir = getDirectoryInCache(id);
     if (fileExists(path.join(packageDir, 'pubspec.yaml'))) {
       return Pubspec.load(packageDir, systemCache.sources,
           expectedName: id.name);
@@ -40,6 +40,12 @@
     return await describeUncached(id);
   }
 
+  @override
+  String getDirectory(PackageId id, {String relativeFrom}) =>
+      getDirectoryInCache(id);
+
+  String getDirectoryInCache(PackageId id);
+
   /// Loads the (possibly remote) pubspec for the package version identified by
   /// [id].
   ///
@@ -49,7 +55,7 @@
 
   /// Determines if the package identified by [id] is already downloaded to the
   /// system cache.
-  bool isInSystemCache(PackageId id) => dirExists(getDirectory(id));
+  bool isInSystemCache(PackageId id) => dirExists(getDirectoryInCache(id));
 
   /// Downloads the package identified by [id] to the system cache.
   Future<Package> downloadToSystemCache(PackageId id);
diff --git a/lib/src/source/git.dart b/lib/src/source/git.dart
index 3a3e18d..c986015 100644
--- a/lib/src/source/git.dart
+++ b/lib/src/source/git.dart
@@ -323,7 +323,7 @@
 
   /// Returns the path to the revision-specific cache of [id].
   @override
-  String getDirectory(PackageId id) =>
+  String getDirectoryInCache(PackageId id) =>
       p.join(_revisionCachePath(id), id.description['path']);
 
   @override
@@ -396,7 +396,7 @@
         result.add(RepairResult(id, success: false));
 
         // Delete the revision cache path, not the subdirectory that contains the package.
-        tryDeleteEntry(getDirectory(id));
+        tryDeleteEntry(getDirectoryInCache(id));
       }
     }
 
diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart
index f6f240e..d563839 100644
--- a/lib/src/source/hosted.dart
+++ b/lib/src/source/hosted.dart
@@ -417,12 +417,12 @@
   @override
   Future<Package> downloadToSystemCache(PackageId id) async {
     if (!isInSystemCache(id)) {
-      var packageDir = getDirectory(id);
+      var packageDir = getDirectoryInCache(id);
       ensureDir(p.dirname(packageDir));
       await _download(id, packageDir);
     }
 
-    return Package.load(id.name, getDirectory(id), systemCache.sources);
+    return Package.load(id.name, getDirectoryInCache(id), systemCache.sources);
   }
 
   /// The system cache directory for the hosted source contains subdirectories
@@ -431,7 +431,7 @@
   /// Each of these subdirectories then contains a subdirectory for each
   /// package downloaded from that site.
   @override
-  String getDirectory(PackageId id) {
+  String getDirectoryInCache(PackageId id) {
     var parsed = source._parseDescription(id.description);
     var dir = _urlToDirectory(parsed.last);
     return p.join(systemCacheRoot, dir, '${parsed.first}-${id.version}');
diff --git a/lib/src/source/path.dart b/lib/src/source/path.dart
index a84b92f..0e08098 100644
--- a/lib/src/source/path.dart
+++ b/lib/src/source/path.dart
@@ -181,7 +181,11 @@
   }
 
   @override
-  String getDirectory(PackageId id) => id.description['path'];
+  String getDirectory(PackageId id, {String relativeFrom}) {
+    return id.description['relative']
+        ? p.relative(id.description['path'], from: relativeFrom)
+        : id.description['path'];
+  }
 
   /// Ensures that [description] is a valid path description and returns a
   /// normalized path to the package.
diff --git a/lib/src/source/sdk.dart b/lib/src/source/sdk.dart
index c2d4edf..9950e66 100644
--- a/lib/src/source/sdk.dart
+++ b/lib/src/source/sdk.dart
@@ -110,7 +110,7 @@
   }
 
   @override
-  String getDirectory(PackageId id) {
+  String getDirectory(PackageId id, {String relativeFrom}) {
     try {
       return _verifiedPackagePath(id);
     } on PackageNotFoundException catch (error) {
diff --git a/lib/src/source/unknown.dart b/lib/src/source/unknown.dart
index 53b9a42..0a0ad98 100644
--- a/lib/src/source/unknown.dart
+++ b/lib/src/source/unknown.dart
@@ -71,6 +71,7 @@
 
   /// Returns the directory where this package can be found locally.
   @override
-  String getDirectory(PackageId id) => throw UnsupportedError(
-      "Cannot find a package from an unknown source '${source.name}'.");
+  String getDirectory(PackageId id, {String relativeFrom}) =>
+      throw UnsupportedError(
+          "Cannot find a package from an unknown source '${source.name}'.");
 }
diff --git a/lib/src/system_cache.dart b/lib/src/system_cache.dart
index 00c918f..47333af 100644
--- a/lib/src/system_cache.dart
+++ b/lib/src/system_cache.dart
@@ -107,6 +107,15 @@
     return Package.load(id.name, source(id.source).getDirectory(id), sources);
   }
 
+  Package loadCached(PackageId id) {
+    final bound = source(id.source);
+    if (bound is CachedSource) {
+      return Package.load(id.name, bound.getDirectoryInCache(id), sources);
+    } else {
+      throw ArgumentError('Call only on Cached ids.');
+    }
+  }
+
   /// Determines if the system cache contains the package identified by [id].
   bool contains(PackageId id) {
     var source = this.source(id.source);
diff --git a/test/get/path/relative_path_test.dart b/test/get/path/relative_path_test.dart
index 03683be..5bf9e0c 100644
--- a/test/get/path/relative_path_test.dart
+++ b/test/get/path/relative_path_test.dart
@@ -50,6 +50,34 @@
         {'foo': '../relative/foo', 'bar': '../relative/bar'}).validate();
   });
 
+  test('path is relative to containing pubspec when using --directory',
+      () async {
+    await d.dir('relative', [
+      d.dir('foo', [
+        d.libDir('foo'),
+        d.libPubspec('foo', '0.0.1', deps: {
+          'bar': {'path': '../bar'}
+        })
+      ]),
+      d.dir('bar', [d.libDir('bar'), d.libPubspec('bar', '0.0.1')])
+    ]).create();
+
+    await d.dir(appPath, [
+      d.appPubspec({
+        'foo': {'path': '../relative/foo'}
+      })
+    ]).create();
+
+    await pubGet(
+        args: ['--directory', appPath],
+        workingDirectory: d.sandbox,
+        output: contains('Changed 2 dependencies in myapp!'));
+
+    await d.appPackagesFile(
+      {'foo': '../relative/foo', 'bar': '../relative/bar'},
+    ).validate();
+  });
+
   test('relative path preserved in the lockfile', () async {
     await d
         .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();
diff --git a/test/must_pub_get_test.dart b/test/must_pub_get_test.dart
index 6ad636f..8008ee3 100644
--- a/test/must_pub_get_test.dart
+++ b/test/must_pub_get_test.dart
@@ -102,7 +102,7 @@
 
         await pubGet();
 
-        await createLockFile(appPath, sandbox: ['foo']);
+        await createLockFile(appPath, dependenciesInSandBox: ['foo']);
 
         // Ensure that the pubspec looks newer than the lockfile.
         await _touch('pubspec.yaml');
@@ -154,7 +154,7 @@
 
         await pubGet();
 
-        await createLockFile(appPath, sandbox: ['foo']);
+        await createLockFile(appPath, dependenciesInSandBox: ['foo']);
 
         // Ensure that the pubspec looks newer than the lockfile.
         await _touch('pubspec.yaml');
@@ -285,7 +285,7 @@
 
         await pubGet();
 
-        await createPackagesFile(appPath, sandbox: ['foo']);
+        await createPackagesFile(appPath, dependenciesInSandBox: ['foo']);
 
         // Ensure that the pubspec looks newer than the lockfile.
         await _touch('pubspec.lock');
diff --git a/test/test_pub.dart b/test/test_pub.dart
index d757cb6..5d84a97 100644
--- a/test/test_pub.dart
+++ b/test/test_pub.dart
@@ -123,14 +123,17 @@
 ///
 /// If [exitCode] is given, expects the command to exit with that code.
 // TODO(rnystrom): Clean up other tests to call this when possible.
-Future<void> pubCommand(RunCommand command,
-    {Iterable<String> args,
-    output,
-    error,
-    silent,
-    warning,
-    int exitCode,
-    Map<String, String> environment}) async {
+Future<void> pubCommand(
+  RunCommand command, {
+  Iterable<String> args,
+  output,
+  error,
+  silent,
+  warning,
+  int exitCode,
+  Map<String, String> environment,
+  String workingDirectory,
+}) async {
   if (error != null && warning != null) {
     throw ArgumentError("Cannot pass both 'error' and 'warning'.");
   }
@@ -152,38 +155,49 @@
       error: error,
       silent: silent,
       exitCode: exitCode,
-      environment: environment);
+      environment: environment,
+      workingDirectory: workingDirectory);
 }
 
-Future<void> pubAdd(
-        {Iterable<String> args,
-        output,
-        error,
-        warning,
-        int exitCode,
-        Map<String, String> environment}) async =>
-    await pubCommand(RunCommand.add,
-        args: args,
-        output: output,
-        error: error,
-        warning: warning,
-        exitCode: exitCode,
-        environment: environment);
+Future<void> pubAdd({
+  Iterable<String> args,
+  output,
+  error,
+  warning,
+  int exitCode,
+  Map<String, String> environment,
+  String workingDirectory,
+}) async =>
+    await pubCommand(
+      RunCommand.add,
+      args: args,
+      output: output,
+      error: error,
+      warning: warning,
+      exitCode: exitCode,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
 
-Future<void> pubGet(
-        {Iterable<String> args,
-        output,
-        error,
-        warning,
-        int exitCode,
-        Map<String, String> environment}) async =>
-    await pubCommand(RunCommand.get,
-        args: args,
-        output: output,
-        error: error,
-        warning: warning,
-        exitCode: exitCode,
-        environment: environment);
+Future<void> pubGet({
+  Iterable<String> args,
+  output,
+  error,
+  warning,
+  int exitCode,
+  Map<String, String> environment,
+  String workingDirectory,
+}) async =>
+    await pubCommand(
+      RunCommand.get,
+      args: args,
+      output: output,
+      error: error,
+      warning: warning,
+      exitCode: exitCode,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
 
 Future<void> pubUpgrade(
         {Iterable<String> args,
@@ -191,44 +205,58 @@
         error,
         warning,
         int exitCode,
-        Map<String, String> environment}) async =>
-    await pubCommand(RunCommand.upgrade,
-        args: args,
-        output: output,
-        error: error,
-        warning: warning,
-        exitCode: exitCode,
-        environment: environment);
+        Map<String, String> environment,
+        String workingDirectory}) async =>
+    await pubCommand(
+      RunCommand.upgrade,
+      args: args,
+      output: output,
+      error: error,
+      warning: warning,
+      exitCode: exitCode,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
 
-Future<void> pubDowngrade(
-        {Iterable<String> args,
-        output,
-        error,
-        warning,
-        int exitCode,
-        Map<String, String> environment}) async =>
-    await pubCommand(RunCommand.downgrade,
-        args: args,
-        output: output,
-        error: error,
-        warning: warning,
-        exitCode: exitCode,
-        environment: environment);
+Future<void> pubDowngrade({
+  Iterable<String> args,
+  output,
+  error,
+  warning,
+  int exitCode,
+  Map<String, String> environment,
+  String workingDirectory,
+}) async =>
+    await pubCommand(
+      RunCommand.downgrade,
+      args: args,
+      output: output,
+      error: error,
+      warning: warning,
+      exitCode: exitCode,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
 
-Future<void> pubRemove(
-        {Iterable<String> args,
-        output,
-        error,
-        warning,
-        int exitCode,
-        Map<String, String> environment}) async =>
-    await pubCommand(RunCommand.remove,
-        args: args,
-        output: output,
-        error: error,
-        warning: warning,
-        exitCode: exitCode,
-        environment: environment);
+Future<void> pubRemove({
+  Iterable<String> args,
+  output,
+  error,
+  warning,
+  int exitCode,
+  Map<String, String> environment,
+  String workingDirectory,
+}) async =>
+    await pubCommand(
+      RunCommand.remove,
+      args: args,
+      output: output,
+      error: error,
+      warning: warning,
+      exitCode: exitCode,
+      environment: environment,
+      workingDirectory: workingDirectory,
+    );
 
 /// Schedules starting the "pub [global] run" process and validates the
 /// expected startup output.
@@ -572,34 +600,51 @@
 
 /// Creates a lock file for [package] without running `pub get`.
 ///
-/// [sandbox] is a list of path dependencies to be found in the sandbox
+/// [dependenciesInSandBox] is a list of path dependencies to be found in the sandbox
 /// directory.
 ///
 /// [hosted] is a list of package names to version strings for dependencies on
 /// hosted packages.
 Future<void> createLockFile(String package,
-    {Iterable<String> sandbox, Map<String, String> hosted}) async {
+    {Iterable<String> dependenciesInSandBox,
+    Map<String, String> hosted}) async {
   var cache = SystemCache(rootDir: _pathInSandbox(cachePath));
 
-  var lockFile =
-      _createLockFile(cache.sources, sandbox: sandbox, hosted: hosted);
+  var lockFile = _createLockFile(cache.sources,
+      sandbox: dependenciesInSandBox, hosted: hosted);
 
   await d.dir(package, [
     d.file('pubspec.lock', lockFile.serialize(null)),
-    d.file('.packages', lockFile.packagesFile(cache, 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> sandbox, Map<String, String> hosted}) async {
+    {Iterable<String> dependenciesInSandBox,
+    Map<String, String> hosted}) async {
   var cache = SystemCache(rootDir: _pathInSandbox(cachePath));
-  var lockFile =
-      _createLockFile(cache.sources, sandbox: sandbox, hosted: hosted);
+  var lockFile = _createLockFile(cache.sources,
+      sandbox: dependenciesInSandBox, hosted: hosted);
 
-  await d.dir(package,
-      [d.file('.packages', lockFile.packagesFile(cache, package))]).create();
+  await d.dir(package, [
+    d.file(
+      '.packages',
+      lockFile.packagesFile(
+        cache,
+        entrypoint: package,
+        relativeFrom: d.sandbox,
+      ),
+    )
+  ]).create();
 }
 
 /// Creates a lock file for [sources] without running `pub get`.