A command line parser generator

Overview

core annotations

jbock is a command line parser that works similar to airline and picocli. While most of these other tools scan for annotations at runtime, jbock is an annotation processor and generates Java source code at compile time instead.

Overview

A command line interface is defined by an abstract class which has a @Command annotation. In this class, each abstract method corresponds either to a named option or a positional parameter.

@Command
abstract class MyCommand {

  /**
   * A {@code @Param} is a positional parameter.
   * This particular param is in the front position,
   * since there are no other params in lower positions.
   */
  @Param(0)
  abstract Path path();

  /**
   * An {@code @Option} is a named option.
   */
  @Option("verbosity")
  abstract OptionalInt verbosity();
}

When jbock is properly configured as an annotation processor, the presence of the @Command annotation will trigger a round of code generation at compile time. The generated class will, in this case, be called MyCommand_Parser. It can be used as follows:

String[] args = { "--verbosity=2", "file.txt" }; // sample psvm input
MyCommand c = new MyCommand_Parser().parseOrExit(args);

// Works as expected!
assertEquals(OptionalInt.of(2), c.verbosity());
assertEquals(Paths.get("file.txt"), c.path());

In the MyCommand example, the path parameter is required, while the option verbosity is optional. The property of being either optional or required is called skew. There are four different skews: required, optional, repeatable and flag. In this case, the skew is determined by the return type of the option's or parameter's abstract method, according to the following rules.

Skew rules

These rules apply for options and params that do not define a custom mapper, as in the MyCommand example:

Skew table A

Return type of the abstract method Skew
{boolean,Boolean} flag (only for @Option)
Optional<A> optional
Optional{Int,Long,Double} optional
List<A> repeatable
A (exact match) required

where A must be one of the auto types, otherwise compilation will fail.

Both @Option and @Param have an optional attribute mappedBy which takes a single value of type Class<?>. Any such mapper class must implement Function<String, E> or Supplier<Function<String, E>> for some E.

If a custom mapper is defined, then the skew is determined by comparing the method's return type to the type of its mapper:

Skew table B

Mapper type Return type of the abstract method Skew
Function<String, M> Optional<M> optional
Function<String, {Integer,Long,Double}> Optional{Int,Long,Double} optional
Function<String, M> List<M> repeatable
Function<String, M> M required
Function<String, {Integer,Float,...}> {int,float,...} required

When none of these rules apply, compilation will fail.

Both rule tables can be summarized in a third table:

Skew rules overview

Mapper defined? Skew
No See Skew Table A
Yes See Skew Table B

Sample projects

Comments
  • uncaught validation error in 4.1.000

    uncaught validation error in 4.1.000

    Tested in 4.1.000, affects versions since 4.0.000

    This examples cause an uncaught AssertionError during compilation

    @Command
    abstract class BadCommand {
    
        @Parameters(converter = MyConverter.class)
        abstract Integer something();
    
        static class MyConverter implements Function<String, Integer> {
    
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        }
    }
    
    opened by h908714124 1
  • Add description attribute

    Add description attribute

    All annotations should get an additional attribute "description", similar to jcommander and picocli. Javadoc reading will be a fallback where this attribute is not set.

    opened by h908714124 1
  • Changes in 3.4

    Changes in 3.4

    Rename annotations to make the API more appealing:

    • CommandLineArguments -> ~~CLI~~ Command
    • Parameter -> Option
    • PositionalParameter -> Param
    question 
    opened by h908714124 1
  • Add a Gitter chat badge to README.md

    Add a Gitter chat badge to README.md

    jbock-java/jbock now has a Chat Room on Gitter

    @h908714124 has just created a chat room. You can visit it here: https://gitter.im/jbock-java/jbock-support.

    This pull-request adds this badge to your README.md:

    Gitter

    If my aim is a little off, please let me know.

    Happy chatting.

    PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.

    opened by gitter-badger 0
  • Supplier<E> is compile error

    Supplier is compile error

    Specifying a mapper class which has a type parameter E and implements Supplier<E> leads to an uncaught exception at compile time. Fixed in 59e52bc3b6641d223f003a01d60aac1f739f088d

    bug 
    opened by h908714124 0
  • Error parsing empty string

    Error parsing empty string

    In 2.8.4, and possibly some of the previous 10 or so revisions, the generated code for positional parameters can't handle the empty string, causing a stacktrace and no useful message at runtime. Fixed in d74fb71d1537fb819796319e166ef9403c31d029

    bug 
    opened by h908714124 0
  • Allow free type variable in collector

    Allow free type variable in collector

    If the type of the collector is

    <E, F> Collector<E, ?, List<F>>
    

    so F can be inferred from the parameter but E is still free. This is currently not allowed, but should be. The mapper can be any function that accepts strings, for example:

    Function<String, String>
    <V> Function<String, V>
    <V> Function<V, V>
    <V> Function<V, List<V>>
    <V, T> Function<V, T>
    
    enhancement 
    opened by h908714124 0
  • Get rid of (mandatory) attributes

    Get rid of (mandatory) attributes

    Attributes can always be inferred:

    1. collector absent, mapper returns optional type -> optional
    2. collector absent, mapper returns list -> repeatable
    3. collector absent, mapper returns anything else but boolean -> not optional, not repeatable (~required)
    4. collector present -> repeatable, not optional; explanation:
      1. collector doesn't return optional type -> repeatable, not optional
      2. collector returns optional -> repeatable (otherwise collector won't be used), not optional (otherwise collector won't be used)
    opened by h908714124 0
