Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
Add extended help
Browse files Browse the repository at this point in the history
This extends the `help` command with the ability to print extended
help for given commands.

Fix: #1
  • Loading branch information
io7m committed Jun 27, 2020
1 parent 16a4dfd commit 86151d3
Show file tree
Hide file tree
Showing 25 changed files with 627 additions and 72 deletions.
Expand Up @@ -18,7 +18,7 @@

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.io7m.claypot.core.internal.CLPLogLevelConverter;
import org.osgi.annotation.versioning.ProviderType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -30,7 +30,6 @@
*/

@ProviderType
@Parameters(resourceBundle = "com.io7m.claypot.core.Claypot")
public abstract class CLPAbstractCommand implements CLPCommandType
{
private final JCommander commander;
Expand All @@ -39,7 +38,7 @@ public abstract class CLPAbstractCommand implements CLPCommandType
@Parameter(
names = "--verbose",
converter = CLPLogLevelConverter.class,
descriptionKey = "com.io7m.claypot.rootDescription"
description = "Set the minimum logging verbosity level."
)
private CLPLogLevel verbose = CLPLogLevel.LOG_INFO;

Expand Down Expand Up @@ -71,6 +70,11 @@ protected final Logger logger()
return this.configuration().logger();
}

protected final CLPStringsType strings()
{
return this.context.strings();
}

