Fix package name when refreshing binstubs (#4205)
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart
index ab80d24..9ce849c 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -371,7 +371,7 @@
/// Returns an [Entrypoint] loaded with the active package if found.
Future<Entrypoint> find(String name) async {
var lockFilePath = _getLockFilePath(name);
- late LockFile lockFile;
+ late final LockFile lockFile;
try {
lockFile = LockFile.load(lockFilePath, cache.sources);
} on IOException {
@@ -379,11 +379,7 @@
dataError('No active package ${log.bold(name)}.');
}
- // Remove the package itself from the lockfile. We put it in there so we
- // could find and load the [Package] object, but normally an entrypoint
- // doesn't expect to be in its own lockfile.
- var id = lockFile.packages[name]!;
- lockFile = lockFile.removePackage(name);
+ final id = lockFile.packages[name]!;
Entrypoint entrypoint;
if (id.source is CachedSource) {
@@ -624,7 +620,7 @@
log.fine('Replacing old binstub $file');
deleteEntry(file);
_createBinStub(
- entrypoint.workspaceRoot,
+ activatedPackage(entrypoint),
p.basenameWithoutExtension(file),
binStubScript,
overwrite: true,
@@ -947,3 +943,17 @@
return match == null ? null : match[1];
}
}
+
+/// The package that was activated.
+///
+/// * For path packages this is [Entrypoint.workspaceRoot].
+/// * For cached packages this is the sole dependency of
+/// [Entrypoint.workspaceRoot].
+Package activatedPackage(Entrypoint entrypoint) {
+ if (entrypoint.isCachedGlobal) {
+ final dep = entrypoint.workspaceRoot.dependencies.keys.single;
+ return entrypoint.cache.load(entrypoint.lockFile.packages[dep]!);
+ } else {
+ return entrypoint.workspaceRoot;
+ }
+}
diff --git a/test/global/binstubs/binstub_runs_global_run_if_no_snapshot_test.dart b/test/global/binstubs/binstub_runs_global_run_if_no_snapshot_test.dart
index b3a804a..8888c8f 100644
--- a/test/global/binstubs/binstub_runs_global_run_if_no_snapshot_test.dart
+++ b/test/global/binstubs/binstub_runs_global_run_if_no_snapshot_test.dart
@@ -2,6 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import '../../descriptor.dart' as d;
@@ -32,4 +35,60 @@
]),
]).validate();
});
+
+ test(
+ 'the binstubs of hosted package runs pub global run if there is no snapshot',
+ () async {
+ final server = await servePackages();
+ server.serve(
+ 'foo',
+ '1.0.0',
+ contents: [
+ d.dir('bin', [d.file('script.dart', "main() => print('ok');")]),
+ ],
+ pubspec: {
+ 'name': 'foo',
+ 'executables': {'foo-script': 'script'},
+ },
+ );
+
+ await runPub(
+ args: ['global', 'activate', 'foo'],
+ output: contains('Installed executable foo-script.'),
+ );
+
+ await d.dir(cachePath, [
+ d.dir('bin', [
+ d.file(
+ binStubName('foo-script'),
+ contains('global run foo:script'),
+ ),
+ ]),
+ ]).validate();
+
+ // Force refresh of snapshot/binstub
+ Directory(
+ p.join(d.sandbox, cachePath, 'global_packages', 'foo', 'bin'),
+ ).deleteSync(recursive: true);
+ final binstub = p.join(
+ d.sandbox,
+ cachePath,
+ 'bin',
+ 'foo-script${Platform.isWindows ? '.bat' : ''}',
+ );
+ final result =
+ await Process.run(binstub, [], environment: getPubTestEnvironment());
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ expect(result.stdout, contains('ok'));
+
+ await d.dir(cachePath, [
+ d.dir('bin', [
+ d.file(
+ binStubName('foo-script'),
+ contains('global run foo:script'),
+ ),
+ ]),
+ ]).validate();
+ });
}