Skip to content

Consider providing API for modifying the model at initialization #1259

@remkop

Description

@remkop

This is a follow-up ticket from discussion on #1256 and #1217.

The use case raised by @MarkoMackic is as follows (Marko, please comment if I missed anything):

  • At model construction time, we want the ability to modify the model, based on some runtime environment information (system properties, environment variables, configuration files, etc.). One example is the ability to include or exclude some subcommand based on a system property.
  • We prefer to use the annotation API because of its ease of use, rather than constructing the model using the programmatic API.
  • We want to do this modification at model construction/initialization time, so that this modified model can be used by other components like generating man pages and generating shell completion scripts.

My initial reaction is that this is already possible with code like this:

static CommandLine createDynamicallyModifiedCommand() {
    CommandLine result = new CommandLine(new MyApp());
    if (someCondition()) { // could be a system property or something else
        result.getCommandSpec().subcommands().get("a")
                 .getCommandSpec().subcommands().get("b")
                 .removeSubcommand("c");
    }
    return result;
}

// runs MyApp
public static void main(String... args) {
    System.exit(createDynamicallyModifiedCommand().execute(args));
}

// generates man pages for MyApp
static class MyManPageGenerator implements Callable<Integer> {
        @Option(names = {"-d", "--outdir"}, defaultValue = ".", paramLabel = "<outdir>",
                description = {"Output directory to write the generated AsciiDoc files to. " +
                        "If not specified, files are written to the current directory."})
        File outdir;

        @Option(names = {"-v", "--verbose"},
                description = {
                        "Specify multiple -v options to increase verbosity.",
                        "For example, `-v -v -v` or `-vvv`"})
        boolean[] verbosity = new boolean[0];

    public Integer call() throws Exception {
        CommandSpec spec = createDynamicallyModifiedCommand().getCommandSpec();
        ManPageGenerator.generateManPage(outdir, null, verbosity, false, spec);
    }

    public static void main(String... args) throws Exception {
        new CommandLine(new MyManPageGenerator()).execute(args);
    }
}

@MarkoMackic can you clarify why the above is unsatisfactory and what you would like to see instead?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions