diff --git a/pip/pip-343.md b/pip/pip-343.md new file mode 100644 index 0000000000000..85fc323cba6c6 --- /dev/null +++ b/pip/pip-343.md @@ -0,0 +1,143 @@ +# PIP-343: Use picocli instead of jcommander + +# Motivation + +We use the [jcommander](https://github.com/cbeust/jcommander) to build the CLI tool, which is a good library, and is +stable, but it misses modern CLI features likes autocompletion, flag/command suggestion, native image, etc. + +These features are very important because there are many commands in the CLI, but the jcommander doesn't give friendly +hints when we use incorrect flags/commands, which makes the user experience not very friendly. + +In modern times, the [picocli](https://github.com/remkop/picocli) supports these features, which is a popular library. + +The following is some comparison between jcommander and picocli: + +- Error prompt: + ``` + bin/pulsar-admin clusters update cluster-a -b + + # jcommander + Need to provide just 1 parameter + + # picocli + Unknown option: '-b' + ``` + +- Command suggestion: + ``` + bin/pulsar-admin cluste + + # jcommander + Expected a command, got cluste + + # picocli + Unmatched argument at index 0: 'cluste' + Did you mean: pulsar-admin clusters? + ``` + +# Goals + +## In Scope + +Use the picocli instead of the jcommander in our CLI tool: + +- bin/pulsar +- bin/pulsar-admin +- bin/pulsar-client +- bin/pulsar-shell +- bin/pulsar-perf + +I'm sure this will greatly improve the user experience, and in the future we can also consider using native images to +reduce runtime, and improve the CLI document based on picocli. + +## Out Scope + +This PR simply replaces jcommander and does not introduce any enhancements. + +In the CLI, [autocomplete](https://picocli.info/autocomplete.html) is an important feature, and after this PIP is +complete I will make a new PIP to support this feature. + +# Detailed Design + +## Design & Implementation Details + +The jcommander and picocli have similar APIs, this will make the migration task very simple. + +This is [utility argument syntax](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html): + +``` +utility_name[-a][-b][-c option_argument] + [-d|-e][-f[option_argument]][operand...] +``` + +1. Use `@Command` instead of `@Parameters` to define the class as a command: + + ```java + @Command(name = "my-command", description = "Operations on persistent topics") + public class MyCommand { + + } + ``` + +2. Use `@Option` instead of `@Parameter` to defined the option of command: + + ```java + @Option(names = {"-r", "--role"}) + private String role; + ``` + +3. Use `@Parameters` to get the operand of command: + + ```java + @Parameters(description = "persistent://tenant/namespace/topic", arity = "1") + private String topicName; + ``` + +4. Migrate jcommander converter to picocli converter: + + ```java + public class TimeUnitToMillisConverter implements ITypeConverter { + @Override + public Long convert(String value) throws Exception { + return TimeUnit.SECONDS.toMillis(RelativeTimeUtil.parseRelativeTimeInSeconds(value)); + } + } + ``` + +5. Add the picocli entrypoint: + + ```java + @Command + public class MyCommand implements Callable { + // Picocli entrypoint. + @Override + public Integer call() throws Exception { + // TODO + // run(); + return 0; + } + } + ``` + +The above is a common migration approach, and then we need to consider pulsar-shell and custom command separately. + +- pulsar-shell + + This is an interactive shell based on jline3 and jcommander, which includes pulsar-admin and pulsar-client commands. + The jcommander does not provide autocompletion because we have implemented it ourselves. In picocli, they + have [picocli-shell-jline3](https://github.com/remkop/picocli/blob/main/picocli-shell-jline3) to help us quickly build + the interactive shell. + +- custom command: + + This is an extension of pulsar-admin, and the plugin's implementation does not depend on jcommander. Since the bridge + is used, we only need to change the generator code based on picocli. + +# Backward & Forward Compatibility + +Fully compatible. + +# Links + +* Mailing List discussion thread: https://lists.apache.org/thread/ydg1q064cd11pxwz693frtk4by74q32f +* Mailing List voting thread: https://lists.apache.org/thread/1bpsr6tkgm00bb66dt2s74r15o4b37s3