Option

A Command option is defined by either an Option annotation or an OptionBuilder object. In this document we will focus on the annotations and its values. Æsh support several different options types each with defined as a seperate annotation. The differen annotations:

  • Option

    • The most common type with a specific name which can have one value (or none)

  • OptionList

    • The difference between Option and OptionList is that OptionList can have multiple values, by default the value separator is , (comma).

  • OptionGroup

    • OptionGroup is similar to OptionList, but it support specific name for each attribute. Eg: -DXm=100, where D is the option name, where Xm is given the value 100.

  • Arguments

    • Arguments is almost identical to OptionList except that it do not have a name. Arguments is required for commands that want argument options.

Common Option attributes

  • All the option types have a name and short name (except Arguments). Name is required, if no name is not provided Æsh will use the field name as the name. Æsh will be default add -- in front of each name on the command line, this is not possible to change. Short name is optional and if defined Æsh will add a - in front on the command line.

  • description and argument are both used for documentation and when Æsh generates info based on the metadata.

  • required specifies if this option is required to be set.

  • defaultValue will be displayed during completion (if it matches)

  • hasValue specifies if this option accept values. This option can only be set to true when the field type is boolean/Boolean. This attribute is only for the Option type.

  • overrideRequired will override missing required options. Very useful for help options etc.

Converter

All Option types have a Converter which is used to convert the input value (String) to the specific field object type. Æsh provides converters for:

  • Boolean/boolean

  • Byte/byte

  • Character/char

  • Double/double

  • File

  • Float/float

  • Integer/int

  • Long/long

  • Short/short

  • String

Any other object type need a specific converter. - and remember the converter must have a public constructor with no arguments.

OptionCompleter

A Completer is optional, but for better user experience we recommend that Completers are used. Æsh provide completers for:

  • File

  • Boolean

  • Default values

As Converters the Completer implementation must have a public constructor with no arguments.

OptionValidator

OptionValidator is called just before Command.execute(…) and is used to ensure that the value given by the user is valid. OptionValidator is optional, but as with the attributes above we recommend that it is used.

OptionActivator

Some options might depend on another option value to be set or a specific value before the option is "visible". By defining an OptionValidator you can define a specific logic that will trigger the visibility of the option. This attribute is highly optional.

OptionRenderer

With OptionRenderer you can specify how a specific option should look. Eg you can change the text color/background color and text type.

TestCommand.java
@CommandDefinition(name="ls", description = "[OPTION]... [FILE]...")
public static class TestCommand implements Command {

    @Option(shortName = 'f', hasValue = false, description = "set foo to true/false")
    private Boolean foo;

    @Option(hasValue = false, description = "set the bar", renderer = BlueBoldRenderer.class)
    private boolean bar;

    @Option(completer = TestCompleter.class, defaultValue = {"MORE"}, argument = "SIZE")
    private String less;

    @OptionList(defaultValue = "/tmp", description = "file location", valueSeparator = ':',
            validator = DirectoryValidator.class,
            activator = BarActivator.class)
    List<File> files;

    @Option(hasValue = false, description = "display this help and exit")
    private boolean help;

    @Arguments
    private List<File> arguments;

    @Override
    public CommandResult execute(CommandInvocation commandInvocation) throws IOException, InterruptedException {
        if(help) {
            commandInvocation.getShell().out().println(commandInvocation.getHelpInfo("ls"));
        }
        else {
            if(foo)
                commandInvocation.getShell().out().println("you set foo to: " + foo);
            if(bar)
                commandInvocation.getShell().out().println("you set bar to: " + bar);
            if(less != null)
                commandInvocation.getShell().out().println("you set less to: " + less);
            if(files != null)
                commandInvocation.getShell().out().println("you set file to: " + files);

            if(arguments != null) {
                for(File f : arguments)
                    commandInvocation.getShell().out().println(f.toString());
            }
        }
        return CommandResult.SUCCESS;
    }
}

public static class TestCompleter implements OptionCompleter {

    @Override
    public void complete(CompleterData completerData) {
        List<String> completeList = new ArrayList<String>();
        if(completerData.getGivenCompleteValue() == null ||
           completerData.getGivenCompleteValue().length() == 0)
            completeList.add("1");
        else {
            char lastChar =
                completerData.getGivenCompleteValue().charAt(completerData.getGivenCompleteValue().length()-1);
            if(Character.isDigit(lastChar)) {
                int i = (int) lastChar;
                i++;
                completeList.add(completerData.getGivenCompleteValue()+i);
            }
        }
    }
}

public static class DirectoryValidator implements OptionValidator<File> {
    @Override
    public void validate(File value) throws OptionValidatorException {
        if(!value.isDirectory()) {
            throw new OptionValidatorException("File validation failed, must be a directory.");
        }
    }
}

public static class BarActivator implements OptionActivator {

    @Override
    public boolean isActivated(ProcessedCommand processedCommand) {
        ProcessedOption bar = processedCommand.findLongOption("bar");
        if(bar != null && bar.getValue() != null)
            return true;
        else
            return false;
    }
}

public static class BlueBoldRenderer implements OptionRenderer {

    private static TerminalTextStyle style = new TerminalTextStyle(CharacterType.UNDERLINE);
    private static TerminalColor color = new TerminalColor(42, Color.DEFAULT);

    @Override
    public TerminalColor getColor() {
        return color;
    }

    @Override
    public TerminalTextStyle getTextType() {
        return style;
    }
}
back to top