44import javax .annotation .Nullable ;
55import java .io .File ;
66import java .io .PrintStream ;
7+ import java .text .DecimalFormat ;
78import java .util .*;
8- import java .util .function .Consumer ;
99
1010/**
1111 * Parses CLI arguments.
1212 */
1313public class CLI {
1414
15+ public static final DecimalFormat MS_DURATION = new DecimalFormat ("#,###" );
16+ public static final int MIN_COMMAND_WIDTH = 24 ;
17+ public static final int MIN_ARGUMENT_WIDTH = 34 ;
18+
1519 private final String [] positionalArgs ;
1620 private int positionalArgsIndex = 0 ;
1721
1822 private final Map <String , String > remainingKeywordArgs ;
19- private @ Nullable Consumer < PrintStream > help ;
23+ private @ Nullable CLICommand currentCommand ;
2024
2125 public CLI (String [] positionalArgs , Map <String , String > keywordArgs ) {
2226 this .positionalArgs = positionalArgs ;
2327 this .remainingKeywordArgs = keywordArgs ;
2428 }
2529
30+ /**
31+ * Used for things like printing help, or for help in error reporting.
32+ */
33+ public void setCurrentCommand (@ Nonnull CLICommand currentCommand ) {
34+ this .currentCommand = currentCommand ;
35+ }
36+
2637 public static CLI parse (String [] args ) {
2738 List <String > positionalArgs = new ArrayList <>();
2839 Map <String , String > keywordArgs = new HashMap <>();
@@ -34,11 +45,11 @@ public static CLI parse(String[] args) {
3445 int eqIndex = arg .indexOf ("=" );
3546 if (eqIndex >= 0 ) {
3647 // Handle --keyword=value.
37- key = arg .substring (2 , eqIndex );
48+ key = arg .substring (0 , eqIndex );
3849 value = arg .substring (eqIndex + 1 );
3950 } else {
4051 // Handle --keyword.
41- key = arg . substring ( 2 ) ;
52+ key = arg ;
4253 value = "" ;
4354 }
4455 keywordArgs .put (key , value );
@@ -49,17 +60,9 @@ public static CLI parse(String[] args) {
4960 return new CLI (positionalArgs .toArray (new String [0 ]), keywordArgs );
5061 }
5162
52- /**
53- * As sub-commands are routed, they can update the help that is displayed
54- * when an error occurs.
55- */
56- public void setHelp (@ Nonnull Consumer <PrintStream > help ) {
57- this .help = help ;
58- }
59-
6063 public void printHelp (PrintStream out ) {
61- if (help != null ) {
62- help . accept (out );
64+ if (currentCommand != null ) {
65+ currentCommand . printHelp (out );
6366 }
6467 }
6568
@@ -89,7 +92,7 @@ public File nextExistingDirectory() {
8992 private void assertNotEmpty (String keyword , String value ) {
9093 if (value .isEmpty ()) {
9194 throw new CLIArgumentException (
92- "Value of -- " + keyword + " is empty, expected -- " + keyword + "=value"
95+ "Value of " + keyword + " is empty, expected " + keyword + "=value"
9396 );
9497 }
9598 }
@@ -190,4 +193,24 @@ private static File parseExistingDirectory(String filename) {
190193
191194 return file ;
192195 }
196+
197+ public static String rightPad (String input , int minLength ) {
198+ if (input .length () >= minLength )
199+ return input ;
200+
201+ StringBuilder builder = new StringBuilder (minLength );
202+ builder .append (input );
203+ while (builder .length () < minLength ) {
204+ builder .append (" " );
205+ }
206+ return builder .toString ();
207+ }
208+
209+ public static String rightPadCommand (String command ) {
210+ return rightPad (command , MIN_COMMAND_WIDTH );
211+ }
212+
213+ public static String rightPadArgument (String argument ) {
214+ return rightPad (argument , MIN_ARGUMENT_WIDTH );
215+ }
193216}
0 commit comments