Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Simplify extractCommandNameArgument #2844

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions source/dub/commandline.d
Original file line number Diff line number Diff line change
Expand Up @@ -82,44 +82,58 @@
args = a list of string arguments that will be processed

Returns:
A structure with two members. `value` is the command name
`remaining` is a list of unprocessed arguments
The command name that was found (may be null).
*/
auto extractCommandNameArgument(string[] args)
string commandNameArgument(ref string[] args)
{
struct Result {
string value;
string[] remaining;
}

if (args.length >= 1 && !args[0].startsWith("-") && !args[0].canFind(":")) {
return Result(args[0], args[1 .. $]);
const result = args[0];
args = args[1 .. $];
return result;
}

return Result(null, args);
return null;
}

/// test extractCommandNameArgument usage
unittest {
/// It returns an empty string on when there are no args
assert(extractCommandNameArgument([]).value == "");
assert(extractCommandNameArgument([]).remaining == []);

/// It returns the first argument when it does not start with `-`
assert(extractCommandNameArgument(["test"]).value == "test");
{
string[] args;
/// It returns an empty string on when there are no args
assert(commandNameArgument(args) is null);
assert(!args.length);
}

/// There is nothing to extract when the arguments only contain the `test` cmd
assert(extractCommandNameArgument(["test"]).remaining == []);
{
string[] args = [ "test" ];
/// It returns the first argument when it does not start with `-`
assert(commandNameArgument(args) == "test");
/// There is nothing to extract when the arguments only contain the `test` cmd
assert(!args.length);
}

/// It extracts two arguments when they are not a command
assert(extractCommandNameArgument(["-a", "-b"]).remaining == ["-a", "-b"]);
{
string[] args = [ "-a", "-b" ];
/// It extracts two arguments when they are not a command
assert(commandNameArgument(args) is null);
assert(args == ["-a", "-b"]);
}

/// It returns the an empty string when it starts with `-`
assert(extractCommandNameArgument(["-test"]).value == "");
{
string[] args = [ "-test" ];
/// It returns the an empty string when it starts with `-`
assert(commandNameArgument(args) is null);
assert(args.length == 1);
}

// Sub package names are ignored as command names
assert(extractCommandNameArgument(["foo:bar"]).value == "");
assert(extractCommandNameArgument([":foo"]).value == "");
{
string[] args = [ "foo:bar" ];
// Sub package names are ignored as command names
assert(commandNameArgument(args) is null);
assert(args.length == 1);
args[0] = ":foo";
assert(commandNameArgument(args) is null);
assert(args.length == 1);
}
}

/** Handles the Command Line options and commands.
Expand Down Expand Up @@ -464,14 +478,12 @@

// extract the command
args = common_args.extractAllRemainingArgs();

auto command_name_argument = extractCommandNameArgument(args);

auto command_args = new CommandArgs(command_name_argument.remaining);
const command_name = commandNameArgument(args);
auto command_args = new CommandArgs(args);

Check warning on line 482 in source/dub/commandline.d

View check run for this annotation

Codecov / codecov/patch

source/dub/commandline.d#L481-L482

Added lines #L481 - L482 were not covered by tests
Command cmd;

try {
cmd = handler.prepareCommand(command_name_argument.value, command_args);
cmd = handler.prepareCommand(command_name, command_args);

Check warning on line 486 in source/dub/commandline.d

View check run for this annotation

Codecov / codecov/patch

source/dub/commandline.d#L486

Added line #L486 was not covered by tests
} catch (Exception e) {
logError("Error processing arguments: %s", e.msg);
logDiagnostic("Full exception: %s", e.toString().sanitize);
Expand All @@ -482,14 +494,14 @@
if (cmd is null) {
logInfoNoTag("USAGE: dub [--version] [<command>] [<options...>] [-- [<application arguments...>]]");
logInfoNoTag("");
logError("Unknown command: %s", command_name_argument.value);
logError("Unknown command: %s", command_name);

Check warning on line 497 in source/dub/commandline.d

View check run for this annotation

Codecov / codecov/patch

source/dub/commandline.d#L497

Added line #L497 was not covered by tests
import std.algorithm.iteration : filter;
import std.uni : toUpper;
foreach (CommandGroup key; handler.commandGroups)
{
foreach (Command command; key.commands)
{
if (levenshteinDistance(command_name_argument.value, command.name) < 4) {
if (levenshteinDistance(command_name, command.name) < 4) {

Check warning on line 504 in source/dub/commandline.d

View check run for this annotation

Codecov / codecov/patch

source/dub/commandline.d#L504

Added line #L504 was not covered by tests
logInfo("Did you mean '%s'?", command.name);
}
}
Expand Down
Loading