Annotation based framework that can be used to quickly set up a Command-Line-Interface.
README is out of date
This library enables a prospective user to quickly configure a command-line interface around an
arbitrary Java application.
Annotate any Java Method with the @Command annotation, and it can be mapped to a
Command
object at runtime.
Each Command
has an optional prefix, one or more distinct names, an optional description,
and an optional enumeration of Arguments.
Here are some examples of usage:
@Command
public void foo() {
// code
}
Here the name field is implicitly set to the name of the method, [ "foo" ]. The description is omitted, as is the enumeration of Arguments.
@Command(name = "foo, -foo", description = "bar")
public void foo() {
// code
}
Here the name field is explicitly set to [ "foo", "-foo" ]. The description field is set to "bar", and the enumeration of Arguments is omitted.
Annotate the Parameters of any @Command annotated Java Method with the @Argument annotation to explicitly set their
name, description, group, and typeConverter properties.
Here are some examples of usage:
@Command
public void foo(
@Argument
String bar
) {
// code
}
Here the name field is implicitly set to [ "bar" ], or [ "arg0" ] depending on compiler options.
The description field is omitted, and the group field is implicitly set to Group.REQUIRED
.
In this example the annotation could have been omitted, and the same configuration
would have been achieved.
@Command
public void foo(
@Argument(name = "-b, --b", description = "bar")
boolean bar
) {
// code
}
Here the name field is explicitly set to [ "-b", "--b" ], and
the description field is set to "bar". The Group field is forcefully set to Group.FLAG
due to the
fact that the Parameter is of type boolean
.
Note that Group.REQUIRED
is the default group for every other type.
@Command
public void foo(
@Argument(typeConverter = BarTypeConverter.class)
Bar bar
) {
// code
}
A user-defined TypeConverter
can be specified by assigning to the typeConverter field a class
which implements the TypeConverter
interface and has a no-args constructor.
Note that the type-safe and preferred way of specifying a user-defined TypeConverter
is
to register it with the CLI
via its Configuration
object.
Built in support exists for primitive types, wrapper classes, and arrays where the component type is either a
primitive type, or a wrapper class.
This field only needs to be specified if the type of the Java Parameter is not one of the
aforementioned.
Limitations exists for types that have one or more parameterized types.
Group.REQUIRED
has the following properties:
- Has to be included when a
Command
is specified for theCommand
to match and execute. - Has no fixed position.
- Has a name.
- Is initialized by including its name together with a value separated by a whitespace character.
Group.OPTIONAL
has the following properties:
- Does not have to be included when a
Command
is specified for theCommand
to match and execute. - Has no fixed position.
- Has a name.
- Has a default value.
- Is initialized by including its name together with a value separated by a whitespace character, or by omission.
Group.FLAG
has the following properties:
- Does not have to be included when a
Command
is specified for theCommand
to match and execute. - Has no fixed position.
- Has a name.
- Has a default value.
- Has a flag value.
- Is initialized by including its name, or by omission.
Group.POSITIONAL
has the following properties:
- Has to be included when a
Command
is specified for theCommand
to match and execute. - Has a fixed relative position.
- Has no name.
- Is initialized by including a value at the Argument's fixed relative position.
Annotate your Class
with the @Controller annotation if it declares any @Command
annotated Java Methods, to give each declared Command
an optional prefix, and to control
the life-cycle of the Objects on which your (non-static) Commands are executed.
Here are some examples of usages:
@Controller(name = ""foo)
public class Foo {
// code
}
You can give each declared Command
a prefix by specifying a
name on the Controller level.
Here the name field is set to "foo".
Note that static Commands will also receive the assigned prefix.
@Controller(Scope.SINGLETON)
public class Foo {
// code
}
You can also specify how instances of your Class
are to be constructed and (re)used.
By specifying a value of type Scope.SINGLETON
on the Controller level,
you're specifying that one instance of your Class
should be used for all subsequent Command
invocations.
If instead a value of type Scope.TRANSIENT
is specified, a new instance will be constructed
prior to each invocation.
Note that your class will only be instantiated if it declares at least one non-static @Command annotated
Java Method.
public class Sample {
public static void main(String[] args) {
CLI cli = new CLI(new Configuration());
cli.accept("--help");
}
}
Input is passed to the CLI
by calling accept(input: String)
.
Unless explicitly told not to, the CLI
will build its declared Help Command
.
Which when invoked will print a view of all of the mapped Commands to the standard
PrintStream
specified by the Configuration
.
public class Sample {
public static void main(String[] args) {
CLI cli = new CLI(new Configuration());
cli.read();
}
}
You can also specify that the CLI
should continuously block and poll for input from the
InputStream
specified by the Configuration
.
coming soon
compileJava {
options.compilerArgs.add("-parameters")
}
coming soon
tbd