io.github.maxnz:interactive-command-parser

Parse commands from an interactive command line

License

License

GroupId

GroupId

io.github.maxnz
ArtifactId

ArtifactId

interactive-command-parser
Last Version

Last Version

0.1
Release Date

Release Date

Type

Type

jar
Description

Description

io.github.maxnz:interactive-command-parser
Parse commands from an interactive command line
Project URL

Project URL

https://github.com/maxnz/InteractiveCommandParser
Source Code Management

Source Code Management

https://github.com/maxnz/InteractiveCommandParser

Download interactive-command-parser

How to add to project

<!-- https://jarcasting.com/artifacts/io.github.maxnz/interactive-command-parser/ -->
<dependency>
    <groupId>io.github.maxnz</groupId>
    <artifactId>interactive-command-parser</artifactId>
    <version>0.1</version>
</dependency>
// https://jarcasting.com/artifacts/io.github.maxnz/interactive-command-parser/
implementation 'io.github.maxnz:interactive-command-parser:0.1'
// https://jarcasting.com/artifacts/io.github.maxnz/interactive-command-parser/
implementation ("io.github.maxnz:interactive-command-parser:0.1")
'io.github.maxnz:interactive-command-parser:jar:0.1'
<dependency org="io.github.maxnz" name="interactive-command-parser" rev="0.1">
  <artifact name="interactive-command-parser" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.github.maxnz', module='interactive-command-parser', version='0.1')
)
libraryDependencies += "io.github.maxnz" % "interactive-command-parser" % "0.1"
[io.github.maxnz/interactive-command-parser "0.1"]

Dependencies

compile (1)

Group / Artifact Type Version
org.jetbrains.kotlin : kotlin-stdlib-jdk8 jar 1.3.72

test (2)

Group / Artifact Type Version
org.jetbrains.kotlin : kotlin-test-junit jar 1.3.72
org.junit.jupiter : junit-jupiter-api jar 5.5.2

Project Modules

There are no modules declared in this project.

Interactive Command Line Parser

Build Status codecov Maven Central

Parse commands from an interactive command line. When a valid command is entered, the associated "action" will be run. Commands can be abbreviated as much as desired provided they still identify a unique command.

Usage

Creating the Parser

A parser takes two template arguments:

  • The type of the receiver that the actions will be run on
  • The type of the argument that will be passed to all actions
class Receiver          // Example class

val r = Receiver()

val parser = CommandParser<Receiver, Int>(r)

Creating Commands

To specify a command that can be entered, use the command builder.

parser.command("cmd") {}

Use the action builder to set what happens when the command is run. The action is passed two arguments:

  • The argument that was passed to the parser
  • A list of the remaining arguments on the command line

Note that the action must be defined before the command is called, otherwise an UninitializedPropertyAccessException will be thrown.

parser.command("cmd") {
    
    // arg is the argument that was passed to the parser
    // args is a list of the remaining arguments on the command line
    action { arg, args ->
        // do something
    }
}

To specify a command that has sub-commands, create a command group with the commandGroup builder. Then use the command builder to specify the sub-commands.

parser.commandGroup("grp") {
    command("sub") {}           // run using "grp sub"
}

Parsing Commands

To parse a command, pass the string containing the command to parseString(), along with the value to pass to the action. Any remaining arguments will be passed to the action in a list.

parser.parseString("cmd", 5)            // The 5 will be passed to the action as arg
parser.parseString("cmd arg1 arg2", 5)  // arg1 and arg2 will be passed as part of args
parser.parseString("grp sub", 5)        // Call a sub-command

Parsing Errors

There are four outcomes from parsing identified in the ParseResult enum:

  • SUCCESS: A command was found and its action was executed
  • BAD_COMMAND: A command could not be found that matched the arguments given
  • COMMAND_NEEDS_SUBCOMMAND: The command called is a command group and requires a sub-command
  • TOO_MANY_MATCHING_COMMANDS: The command called does not match a unique command (e.g. given two defined commands test and tea, passing te does not identify a unique command, while passing tes would identify test)

Parsing Error Callbacks

The three error cases have callbacks that are used to print or send the error message to the right place. It is up to the user to set these callbacks, whether it is printing to the terminal or sending to a socket or something else.

The callbacks are passed two arguments:

  • The argument that was passed to the parser that would have been passed to a command's action
  • The message detailing the error

The callbacks are as follows:

  • BAD_COMMAND -> badCommandAction
  • COMMAND_NEEDS_SUBCOMMAND -> commandNeedsSubCommandAction
  • TOO_MANY_MATCHING_COMMANDS -> tooManyMatchingCommandsAction
Help Message Callback

There is a fourth callback for printing the help message called helpMessageAction.

This is done because the help command is pre-defined and this allows the user to specify what that command will actually do with the message.

Help Messages

The library can automatically generate a help message for your parser when you parse the command help. The commands are sorted alphabetically in the help message.

To set a description for a command, set the description property.

parser.command("ex") {
    description = "Describe the command here"
}

// This also works for command groups
parser.commandGroup("ex-grp") {
    description = "Describe the group of commands here"
}

If your command takes one or more arguments, you can specify that using the argHelpStr property. Note that the library does NOT check the number of or type of arguments, that is left to the user.

parser.command("i-have-args") {
    argHelpStr = "ARG"
}

A paragraph can be added at the beginning of the help message by setting the parser's helpParagraph property.

parser.helpParagraph = "Help paragraph for this parser"

To specify where to send the help message, set the helpMessageAction (see Help Message Callback).

Example

The following parser definition would create the following help message:

parser.apply {
    helpParagraph = "Test Commands"    

    command("example1") {
        description = "Test command 1"
    }
    command("testTestTestTestTest2") {
        description = "Test command 2"
    }
    command("tttttttttttttttttt") {
        description = "Test command 3"
    }
    command("test4") {
        description = "Test command 4"
        argHelpStr = "T"
    }
    command("testTestTest5") {
        description = "Test command 5"
        argHelpStr = "TTTTTT"
    }
    commandGroup("test6") {
        description = "Test command 6"

        command("sub6-1") {
            description = "SubCommand 6-1"
        }
        command("sub6-2") {
            description = "SubCommand 6-2"
        }
    }
    commandGroup("tt") {
        description = "Test command 7"

        command("ttt") {
            description = "SubCommand 7"
        }
    }
}
Test Commands

Commands:
example1          Test command 1
help              Print this help message
test4 T           Test command 4
test6 {sub6-1, sub6-2}
                  Test command 6
test6 sub6-1      SubCommand 6-1
test6 sub6-2      SubCommand 6-2
testTestTest5 TTTTTT
                  Test command 5
testTestTestTestTest2
                  Test command 2
tt {ttt}          Test command 7
tt ttt            SubCommand 7
tttttttttttttttttt
                  Test command 3

Versions

Version
0.1