Airline includes a powerful and extensible restrictions system that allows users to significantly reduce the boiler plate code typical of many CLI libraries. Restrictions work by simply applying appropriate annotations to the @Option
or @Arguments
annotated fields that you wish to restrict and Airline handles all the work of enforcing those restrictions for you.
For example here’s a class representing a UK postal address annotated with appropriate restrictions:
public class PostalAddress {
@Option(name = "--recipient",
title = "Recipient",
description = "Specifies the name of the receipient")
@Required
public String recipient;
@Option(name = "--number",
title = "HouseNumber",
description = "Specifies the house number")
@RequireOnlyOne(tag = "nameOrNumber")
@IntegerRange(min = 0, minInclusive = false)
public Integer houseNumber;
@Option(name = "--name",
title = "HouseName",
description = "Specifies the house name")
@RequireOnlyOne(tag = "nameOrNumber")
@NotEmpty
@NotBlank
public String houseName;
@Option(name = { "-a", "--address", "--line" },
title = "AddressLine",
description = "Specifies an address line. Specify this multiple times to provide multiple address lines, these should be in the order they should be used.")
@Required
@MinOccurrences(occurrences = 1)
public List<String> addressLines = new ArrayList<>();
@Option(name = "--postcode",
title = "PostCode",
description = "Specifies the postcode")
@Required
@Pattern(pattern = "^([A-Z]{1,2}([0-9]{1,2}|[0-9][A-Z])) (\\d[A-Z]{2})$", description = "Must be a valid UK postcode.", flags = java.util.regex.Pattern.CASE_INSENSITIVE)
public String postCode;
}
Here we can see a variety of different restrictions annotations being used. For example we use the @RequireOnlyOne
annotation to require that either a house name or number must be provided. The @MinOccurrences
annotation to require at least one address line and the @Pattern
annotation to enforce postcode validation.
If you’ve ever written a command line application you can quickly see just how much boilerplate code you are avoiding having to write here.
As an additional benefit restrictions automatically interact with the Help system so that option help automatically describes the restrictions that are applicable. Below is the generated help from an example command that uses the above options module:
NAME
ship-it check-address - Check if an address meets our restrictions
SYNOPSIS
ship-it check-address {-a | --address | --line} <AddressLine>...
[ --name <HouseName> ] [ --number <HouseNumber> ] --postcode <PostCode>
--recipient <Recipient>
OPTIONS
-a <AddressLine>, --address <AddressLine>, --line <AddressLine>
Specifies an address line. Specify this multiple times to provide
multiple address lines, these should be in the order they should be
used.
This option must occur a minimum of 1 times
--name <HouseName>
Specifies the house name
This options value cannot be blank (empty or all whitespace)
This options value cannot be empty
This option is part of the group 'nameOrNumber' from which only one
option may be specified
--number <HouseNumber>
Specifies the house number
This options value must fall in the following range: value >0
This option is part of the group 'nameOrNumber' from which only one
option may be specified
--postcode <PostCode>
Specifies the postcode
This options value must match the regular expression
'^([A-Z]{1,2}([0-9]{1,2}|[0-9][A-Z])) (\d[A-Z]{2})$'. Must be a
valid UK postcode.
--recipient <Recipient>
Specifies the name of the receipient
The following annotations are used to specify that options/arguments (or combinations thereof) are required:
@Required
annotation indicates that an option/argument must be specified@RequireSome
annotation indicates that one/more from some set of options must be specified@RequireOnlyOne
annotation indicates that precisely one of some set of options must be specified@MutuallyExclusiveWith
annotation indicates that precisely one of some set of options may be specifiedThe following annotations are used to specify the number of times that options/arguments can be specified:
@Once
annotation indicates that at option/argument may be specified only once@MinOccurrences
annotation indicates that an option/argument must be specified a minimum number of times@MaxOccurrences
annotation indicates that an option/argument may be specified a maximum number of timesThe following annotations are used to specify restrictions on the values for options/arguments:
@AllowedRawValues
annotation specifies a set of strings that may be specified as the value@AllowedValues
annotation specifies a set of values that may be specified as the value@MaxLength
annotation specifies the maximum length of the value that may be given@MinLength
annotation specifies the minimum length of the value that may be given@NotBlank
annotation specifies that a value may not consist entirely of white space@NotEmpty
annotation specifies that the value may not be an empty string@Path
annotation specifies restrictions on values that refer to files and/or directories@Pattern
annotation specifies that a value must match a regular expression@Port
annotation specifies restrictions on values that represent port numbersA further subset of annotations specify restrictions on the values for options/arguments in terms of ranges of acceptable values:
@ByteRange
annotation specifies a range of byte
values that are acceptable@DoubleRange
annotation specifies a range of double
values that are acceptable@FloatRange
annotation specifies a range of float
values that are acceptable@IntegerRange
annotation specifies a range of int
values that are acceptable@LexicalRange
annotation specifies a range of string
values that are acceptable@LongRange
annotation specifies a range of long
values that are acceptable@ShortRange
annotation specifies a range of short
values that are acceptableThe following are special purpose restrictions:
@Unrestricted
annotation indicates that no restrictions apply to the option. Used in conjunction with option overriding to clear restrictions.@Partials/@Partial
annotation is used to apply restrictions to only some parts of options/arguments where multiple values are accepted by those fieldsThe following are Global restrictions which apply over the final parser state:
@CommandRequired
annotation indicates that a command must be specified.@NoMissingOptionValues
annotation indicates that specifying an option without its corresponding value(s) is not permitted.@NoUnexpectedArguments
annotation indicates that any unrecognised inputs are not permitted.Airline includes the ability to create Custom Restrictions which allow you to define and use your own restriction annotations.
This documentation is itself open source and lives in GitHub under the docs/ directory.
I am not a professional technical writer and as the developer of this software I can often make assumptions of
knowledge that you as a user reading this may not have. Improvements to the documentation are always welcome, if you
have suggestions for the documentation please submit pull requests to the main
branch.