Releases(5.14)
  • 5.14(Apr 3, 2022)

  • 5.13(Mar 23, 2022)

  • v5.12(Sep 15, 2021)

    • make the default conversion for enums case-insensitive
    • allow directories in file converter
    • remove attribute generateParseOrExit
    • add attribute skipGeneratingParseOrExit
    Source code(tar.gz)
    Source code(zip)
  • v5.11(Aug 26, 2021)

  • v5.10(Aug 19, 2021)

  • v5.9(Aug 6, 2021)

    • BUGFIX Invalid code is generated when an unannotated abstract method has at least one parameter. The bug was introduced in v5.7 and is fixed in v5.9.
    • Improve some error messages.
    Source code(tar.gz)
    Source code(zip)
  • v5.8(Aug 5, 2021)

    In order to avoid certain staleness problems with gradle's "isolating" annotation processing model, some features had to be removed.

    • Remove the Converter annotation.
    • The converter attribute must now point to a static member class of the command class (see note).
    • Forbid inheritance of abstract methods.

    Note: Effectively, it is still possible to define a "standalone" converter class, by writing a small static inner class which implements Supplier<StringConverter<X>> and returns an instance of the "real" converter class from its get method. For example, see how BigIntegerConverter is used in CustomConverterCommand.

    Source code(tar.gz)
    Source code(zip)
  • v5.7(Aug 3, 2021)

    • allow abstract overrides
    • improve parameters-validation error message
    • forbid StringConverter of Optional
    • improve invalid position error message
    Source code(tar.gz)
    Source code(zip)
  • v5.6(Jul 22, 2021)

  • v5.5(Jul 13, 2021)

  • v5.4(Jul 9, 2021)

  • v5.3(Jul 7, 2021)

  • v5.2(Jul 5, 2021)

    • depend on io.github.jbock-java:either:1.0
    • new attribute generateParseOrExitMethod
    • remove attributes atFileExpansion and helpEnabled; configure the ParseRequest instead
    • fix formatting in generated character converter
    • improve at-file syntax: ignore all empty lines, allow quoting
    • add support for alternative Optional types: vavr
    • the generated parse method now takes an argument of type ParseRequest
    • use 4-space indentation for all source files
    Source code(tar.gz)
    Source code(zip)
  • core_5.1(Jun 21, 2021)

    jbock 5.1 "midsummer edition"

    • removed ansi attribute from Command, it is now a runtime config in StandardErrorHandler
    • remove redundant attribute exithook from StandardErrorHandler; custom exit logic can now be implemented without this; see implementation of generated method parseOrExit
    • add attribute unixClustering to CommandModel
    • fix: atFileExpansion = false didn't compile
    • fix: potential infinite loop at compile time, in EnumName logic
    • allow additional tokens after at file expansion
    • refactoring: avoid lambdas in generated method StatefulParser#build, extract convert logic for enums, File and char to inner classes
    Source code(tar.gz)
    Source code(zip)
  • compiler_5.0(Jun 11, 2021)

    • Changed the maven group name to io.github.jbock-java
    • Renamed the artifacts: "jbock-annotations" -> "jbock" (aka "core"), "jbock" -> "jbock-compiler".
    • moved the Either library into core
    • add runtime model of the annotated class (net.jbock.model.CommandModel)
    • parse now returns an Either
    • rename the generated class, "*_Parser" -> "*Parser"
    • SuperCommand is now an attribute
    • add the atFileExpansion attribute
    • add the unixClustering attribute
    • runtime config, like terminalWidth, works differently (see implementation of parseOrExit)
    Source code(tar.gz)
    Source code(zip)
  • v4.4.000(May 24, 2021)

  • a4.4(May 27, 2021)

  • v4.3.002(May 22, 2021)

  • v4.3.001(May 21, 2021)

  • v4.3.000(May 21, 2021)

  • a4.3(May 21, 2021)

  • v4.2.000(May 12, 2021)

  • a4.2(May 11, 2021)

  • v4.1.001(May 9, 2021)

  • v4.1.000(May 6, 2021)

  • a4.1(May 6, 2021)

  • v4.0.001(May 4, 2021)

  • v4.0.000(May 4, 2021)

  • a4.0(May 4, 2021)

    Make annotations more similar to jcommander and picocli:

    • @Param(0) -> @Parameter(index = 0)
    • @Option("foo") -> @Option(names = "--foo")
    • @Parameters for repeatable positional parameters
    Source code(tar.gz)
    Source code(zip)
  • v3.6.006(May 1, 2021)

