Skip to content
This repository was archived by the owner on Oct 17, 2024. It is now read-only.

Commit b08471e

Browse files
authored
Suggest command based on aliases (#235)
1 parent bd3ac85 commit b08471e

5 files changed

+73
-6
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 2.4.0
2+
3+
* Command suggestions will now also suggest based on aliases of a command.
4+
* Introduce getter `Command.suggestionAliases` for names that cannot be used as
5+
aliases, but will trigger suggestions.
6+
17
## 2.3.2
28

39
* Require Dart 2.18

lib/command_runner.dart

+22-4
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,17 @@ class CommandRunner<T> {
220220
SplayTreeSet<Command<T>>((a, b) => distances[a]! - distances[b]!);
221221
for (var command in commands) {
222222
if (command.hidden) continue;
223-
var distance = _editDistance(name, command.name);
224-
if (distance <= suggestionDistanceLimit) {
225-
distances[command] = distance;
226-
candidates.add(command);
223+
for (var alias in [
224+
command.name,
225+
...command.aliases,
226+
...command.suggestionAliases
227+
]) {
228+
var distance = _editDistance(name, alias);
229+
if (distance <= suggestionDistanceLimit) {
230+
distances[command] =
231+
math.min(distances[command] ?? distance, distance);
232+
candidates.add(command);
233+
}
227234
}
228235
}
229236
if (candidates.isEmpty) return '';
@@ -412,6 +419,17 @@ abstract class Command<T> {
412419
/// This is intended to be overridden.
413420
List<String> get aliases => const [];
414421

422+
/// Alternate non-functional names for this command.
423+
///
424+
/// These names won't be used in the documentation, and also they won't work
425+
/// when invoked on the command line. But if an unknown command is used it
426+
/// will be matched against this when creating suggestions.
427+
///
428+
/// A name does not have to be repeated both here and in [aliases].
429+
///
430+
/// This is intended to be overridden.
431+
List<String> get suggestionAliases => const [];
432+
415433
Command() {
416434
if (!argParser.allowsAnything) {
417435
argParser.addFlag('help',

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: args
2-
version: 2.3.2
2+
version: 2.4.0
33
description: >-
44
Library for defining parsers for parsing raw command-line arguments into a set
55
of options and values using GNU and POSIX style options.

test/command_runner_test.dart

+22
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,28 @@ Did you mean one of these?
481481
throwsUsageException(
482482
'Could not find a command named "hidde".', anything));
483483
});
484+
485+
test('Suggests based on aliases', () {
486+
var command = AliasedCommand();
487+
runner.addCommand(command);
488+
expect(() => runner.run(['rename']), throwsUsageException('''
489+
Could not find a command named "rename".
490+
491+
Did you mean one of these?
492+
aliased
493+
''', anything));
494+
});
495+
496+
test('Suggests based on suggestedAliases', () {
497+
var command = SuggestionAliasedCommand();
498+
runner.addCommand(command);
499+
expect(() => runner.run(['renamed']), throwsUsageException('''
500+
Could not find a command named "renamed".
501+
502+
Did you mean one of these?
503+
aliased
504+
''', anything));
505+
});
484506
});
485507

486508
group('with --help', () {

test/test_utils.dart

+22-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,28 @@ class AliasedCommand extends Command {
266266
final takesArguments = false;
267267

268268
@override
269-
final aliases = const ['alias', 'als'];
269+
final aliases = const ['alias', 'als', 'renamed'];
270+
271+
@override
272+
void run() {
273+
hasRun = true;
274+
}
275+
}
276+
277+
class SuggestionAliasedCommand extends Command {
278+
bool hasRun = false;
279+
280+
@override
281+
final name = 'aliased';
282+
283+
@override
284+
final description = 'Set a value.';
285+
286+
@override
287+
final takesArguments = false;
288+
289+
@override
290+
final suggestionAliases = const ['renamed'];
270291

271292
@override
272293
void run() {

0 commit comments

Comments
 (0)