Validate package name in `pub global activate` (#3735)
diff --git a/lib/src/command/global_activate.dart b/lib/src/command/global_activate.dart index 1cb8438..8fdbc46 100644 --- a/lib/src/command/global_activate.dart +++ b/lib/src/command/global_activate.dart
@@ -7,7 +7,10 @@ import 'package:pub_semver/pub_semver.dart'; import '../command.dart'; +import '../command_runner.dart'; +import '../io.dart'; import '../package_name.dart'; +import '../pubspec.dart'; import '../utils.dart'; /// Handles the `global activate` pub command. @@ -148,6 +151,14 @@ } validateNoExtraArgs(); + + if (!packageNameRegExp.hasMatch(package)) { + final suggestion = dirExists(package) + ? '\n\nDid you mean `$topLevelProgram pub global activate --source path ${escapeShellArgument(package)}`?' + : ''; + + usageException('Not a valid package name: "$package"$suggestion'); + } return globals.activateHosted( ref.withConstraint(constraint), executables,
diff --git a/test/global/activate/activate_hosted_test.dart b/test/global/activate/activate_hosted_test.dart new file mode 100644 index 0000000..c7d3ba9 --- /dev/null +++ b/test/global/activate/activate_hosted_test.dart
@@ -0,0 +1,23 @@ +// Copyright (c) 2014, 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'; +import 'package:test/test.dart'; + +import '../../descriptor.dart'; +import '../../test_pub.dart'; + +void main() { + test('activating an invalid package name fails nicely', () async { + await appDir().create(); + await runPub( + args: ['global', 'activate', '.'], + error: allOf( + contains('Not a valid package name: "."'), + contains('Did you mean `dart pub global activate --source path .'), + ), + exitCode: USAGE, + ); + }); +}