Owner
H90
H90
Java annotation-based framework for parsing Git like command line structures

Airline Airline is a Java annotation-based framework for parsing Git like command line structures. Latest release is 0.8, available from Maven Central

null 847 Nov 26, 2022
Command line parsing framework for Java

JCommander This is an annotation based parameter parsing framework for Java 8. Here is a quick example: public class JCommanderTest { @Parameter

Cedric Beust 1.8k Dec 29, 2022
Command-line API for Atlassian JIRA using the Tomitribe CREST library

Atlassian JIRA Command-Line (CLI) Jamira is a command-line API for Atlassian JIRA using the Tomitribe CREST library. Installation Jamira can be downlo

Tomitribe 12 Sep 10, 2022
DeV Tools - Swiss Army Knife of command line utilities

dvt aims to bundle all small utilities used by developers (typically a mix of cli and online tools) into one binary that you can simply use in the console. No need for complex pipe-ing, copy-pasting on different sites or keep installing cli utilities for every need.

Madalin Ilie 13 Sep 15, 2022
AWS JSON TRANSLATOR CLI is a command line application to translate JSON files using AWS Translate

A command line tool to translate JSON files using AWS Translate.

Marc Guillem 0 May 30, 2022
Wrapper around ping command for Windows and MacOS

Wrapper around ping command for Windows and MacOS. Extended with functionality to intercept results provided by the ping command output (latency, ttl and etc.)

Vladislav Kozlov 1 Jan 6, 2022
Annotation-based command framework for Minestom

Minestand Annotation-based command framework for Minestom Advantages over other frameworks Minestand works by converting your classes into Minestom co

null 6 Aug 27, 2022
Reflectionless command line parser

jbock is a command line parser, which uses the same annotation names as JCommander and picocli. However it does not use reflection. It is an annotatio

null 74 Jan 4, 2023
A simple command-line argument parser for Java applications that relies on records.

RecordArgs A simple command-line argument parser for Java applications that relies on records. Specifically, it uses their component names to parse co

Nicolai Parlog 8 Apr 4, 2022
TransitScheduler - a command line tool that can read .json data formulated for tracking transit patterns to a multithreaded concurrent simulation of passengers boarding and unboarding trains that constantly move to the next station on the line. The trick here, is that two trains cannot occupy the same station at any time.

TransitScheduler - a command line tool that can read .json data formulated for tracking transit patterns to a multithreaded concurrent simulation of passengers boarding and unboarding trains that constantly move to the next station on the line. The trick here, is that two trains cannot occupy the same station at any time.

Emmet Hayes 1 Dec 2, 2022
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files.

ANTLR v4 Build status ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating

Antlr Project 13.6k Dec 28, 2022
JavaCC - a parser generator for building parsers from grammars. It can generate code in Java, C++ and C#.

JavaCC Java Compiler Compiler (JavaCC) is the most popular parser generator for use with Java applications. A parser generator is a tool that reads a

null 971 Dec 27, 2022
A fast JSON parser/generator for Java.

fastjson Fastjson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON str

Alibaba 25.1k Dec 31, 2022
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files.

ANTLR v4 Build status ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating

Antlr Project 13.6k Jan 3, 2023
Rekex parser generator - grammar as algebraic datatypes

Rekex PEG parser generator for Java 17 grammar as algebraic datatypes A context-free grammar has the form of A = A1 | A2 A1 = B C ... which looks ex

Zhong Yu 41 Dec 18, 2022
A JNI code generator based on the JNI generator used by the eclipse SWT project

HawtJNI Description HawtJNI is a code generator that produces the JNI code needed to implement java native methods. It is based on the jnigen code gen

FuseSource 153 Nov 17, 2022
Log4j-payload-generator - Log4j jndi injects the Payload generator

0x01 简介 log4j-payload-generator是 woodpecker框架 生产log4 jndi注入漏洞payload的插件。目前可以一键生产以下5类payload。 原始payload {[upper|lower]:x}类型随机混payload {[upper|lower]:x}

null 469 Dec 30, 2022
OpenApi Generator - REST Client Generator

Quarkus - Openapi Generator Welcome to Quarkiverse! Congratulations and thank you for creating a new Quarkus extension project in Quarkiverse! Feel fr

Quarkiverse Hub 46 Jan 3, 2023
Java annotation-based framework for parsing Git like command line structures

Airline Airline is a Java annotation-based framework for parsing Git like command line structures. Latest release is 0.8, available from Maven Central

null 847 Nov 26, 2022