Changelog

Release history for Crest.

A summary of features and significant enhancements in each release.

0.51

  • The descriptor goal can scan dependencies. Set scanDependencies to true on the crest-maven-plugin and every runtime-scope dependency is scanned alongside the module’s own classes. That is the same artifact set maven-shade-plugin inlines, so commands living in a library you depend on land in crest-commands.txt without that library shipping a descriptor of its own. Unpackaged reactor modules are scanned as directories, the Crest runtime itself is skipped, and excludes apply to everything found.
  • @GlobalOptions classes are found by the descriptor goal. They previously had to be listed by hand in includes.
  • @Command usage is validated at startup. A @Command method that is not public, or is abstract, could never be invoked and was silently ignored. Crest now rejects the class with an InvalidCommandUsageException that lists every offending method across the class, its superclasses and its interfaces, and says what is wrong with each.
  • Class-level @Command with no @Command methods is rejected with a message saying exactly that, instead of being mistaken for an interceptor and failing with a @CrestInterceptor not found error.
  • A class returned more than once is registered once. Several Loaders, or a crest-commands.txt merged from several jars, can list the same class. The repeat no longer fails with interceptor is conflicting.

0.50

  • Interceptor instances come from the TargetProvider. Main obtains interceptor instances through the same TargetProvider it uses for commands, so a custom provider — an IoC container, for example — can construct an interceptor with dependencies it could never receive through a no-arg constructor. The default provider is unchanged: interceptors are still instantiated reflectively via their no-arg constructor.

