1 package org
.argeo
.slc
.cli
;
3 import java
.io
.PrintWriter
;
4 import java
.io
.StringWriter
;
6 import java
.util
.function
.Function
;
8 import org
.apache
.commons
.cli
.HelpFormatter
;
9 import org
.apache
.commons
.cli
.Options
;
11 /** A special command that can describe {@link DescribedCommand}. */
12 public class HelpCommand
implements DescribedCommand
<String
> {
13 private CommandsCli commandsCli
;
14 private CommandsCli parentCommandsCli
;
17 private static int helpWidth
= 80;
18 private static int helpLeftPad
= 4;
19 private static int helpDescPad
= 20;
21 public HelpCommand(CommandsCli parentCommandsCli
, CommandsCli commandsCli
) {
23 this.parentCommandsCli
= parentCommandsCli
;
24 this.commandsCli
= commandsCli
;
28 public String
apply(List
<String
> args
) {
29 StringWriter out
= new StringWriter();
31 if (args
.size() == 0) {// overview
32 printHelp(commandsCli
, out
);
34 String cmd
= args
.get(0);
35 Function
<List
<String
>, ?
> function
= commandsCli
.getCommand(cmd
);
37 return "Command " + cmd
+ " not found.";
40 DescribedCommand
<?
> command
= null;
41 if (function
instanceof DescribedCommand
) {
42 command
= (DescribedCommand
<?
>) function
;
43 options
= command
.getOptions();
44 examples
= command
.getExamples();
46 options
= new Options();
49 String description
= getShortDescription(function
);
50 String commandCall
= getCommandUsage(cmd
, command
);
51 HelpFormatter formatter
= new HelpFormatter();
52 formatter
.printHelp(new PrintWriter(out
), helpWidth
, commandCall
, description
, options
, helpLeftPad
,
53 helpDescPad
, examples
, false);
55 return out
.toString();
58 private static String
getShortDescription(Function
<List
<String
>, ?
> function
) {
59 if (function
instanceof DescribedCommand
) {
60 return ((DescribedCommand
<?
>) function
).getDescription();
62 return function
.toString();
66 public String
getCommandUsage(String cmd
, DescribedCommand
<?
> command
) {
67 String commandCall
= getCommandCall(commandsCli
) + " " + cmd
;
68 assert command
!= null;
69 if (command
!= null && command
.getUsage() != null) {
70 commandCall
= commandCall
+ " " + command
.getUsage();
76 public String
getDescription() {
77 return "Shows this help or describes a command";
81 public String
getUsage() {
85 public CommandsCli
getParentCommandsCli() {
86 return parentCommandsCli
;
89 protected String
getCommandCall(CommandsCli commandsCli
) {
90 HelpCommand hc
= commandsCli
.getHelpCommand();
91 if (hc
.getParentCommandsCli() != null) {
92 return getCommandCall(hc
.getParentCommandsCli()) + " " + commandsCli
.getCommandName();
94 return commandsCli
.getCommandName();
98 public static void printHelp(DescribedCommand
<?
> command
, StringWriter out
) {
99 String usage
= "java " + command
.getClass().getName()
100 + (command
.getUsage() != null ?
" " + command
.getUsage() : "");
101 HelpFormatter formatter
= new HelpFormatter();
102 formatter
.printHelp(new PrintWriter(out
), helpWidth
, usage
, command
.getDescription(), command
.getOptions(),
103 helpLeftPad
, helpDescPad
, command
.getExamples(), false);
107 public static void printHelp(CommandsCli commandsCli
, String commandName
, StringWriter out
) {
108 DescribedCommand
<?
> command
= (DescribedCommand
<?
>) commandsCli
.getCommand(commandName
);
109 String usage
= commandsCli
.getHelpCommand().getCommandUsage(commandName
, command
);
110 HelpFormatter formatter
= new HelpFormatter();
111 formatter
.printHelp(new PrintWriter(out
), helpWidth
, usage
, command
.getDescription(), command
.getOptions(),
112 helpLeftPad
, helpDescPad
, command
.getExamples(), false);
116 public static void printHelp(CommandsCli commandsCli
, StringWriter out
) {
117 out
.append(commandsCli
.getDescription()).append('\n');
118 String leftPad
= spaces(helpLeftPad
);
119 for (String cmd
: commandsCli
.getSubCommands()) {
120 Function
<List
<String
>, ?
> function
= commandsCli
.getCommand(cmd
);
121 assert function
!= null;
124 // TODO deal with long commands
125 out
.append(spaces(helpDescPad
- cmd
.length()));
126 out
.append(getShortDescription(function
));
131 private static String
spaces(int count
) {
133 // return " ".repeat(count);
137 StringBuilder sb
= new StringBuilder(count
);
138 for (int i
= 0; i
< count
; i
++)
140 return sb
.toString();