protected final CLPApplicationConfiguration configuration()
{
return this.context().configuration();
Expand Down
Expand Up @@ -16,8 +16,12 @@

package com.io7m.claypot.core;

import com.io7m.claypot.core.internal.CLPXMLResourceBundle;
import org.osgi.annotation.versioning.ProviderType;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.ResourceBundle;
Expand Down Expand Up @@ -52,5 +56,28 @@ public final String format(
Objects.requireNonNull(args, "args");
return MessageFormat.format(this.resources.getString(id), args);
}

protected static ResourceBundle ofXMLResource(
final Class<?> clazz,
final String resource)
{
try (var stream = clazz.getResourceAsStream(resource)) {
return ofXML(stream);
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
}

protected static ResourceBundle ofXML(
final InputStream stream)
{
try {
return new CLPXMLResourceBundle(
Objects.requireNonNull(stream, "stream")
);
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
}
}

Expand Up @@ -24,6 +24,8 @@

public interface CLPCommandContextType
{
CLPStringsType strings();

CLPApplicationConfiguration configuration();

JCommander commander();
Expand Down
Expand Up @@ -25,6 +25,14 @@
@ProviderType
public interface CLPCommandType
{
/**
* @return Extra help text for the command
*/

default String extendedHelp() {
return "";
}

/**
* @return The name of the command
*/
Expand Down
Expand Up @@ -79,7 +79,11 @@ public String getName()
return this.name;
}

Level toLevel()
/**
* @return The level as a Logback level
*/

public Level toLevel()
{
switch (this) {
case LOG_TRACE:
Expand Down
Expand Up @@ -37,7 +37,7 @@ private CLPStrings(
public static CLPStringsType create()
{
return new CLPStrings(
ResourceBundle.getBundle("com.io7m.claypot.core.Claypot")
ofXMLResource(CLPStrings.class, "/com/io7m/claypot/core/Claypot.xml")
);
}
}
Expand Up @@ -18,6 +18,9 @@

import com.beust.jcommander.JCommander;
import com.beust.jcommander.ParameterException;
import com.io7m.claypot.core.internal.CLPBriefUsageFormatter;
import com.io7m.claypot.core.internal.CLPCommandHelp;
import com.io7m.claypot.core.internal.CLPCommandRoot;
import org.slf4j.Logger;

import java.util.HashMap;
Expand Down Expand Up @@ -63,9 +66,8 @@ public static Claypot create(
final CLPApplicationConfiguration configuration)
{
final var strings = CLPStrings.create();

final var commander = new JCommander();
final var context = new Context(commander, configuration);
final var context = new Context(commander, strings, configuration);

commander.setProgramName(configuration.programName());
commander.addObject(new CLPCommandRoot(context));
Expand All @@ -75,7 +77,8 @@ public static Claypot create(
final var commandMap =
new HashMap<String, CLPCommandType>(constructors.size() + 1);

commandMap.put("help", new CLPCommandHelp(context));
final var help = new CLPCommandHelp(context);
commandMap.put(help.name(), help);

for (final var constructor : constructors) {
final var command = constructor.create(context);
Expand Down Expand Up @@ -123,11 +126,7 @@ public void execute(

final String cmd = this.commander.getParsedCommand();
if (cmd == null) {
final var console = new CLPStringBuilderConsole();
this.commander.setUsageFormatter(new CLPBriefUsageFormatter(this.commander));
this.commander.setConsole(console);
this.commander.usage();
logger.info("{}", console.builder().toString());
CLPBriefUsageFormatter.showBriefUsage(logger, this.commander);
this.exitCode = 1;
return;
}
Expand Down Expand Up @@ -215,18 +214,28 @@ public String toString()
private static final class Context implements CLPCommandContextType
{
private final JCommander commander;
private final CLPStringsType strings;
private final CLPApplicationConfiguration configuration;

private Context(
final JCommander inCommander,
final CLPStringsType inStrings,
final CLPApplicationConfiguration inConfiguration)
{
this.commander =
Objects.requireNonNull(inCommander, "commander");
this.strings =
Objects.requireNonNull(inStrings, "inStrings");
this.configuration =
Objects.requireNonNull(inConfiguration, "inConfiguration");
}

@Override
public CLPStringsType strings()
{
return this.strings;
}

@Override
public CLPApplicationConfiguration configuration()
{
Expand Down
Expand Up @@ -14,12 +14,15 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package com.io7m.claypot.core;
package com.io7m.claypot.core.internal;

import com.beust.jcommander.DefaultUsageFormatter;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.JCommander.ProgramName;
import com.beust.jcommander.Parameters;
import com.io7m.claypot.core.CLPStrings;
import com.io7m.claypot.core.CLPStringsType;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Comparator;
Expand All @@ -41,6 +44,40 @@ public CLPBriefUsageFormatter(
CLPStrings.create();
}

public static void showBriefUsage(
final Logger logger,
final JCommander commander)
{
Objects.requireNonNull(logger, "logger");
Objects.requireNonNull(commander, "commander");

final var console = new CLPStringBuilderConsole();
commander.setUsageFormatter(new CLPBriefUsageFormatter(commander));
commander.setConsole(console);
commander.usage();
logger.info("{}", console.builder().toString());
}

@Override
public void appendMainLine(
final StringBuilder out,
final boolean hasOptions,
final boolean hasCommands,
final int indentCount,
final String indent)
{
super.appendMainLine(out, hasOptions, hasCommands, indentCount, indent);

out.append('\n');
out.append(" ");
out.append(this.strings.format(
"com.io7m.claypot.help",
this.commander.getProgramName()
).trim());
out.append('\n');
out.append('\n');
}

@Override
public void appendCommands(
final StringBuilder out,
Expand All @@ -58,15 +95,23 @@ public void appendCommands(
final var commandNames = new ArrayList<>(rawCommands.keySet());
commandNames.sort(Comparator.comparing(ProgramName::getDisplayName));

var longest = 0;
for (final var commandName : commandNames) {
longest = Math.max(commandName.getName().length(), longest);
}
longest += 4;

for (final var commandName : commandNames) {
final var commands = rawCommands.get(commandName);
final Object arg = commands.getObjects().get(0);
final Parameters p = arg.getClass().getAnnotation(Parameters.class);

if (p == null || !p.hidden()) {
final String lineFormat =
String.format(" %%-%ds %%s", Integer.valueOf(longest));
final String description =
String.format(
" %-32s %s",
lineFormat,
commandName.getDisplayName(),
this.getCommandDescription(commandName.getName())
);
Expand Down

0 comments on commit 86151d3

Please sign in to comment.