0.49

  • Interceptors accept the full injectable parameter suite. Beyond CrestContext, @Option parameters and @Options beans, a @CrestInterceptor method may now declare @In InputStream, @Out/@Err PrintStream, Environment, and any registered service — everything a command method can inject. Only positional parameters remain illegal, and the error names the offending parameter and the exact annotation to add (#133).
  • Help composes one document from every participant. The man page DESCRIPTION is assembled from the command method’s javadoc, its @Options beans, and each interceptor in the chain in the order they run. Option descriptions resolve the same way, with the earliest declarer winning when several document the same option, so an interceptor-contributed option is documented by the interceptor that declares it (#134).
  • ARGUMENTS section on man pages. Positional arguments are listed in invocation order with the @param text written at their declaring site — the command method for its own positionals, the bean constructor for bean-sourced ones. The section renders when at least one positional is documented; injected parameters never appear (#144).
  • Inline javadoc tags are translated at capture time: {@code}/{@literal} reduce to their content, {@link}/{@linkplain} to the label or shortened reference, {@value} to the resolved constant. Unknown tags drop their braces and keep their text, so a raw {@ can never reach rendered help (#139).
  • Javadoc captured for interceptors and @Options beans. The annotation processor now stores javadoc for @CrestInterceptor methods and for @Options/@GlobalOptions beans — including nested beans — keyed so the runtime can resolve them from the method or parameter type alone (#135).
  • Modernized archetype. The generated project has no main() of its own: org.tomitribe.crest.Main is the entry point, the descriptor goal records commands at build time, and the executable goal turns the shaded jar into ./target/<artifactId>. The sample command demonstrates javadoc-sourced help, an enum option, and a typed positional argument so the usage line reads greet [options] Name (#138).
  • Annotation processing explicitly enabled with -proc:full. JDK 23+ javac no longer runs processors found on the class path, which silently produced jars with no processor registration and no javadoc help (#143).
  • [options] in the SYNOPSIS now reflects the linked option spec, so interceptor-contributed options count (#136).
  • Fix preformatted lines starting with a dash being parsed as bullets (#140).
  • HelpProcessor declares SourceVersion.latestSupported(), ending the RELEASE_6 warnings on every consumer compile (#141).
  • README and installation docs updated to the archetype’s modern recipe (#142).
  • Whole-document help test suite covering interceptors, beans, global options, precedence, preformatted text, and sparse javadoc (#137).

0.48

  • Interceptors can declare options. The @CrestInterceptor method may take @Option parameters and @Options beans alongside its CrestContext. Declared options parse from the command line, appear in help and bash completion, and are passed to the interceptor at execution — the command method does not need to declare them. A command and interceptor declaring the identical option (same name, type, and default) share one value; conflicting declarations fail at deploy time naming both parties.
  • CrestContext.getOptions() — the mutable option namespace of the invocation, keyed by option name: every option declared by the command or any interceptor bound to it. Where the command declares the option, the entry is a live view over the same storage as getParameters(). Replacing a value is seen by every interceptor later in the chain and by the command itself; writes are type checked against the declared option type. @Options beans are derived values, rebuilt from their constituents when one is replaced.
  • @Priority for interceptor ordering. Double-valued: lower runs first (outermost), unannotated interceptors run at 5, ties keep declaration order. The valid range is greater than 0 and less than 11 — the endpoints are deliberately excluded so there is always room to slot a new interceptor before or after any existing priority without renumbering: between 6 and 7 there is 6.5, before 1 there is 0.9.
  • Deploy-time interceptor binding. Bindings resolve when the Main is constructed: an unresolved custom annotation, a class with no @CrestInterceptor method, an out-of-range priority, or an option conflict fails at startup instead of on first invocation.
  • Interceptors run once even when reachable through several bindings on the same command, e.g. an interceptor class carrying two custom annotations both used on the method.
  • Bash completion now offers the constituent options of @Options bean parameters and interceptor-declared options.
  • toolz demo module.

0.47

  • tomitribe-crest-util module with a generic include/exclude regex Filter for list commands.
  • Commands can see which fields will be visible in table output.
  • Update to tomitribe-util 1.5.14.

0.46

  • Fix wrong javadoc description resolved for a method (#131).

0.45

  • Wrap long command descriptions in listings.
  • Omit groups from recursive listings.

0.44

  • Expanded help documentation and fully rendered examples.
  • Don’t show the help suggestion on man-page style output.
  • Fix javadoc bullet indentation/continuation (#129).

0.43

  • help --all lists every command in the CLI as a flat, full-path listing. help <group> --all scopes the listing to a subtree, and help <group> (or bare-group invocation) now defaults to recursive. Groups appear inline alongside leaves so the structure is self-documenting at every level.
  • Help: section added to listings and man pages, surfacing help --all and help <command> so users discover detailed help even when they don’t already know it exists. On a leaf’s man page the hint shows the actual command path, copy-paste ready.
  • Unlimited sub-command depth in the help command. Varargs collapsed four help() overloads into one and now navigate paths of arbitrary depth, replacing the previous 3-level cap.
  • Optional positional varargs. Framework no longer requires ≥1 value for listable positional parameters; opt into the strict behavior with @Required.
  • Fix NPE in HtmlDocumentParser that crashed help output when javadoc contained HTML tags like <p> or <br>.

0.42

  • More accurate first-sentence extraction for @Command descriptions sourced from javadoc. The first sentence (split on period+space, exclamation, or question) is now extracted via DocumentParser so heading-prefixed and multi-paragraph javadoc resolve correctly.

0.41

  • Multi-level command groups. @Command("quote line-item") on a class creates nested groups to any depth. Class and method paths are concatenated following the JAX-RS @Path model. Intermediate groups are auto-created. Multiple classes can contribute to the same deep group.
  • Constructor validation improvements.

0.40

  • Hugo documentation site.
  • Crest Maven Plugin can now create executable jars.
  • @Editor support in table output.
  • Show negated boolean options in help.
  • Class include/exclude filtering for command loading.

0.39

  • @Command descriptions from Javadoc, extracted at compile time by annotation processor.

0.38

  • Split-class command groups. Multiple classes can contribute sub-commands to the same @Command group.

0.37

  • @GlobalOptions annotation for flags that apply across all commands.
  • Global options support in bash completion.

0.36

  • Pluggable bean provider via TargetProvider SPI for CDI and other DI frameworks.

0.35

  • @Editor support loaded from Loader and used in help output.

0.34

  • Help output matches method signature order.
  • Fix help for overloaded commands.

0.33

  • CSV and TSV table output no longer pads or wraps rows.

0.32

  • Remove deprecated Main.systemDefaults() builder method.

0.31

  • Command name and version in help from Main.builder() or MANIFEST.MF.
  • Convenience --csv and --tsv flags for table output.

0.30

  • Main.builder() API for programmatic CLI construction.

0.29

  • CSV table format via @Table.

0.28

  • TSV table format via @Table.

0.27

  • Fix regression with object-based tables.
  • Map key escaping and field name escaping for tables.

0.26

  • Map support in table formatting.

0.25

  • Programmatic table builder API.

0.24

  • Case-insensitive field/column names in tables.

0.23

  • Print help when @Exit(help=true) is set on exceptions.

0.22

  • Allow commands to set table options.

0.21

  • Allow commands to set table options at runtime.

0.20

  • Prefer @Options constructor with Crest annotations.

0.19

  • Javadoc fallback for help text.
  • Archetype fixes.

0.18

  • @Table annotation for automatic table formatting of return values.
  • Table border styles, headers, field selection, sorting, and word wrapping.
  • Stream return type support.

0.17

  • CDI-style custom interceptor annotations via @CrestInterceptor.
  • GraalVM native image support via Apache Arthur extension.

0.16

  • Windows compatibility fixes.
  • Dependency updates (ASM 9, JUnit 4.13.1).

0.15

  • @Exit exceptions control reporting. Help is only printed when requested.

0.14

  • Table output from String[][] return values with configurable borders.
  • Man page piped to less.
  • Auto-detect terminal width.

0.13

  • Improved exception handling for all return types.

0.12

  • Bash completion script generation.
  • Stream return type support.

0.11

  • @DefaultMapping made repeatable.
  • Upgrade to Java 8 compilation.

0.10

  • System property and environment variable interpolation for defaults.
  • Nullable @Options support.
  • Varargs with @In/@Out streams.

0.9

  • @Option(description) for inline option descriptions.

0.8

  • Bean validation fixes.
  • Ctrl+C handling in CLI.

0.7

  • Bean Validation 1.1 support.
  • Interactive CLI with history, clear, and alias support.

0.6

  • Command interceptors for cross-cutting concerns like security.

0.5

  • Crest Maven Plugin for compile-time command discovery.
  • @Default for prefixed bean parameters.
  • @In/@Out/@Err stream injection.

0.4

  • @Exit annotation for exception exit codes.
  • Iterable return type support.

0.3

  • Maven archetype for quick project setup.