Skip to content

Commit

Permalink
Add cli-completion mode in --help
Browse files Browse the repository at this point in the history
  • Loading branch information
making committed Jan 28, 2021
1 parent e3ffeb7 commit 93bba03
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 3 deletions.
17 changes: 16 additions & 1 deletion src/main/java/am/ik/rsocket/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.rsocket.metadata.WellKnownMimeType;
import io.rsocket.transport.ClientTransport;
import io.rsocket.util.DefaultPayload;
import joptsimple.HelpFormatter;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
Expand All @@ -66,7 +67,7 @@ public class Args {

private final OptionSpec<Void> version = parser.acceptsAll(Arrays.asList("v", "version"), "Print version");

private final OptionSpec<Void> help = parser.acceptsAll(Arrays.asList("help"), "Print help");
private final OptionSpec<String> help = parser.acceptsAll(Arrays.asList("h", "help"), "Print help").withOptionalArg();

private final OptionSpec<Void> wiretap = parser.acceptsAll(Arrays.asList("w", "wiretap"), "Enable wiretap");

Expand Down Expand Up @@ -606,6 +607,10 @@ public boolean help() {
return this.options.has(this.help);
}

public String helpFormatter() {
return this.options.valueOf(this.help);
}

public boolean version() {
return this.options.has(this.version);
}
Expand All @@ -621,6 +626,16 @@ public void printHelp(PrintStream stream) {
}
}

public void printHelp(PrintStream stream, HelpFormatter helpFormatter) {
try {
this.parser.formatHelpWith(helpFormatter);
this.parser.printHelpOn(stream);
}
catch (IOException e) {
throw new UncheckedIOException(e);
}
}

public boolean showSystemProperties() {
return this.options.has(this.showSystemProperties);
}
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/am/ik/rsocket/CliCompletionHelpFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package am.ik.rsocket;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import io.rsocket.metadata.TracingMetadataCodec;
import joptsimple.HelpFormatter;
import joptsimple.OptionDescriptor;

public class CliCompletionHelpFormatter implements HelpFormatter {
private final Map<String, Object[]> possibleValues = new HashMap<String, Object[]>() {
{
put("am.ik.rsocket.InteractionModel", InteractionModel.values());
put("io.rsocket.metadata.TracingMetadataCodec$Flags", TracingMetadataCodec.Flags.values());
}
};

@Override
public String format(Map<String, ? extends OptionDescriptor> options) {
Comparator<OptionDescriptor> comparator = Comparator.comparing(optionDescriptor -> optionDescriptor.options().iterator().next());
Set<OptionDescriptor> sorted = new TreeSet<>(comparator);
sorted.addAll(options.values());
final StringBuilder sb = new StringBuilder();
sb.append("name: rsc").append(System.lineSeparator());
sb.append("binary_name: rsc").append(System.lineSeparator());
sb.append("before_help: |").append(System.lineSeparator());
sb.append(" usage: rsc Uri [Options]").append(System.lineSeparator());
sb.append(" Non-option arguments: [String: Uri]").append(System.lineSeparator());
sb.append(System.lineSeparator());
sb.append("args:").append(System.lineSeparator());
sorted.forEach(descriptor -> {
final List<String> opts = new ArrayList<>(descriptor.options());
if (opts.contains("[arguments]")) {
return;
}
Collections.sort(opts, Comparator.comparingInt(String::length).reversed());
final String longest = opts.get(0);
final String shortest = opts.get(opts.size() - 1);
sb.append("- ").append(longest).append(":").append(System.lineSeparator());
if (shortest.length() == 1) {
sb.append(" short: ").append(shortest).append(System.lineSeparator());
opts.remove(shortest);
}
sb.append(" long: ").append(longest).append(System.lineSeparator());
if (opts.size() > 1) {
sb.append(" aliases: ").append(opts.subList(1, opts.size())).append(System.lineSeparator());
}
sb.append(" required: ").append(descriptor.isRequired()).append(System.lineSeparator());
sb.append(" about: \"").append(descriptor.description()).append("\"").append(System.lineSeparator());
final String indicator = descriptor.argumentTypeIndicator();
sb.append(" takes_value: ").append(!"".equals(indicator)).append(System.lineSeparator());
if (possibleValues.containsKey(indicator)) {
sb.append(" possible_values: ").append(Arrays.toString(possibleValues.get(indicator))).append(System.lineSeparator());
}
});
return sb.toString();
}
}
7 changes: 6 additions & 1 deletion src/main/java/am/ik/rsocket/RscCommandLineRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ public void run(String... a) throws Exception {
final Args args = new Args(a);
try {
if (args.help()) {
args.printHelp(System.out);
if ("cli-completion".equals(args.helpFormatter())) {
args.printHelp(System.out, new CliCompletionHelpFormatter());
}
else {
args.printHelp(System.out);
}
return;
}
if (args.version()) {
Expand Down
7 changes: 6 additions & 1 deletion src/test/java/am/ik/rsocket/RscApplicationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
class RscApplicationTests {

@Test
void test(CapturedOutput capture) throws Exception {
void help(CapturedOutput capture) throws Exception {
RscApplication.main(new String[] { "-h" });
assertThat(capture.toString()).isNotEmpty();
}

@Test
void helpYamlMode(CapturedOutput capture) throws Exception {
RscApplication.main(new String[] { "-h", "cli-completion" });
assertThat(capture.toString()).isNotEmpty();
}
}

0 comments on commit 93bba03

Please sign in to comment.