package org.argeo.api.cli;
+/** Exception thrown when the provided arguments are not correct. */
public class CommandArgsException extends IllegalArgumentException {
private static final long serialVersionUID = -7271050747105253935L;
private String commandName;
import java.util.List;
/** {@link RuntimeException} referring during a command run. */
-public class CommandRuntimeException extends RuntimeException {
+class CommandRuntimeException extends RuntimeException {
private static final long serialVersionUID = 5595999301269377128L;
private final DescribedCommand<?> command;
/** Base class for a CLI managing sub commands. */
public abstract class CommandsCli implements DescribedCommand<Object> {
- public final static String HELP = "help";
-
private final String commandName;
private Map<String, Function<List<String>, ?>> commands = new TreeMap<>();
public Object apply(List<String> args) {
String cmd = null;
List<String> newArgs = new ArrayList<>();
+ boolean isHelpOption = false;
try {
CommandLineParser clParser = new DefaultParser();
CommandLine commonCl = clParser.parse(getOptions(), args.toArray(new String[args.size()]), true);
List<String> leftOvers = commonCl.getArgList();
for (String arg : leftOvers) {
+ if (arg.equals("--" + HelpCommand.HELP_OPTION.getLongOpt())) {
+ isHelpOption = true;
+ // TODO break?
+ }
+
if (!arg.startsWith("-") && cmd == null) {
cmd = arg;
} else {
}
Function<List<String>, ?> function = cmd != null ? getCommand(cmd) : getDefaultCommand();
+
+ // --help option
+ if (!(function instanceof CommandsCli))
+ if (function instanceof DescribedCommand<?> command)
+ if (isHelpOption) {
+ throw new PrintHelpRequestException(cmd, this);
+// StringWriter out = new StringWriter();
+// HelpCommand.printHelp(command, out);
+// System.out.println(out.toString());
+// return null;
+ }
+
if (function == null)
throw new IllegalArgumentException("Uknown command " + cmd);
try {
protected void addCommandsCli(CommandsCli commandsCli) {
addCommand(commandsCli.getCommandName(), commandsCli);
- commandsCli.addCommand(HELP, new HelpCommand(this, commandsCli));
+ commandsCli.addCommand(HelpCommand.HELP, new HelpCommand(this, commandsCli));
}
public String getCommandName() {
}
public HelpCommand getHelpCommand() {
- return (HelpCommand) getCommand(HELP);
+ return (HelpCommand) getCommand(HelpCommand.HELP);
}
public Function<List<String>, String> getDefaultCommand() {
/** In order to implement quickly a main method. */
public static void mainImpl(CommandsCli cli, String[] args) {
try {
- cli.addCommand(CommandsCli.HELP, new HelpCommand(null, cli));
+ cli.addCommand(HelpCommand.HELP, new HelpCommand(null, cli));
Object output = cli.apply(Arrays.asList(args));
- System.out.println(output);
+ if (output != null)
+ System.out.println(output);
System.exit(0);
+ } catch (PrintHelpRequestException e) {
+ StringWriter out = new StringWriter();
+ HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out);
+ System.out.println(out.toString());
} catch (CommandArgsException e) {
System.err.println("Wrong arguments " + Arrays.toString(args) + ": " + e.getMessage());
Throwable cause = e.getCause();
Object output = command.apply(Arrays.asList(args));
System.out.println(output);
System.exit(0);
+ } catch (PrintHelpRequestException e) {
+ StringWriter out = new StringWriter();
+ HelpCommand.printHelp(command, out);
+ System.out.println(out.toString());
+ System.exit(1);
} catch (IllegalArgumentException e) {
StringWriter out = new StringWriter();
HelpCommand.printHelp(command, out);
import java.util.function.Function;
import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
/** A special command that can describe {@link DescribedCommand}. */
public class HelpCommand implements DescribedCommand<String> {
+ /**
+ * System property forcing the root command to this value (typically the name of
+ * a script).
+ */
+ public final static String ROOT_COMMAND_PROPERTY = "org.argeo.api.cli.rootCommand";
+
+ final static String HELP = "help";
+ final static Option HELP_OPTION = Option.builder().longOpt(HELP).desc("print this help").build();
+
private CommandsCli commandsCli;
private CommandsCli parentCommandsCli;
if (hc.getParentCommandsCli() != null) {
return getCommandCall(hc.getParentCommandsCli()) + " " + commandsCli.getCommandName();
} else {
+ String rootCommand = System.getProperty(ROOT_COMMAND_PROPERTY);
+ if (rootCommand != null)
+ return rootCommand;
return commandsCli.getCommandName();
}
}
String usage = "java " + command.getClass().getName()
+ (command.getUsage() != null ? " " + command.getUsage() : "");
HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
+ Options options = command.getOptions();
+ options.addOption(HelpCommand.HELP_OPTION);
+ formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), options, helpLeftPad,
+ helpDescPad, command.getExamples(), false);
}
DescribedCommand<?> command = (DescribedCommand<?>) commandsCli.getCommand(commandName);
String usage = commandsCli.getHelpCommand().getCommandUsage(commandName, command);
HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
+ Options options = command.getOptions();
+ options.addOption(HelpCommand.HELP_OPTION);
+ formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), options, helpLeftPad,
+ helpDescPad, command.getExamples(), false);
}
--- /dev/null
+package org.argeo.api.cli;
+
+/** An exception indicating that help should be printed. */
+class PrintHelpRequestException extends RuntimeException {
+
+ private static final long serialVersionUID = -9029122270660656639L;
+
+ private String commandName;
+ private volatile CommandsCli commandsCli;
+
+ public PrintHelpRequestException(String commandName, CommandsCli commandsCli) {
+ super();
+ this.commandName = commandName;
+ this.commandsCli = commandsCli;
+ }
+
+ public static long getSerialversionuid() {
+ return serialVersionUID;
+ }
+
+ public String getCommandName() {
+ return commandName;
+ }
+
+ public CommandsCli getCommandsCli() {
+ return commandsCli;
+ }
+
+}
+Main-Class: org.argeo.cms.cli.ArgeoCli
+
+Class-Path: \
+org.argeo.api.acr.2.3.jar \
+org.argeo.api.cli.2.3.jar \
+org.argeo.api.cms.2.3.jar \
+org.argeo.api.uuid.2.3.jar \
+org.argeo.cms.2.3.jar \
+org.argeo.cms.ee.2.3.jar \
+org.argeo.cms.lib.equinox.2.3.jar \
+org.argeo.cms.lib.jetty.2.3.jar \
+org.argeo.cms.lib.pgsql.2.3.jar \
+org.argeo.cms.lib.sshd.2.3.jar \
+org.argeo.cms.ux.2.3.jar \
+org.argeo.init.2.3.jar \
+org.argeo.util.2.3.jar \
+../org.argeo.tp/bcmail.1.71.jar \
+../org.argeo.tp/bcpg.1.71.jar \
+../org.argeo.tp/bcpkix.1.71.jar \
+../org.argeo.tp/bcprov.1.71.jar \
+../org.argeo.tp/bcutil.1.71.jar \
+../org.argeo.tp/com.fasterxml.jackson.core.jackson-annotations.2.13.jar \
+../org.argeo.tp/com.fasterxml.jackson.core.jackson-core.2.13.jar \
+../org.argeo.tp/com.fasterxml.jackson.core.jackson-databind.2.13.jar \
+../org.argeo.tp/com.googlecode.javaewah.JavaEWAH.1.1.jar \
+../org.argeo.tp/com.sun.mail.mbox.1.6.jar \
+../org.argeo.tp/com.zaxxer.sparsebits.1.2.jar \
+../org.argeo.tp/jakarta.mail.1.6.jar \
+../org.argeo.tp/jakarta.servlet.api.4.0.jar \
+../org.argeo.tp/javax.activation.1.2.jar \
+../org.argeo.tp/javax.websocket.1.1.jar \
+../org.argeo.tp/net.i2p.crypto.eddsa.0.3.jar \
+../org.argeo.tp/org.argeo.ext.slf4j.2.3.jar \
+../org.argeo.tp/org.h2.1.4.jar \
+../org.argeo.tp/org.postgresql.jdbc42.42.3.jar \
+../org.argeo.tp/org.slf4j.api.1.7.jar \
+../org.argeo.tp/org.slf4j.commons.logging.1.7.jar \
+../org.argeo.tp/org.tukaani.xz.1.9.jar \
+../org.argeo.tp/org.w3c.css.sac.1.3.jar \
+../org.argeo.tp/org.w3c.dom.smil.1.0.jar \
+../org.argeo.tp/org.w3c.dom.svg.1.1.jar \
+../org.argeo.tp.apache/org.apache.batik.1.14.jar \
+../org.argeo.tp.apache/org.apache.batik.constants.1.14.jar \
+../org.argeo.tp.apache/org.apache.batik.css.1.14.jar \
+../org.argeo.tp.apache/org.apache.batik.i18n.1.14.jar \
+../org.argeo.tp.apache/org.apache.batik.util.1.14.jar \
+../org.argeo.tp.apache/org.apache.commons.cli.1.5.jar \
+../org.argeo.tp.apache/org.apache.commons.codec.1.15.jar \
+../org.argeo.tp.apache/org.apache.commons.compress.1.21.jar \
+../org.argeo.tp.apache/org.apache.commons.exec.1.3.jar \
+../org.argeo.tp.apache/org.apache.commons.fileupload.1.4.jar \
+../org.argeo.tp.apache/org.apache.commons.httpclient.3.1.jar \
+../org.argeo.tp.apache/org.apache.commons.io.2.11.jar \
+../org.argeo.tp.apache/org.apache.commons.vfs.2.9.jar \
+../org.argeo.tp.apache/org.apache.httpcomponents.httpclient.4.5.jar \
+../org.argeo.tp.apache/org.apache.httpcomponents.httpcore.4.4.jar \
+../org.argeo.tp.apache/org.apache.httpcomponents.httpmime.4.5.jar \
+../org.argeo.tp.apache/org.apache.sshd.2.8.jar \
+../org.argeo.tp.apache/org.apache.sshd.cli.2.8.jar \
+../org.argeo.tp.apache/org.apache.sshd.git.2.8.jar \
+../org.argeo.tp.apache/org.apache.sshd.putty.2.8.jar \
+../org.argeo.tp.apache/org.apache.sshd.scp.2.8.jar \
+../org.argeo.tp.apache/org.apache.sshd.sftp.2.8.jar \
+../org.argeo.tp.apache/org.apache.tika.core.1.28.jar \
+../org.argeo.tp.apache/org.apache.tika.parsers.1.28.jar \
+../org.argeo.tp.apache/org.apache.tomcat.jni.9.0.jar \
+../org.argeo.tp.apache/org.apache.xalan.2.7.jar \
+../org.argeo.tp.apache/org.apache.xerces.2.12.jar \
+../org.argeo.tp.apache/org.apache.xmlgraphics.2.7.jar \
+../org.argeo.tp.apache/org.apache.xml.resolver.1.2.jar \
+
@Override
public String getDescription() {
- return "Argeo utilities";
+ return "Argeo CMS utilities";
+ }
+
+ public static void main(String[] args) {
+ mainImpl(new ArgeoCli("argeo"), args);
}
}
import org.argeo.api.cli.CommandsCli;
+/** SSH command line interface. */
public class SshCli extends CommandsCli {
public SshCli(String commandName) {
super(commandName);
--- /dev/null
+!bin/
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+java -Dorg.argeo.api.cli.rootCommand=$0 -jar /usr/share/a2/org.argeo.cms/org.argeo.cms.cli.2.3.jar "$@"
\ No newline at end of file