JAL-629 change --renderer to --textrenderer to be more specific
[jalview.git] / src / jalview / bin / argparser / Arg.java
index 65a865b..763a6f2 100644 (file)
@@ -1,5 +1,6 @@
 package jalview.bin.argparser;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.List;
@@ -8,19 +9,58 @@ import java.util.stream.Collectors;
 
 public enum Arg
 {
-  HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS,
-  COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION,
-  ANNOTATION2, DISPLAY, GUI, NEWS, SORTBYTREE, USAGESTATS, OPEN, OPENNEW,
-  PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT, OUTPUTTYPE,
-  SSANNOTATION, NOTEMPFAC, TEMPFAC, TEMPFAC_LABEL, TEMPFAC_DESC,
-  TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, IMAGE,
-  QUIT, CLOSE, DEBUG("d"), QUIET("q"), ARGFILE, INCREMENT, NPP("n++"),
-  SUBSTITUTIONS, INITSUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE;
-
-  protected static enum Opt
+  HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, SHOWANNOTATIONS,
+  COLOUR("color"), FEATURES, ANNOTATIONS, GROOVY, GROUPS, HEADLESS, JABAWS,
+  DISPLAY, NEWS, SORTBYTREE, USAGESTATS, APPEND, OPEN, PROPS, QUESTIONNAIRE,
+  SETPROP, TREE, VDOC, VSESS, OUTPUT, SSANNOTATIONS, NOTEMPFAC, TEMPFAC,
+  TITLE, PAEMATRIX, WRAP, NOSTRUCTURE, STRUCTURE, STRUCTUREVIEWER, IMAGE,
+  TYPE, FORMAT, OVERWRITE, TEXTRENDERER, QUIT, CLOSE, DEBUG("d"), TRACE,
+  QUIET("q"), ARGFILE, NEW, NPP("n++"), SUBSTITUTIONS, INITSUBSTITUTIONS,
+  NIL, SPLASH, SETARGFILE, UNSETARGFILE, WEBSERVICEDISCOVERY, ALL, BACKUPS,
+  TESTOUTPUT;
+
+  public static enum Opt
   {
-    BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
-    GLOB, NOACTION, ALLOWSUBSTITUTIONS, PRIVATE
+    BOOLEAN, // This Arg can be specified as --arg or --noarg to give true or
+             // false. A default can be given with setOptions(bool, Opt....).
+             // Use ArgParser.isSet(Arg) to see if this arg was not specified.
+    STRING, // This Arg can accept a value either through --arg=value or --arg
+            // value.
+    UNARY, // This Arg is a boolean value, true if present, false if not. Like
+           // BOOLEAN but without the --noarg option.
+    MULTI, // This Arg can be specified multiple times. Multiple values are
+           // stored in the ArgValuesMap (along with their positional index) for
+           // each linkedId.
+    LINKED, // This Arg can be linked to others through a --arg[linkedId] or
+            // --arg[linkedId]=value. If no linkedId is specified then the
+            // current default linkedId will be used.
+    NODUPLICATEVALUES, // This Arg can only have one value (per linkedId). The
+                       // first value will be used and subsequent values ignored
+                       // with a warning.
+    BOOTSTRAP, // This Arg value(s) can be determined at an earlier stage than
+               // non-BOOTSTRAP Args. Substitutions do not happen in BOOTSTRAP
+               // Args and they cannot be linked or contain SubVals. See
+               // jalview.bin.argparser.BootstrapArgs.
+    GLOB, // This Arg can expand wildcard filename "globs" (e.g.
+          // path/*/filename*). If the Arg value is given as --arg filename*
+          // then the shell will have expanded the glob already, but if
+          // specified as --arg=filename* then the Java glob expansion method
+          // will be used (see FileUtils.getFilenamesFromGlob()). Note that this
+          // might be different from the shell expansion rules.
+    NOACTION, // This Arg does not perform a data task, usually used to control
+              // flow in ArgParser.parse(args).
+    ALLOWSUBSTITUTIONS, // This Arg allows substitutions in its linkedId,
+                        // SubVals and values.
+    PRIVATE, // This Arg is used internally, and cannot be specified by the
+             // user.
+    ALLOWALL, // This Arg can use the '*' linkedId to apply to all known
+              // linkedIds
+    INCREMENTDEFAULTCOUNTER, // If an Arg has this option and the default
+                             // linkedId is used, the defaultLinkedIdCounter is
+                             // incremented *first*.
+    INPUT, // This Arg counts as an input for REQUIREINPUT
+    REQUIREINPUT, // This Arg can only be applied via --all if there is an
+                  // input (i.e. --open or --append)
   }
 
   static
@@ -31,71 +71,76 @@ public enum Arg
     MENUBAR.setOptions(true, Opt.BOOLEAN);
     STATUS.setOptions(true, Opt.BOOLEAN);
     SHOWOVERVIEW.setOptions(Opt.UNARY, Opt.LINKED);
-    ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED);
+    SHOWANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED);
     COLOUR.setOptions(Opt.STRING, Opt.LINKED);
     FEATURES.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
             Opt.ALLOWSUBSTITUTIONS);
+    ANNOTATIONS.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
+            Opt.ALLOWSUBSTITUTIONS);
+    TREE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
+            Opt.ALLOWSUBSTITUTIONS);
     GROOVY.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
             Opt.ALLOWSUBSTITUTIONS);
     GROUPS.setOptions(Opt.STRING, Opt.LINKED);
     HEADLESS.setOptions(Opt.UNARY, Opt.BOOTSTRAP);
-    JABAWS.setOptions(Opt.STRING);
-    ANNOTATION.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
-    ANNOTATION2.setOptions(true, Opt.BOOLEAN, Opt.LINKED);
+    TESTOUTPUT.setOptions(Opt.UNARY, Opt.BOOTSTRAP);
+    JABAWS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
     DISPLAY.setOptions(true, Opt.BOOLEAN);
-    GUI.setOptions(true, Opt.BOOLEAN);
     NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
     SPLASH.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
-    // expects a string value
-    SORTBYTREE.setOptions(true, Opt.BOOLEAN);
-    USAGESTATS.setOptions(true, Opt.BOOLEAN);
-    OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
-            Opt.ALLOWSUBSTITUTIONS);
-    OPENNEW.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
-            Opt.ALLOWSUBSTITUTIONS);
+    SORTBYTREE.setOptions(true, Opt.LINKED, Opt.BOOLEAN);
+    QUESTIONNAIRE.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
+    USAGESTATS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
+    WEBSERVICEDISCOVERY.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
+    APPEND.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
+            Opt.ALLOWSUBSTITUTIONS, Opt.INPUT);
+    OPEN.setOptions(Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER,
+            Opt.MULTI, Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT);
     PROPS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
-    QUESTIONNAIRE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
     SETPROP.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
-    TREE.setOptions(Opt.STRING);
 
     VDOC.setOptions(Opt.UNARY);
     VSESS.setOptions(Opt.UNARY);
 
-    OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
-    OUTPUTTYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
+    OUTPUT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS,
+            Opt.ALLOWALL, Opt.REQUIREINPUT);
 
-    SSANNOTATION.setOptions(Opt.BOOLEAN, Opt.LINKED);
+    SSANNOTATIONS.setOptions(Opt.BOOLEAN, Opt.LINKED);
     NOTEMPFAC.setOptions(Opt.UNARY, Opt.LINKED);
     TEMPFAC.setOptions(Opt.STRING, Opt.LINKED);
-    TEMPFAC_LABEL.setOptions(Opt.STRING, Opt.LINKED);
-    TEMPFAC_DESC.setOptions(Opt.STRING, Opt.LINKED);
-    TEMPFAC_SHADING.setOptions(Opt.BOOLEAN, Opt.LINKED);
     TITLE.setOptions(Opt.STRING, Opt.LINKED);
     PAEMATRIX.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
             Opt.ALLOWSUBSTITUTIONS);
     NOSTRUCTURE.setOptions(Opt.UNARY, Opt.LINKED);
     STRUCTURE.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI,
             Opt.ALLOWSUBSTITUTIONS);
+    STRUCTUREVIEWER.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI);
     WRAP.setOptions(Opt.BOOLEAN, Opt.LINKED);
-    IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS);
+    IMAGE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWSUBSTITUTIONS,
+            Opt.ALLOWALL, Opt.REQUIREINPUT);
+    TYPE.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWALL);
+    FORMAT.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWALL);
+    TEXTRENDERER.setOptions(Opt.STRING, Opt.LINKED, Opt.ALLOWALL);
     QUIT.setOptions(Opt.UNARY);
-    CLOSE.setOptions(Opt.UNARY, Opt.LINKED);
+    OVERWRITE.setOptions(Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL);
+    BACKUPS.setOptions(true, Opt.BOOLEAN, Opt.LINKED, Opt.ALLOWALL);
+    CLOSE.setOptions(Opt.UNARY, Opt.LINKED, Opt.ALLOWALL);
     DEBUG.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
+    TRACE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
     QUIET.setOptions(Opt.UNARY, Opt.MULTI, Opt.BOOTSTRAP);
     ARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP, Opt.GLOB,
             Opt.ALLOWSUBSTITUTIONS);
-    INCREMENT.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
+    NEW.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION,
+            Opt.INCREMENTDEFAULTCOUNTER);
     NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
     SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
-    INITSUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION);
+    INITSUBSTITUTIONS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP,
+            Opt.NOACTION); // defaulting substitutions to true
     NIL.setOptions(Opt.UNARY, Opt.LINKED, Opt.MULTI, Opt.NOACTION);
     SETARGFILE.setOptions(Opt.STRING, Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
     UNSETARGFILE.setOptions(Opt.MULTI, Opt.PRIVATE, Opt.NOACTION);
-    // Opt.BOOTSTRAP args are parsed (not linked with no SubVals so using a
-    // simplified parser, see jalview.bin.argparser.BootstrapArgs)
-    // before a full parse of arguments and so can be accessible at an earlier
-    // stage to (e.g.) set debug log level, provide a props file (that might set
-    // log level), run headlessly, read an argfile instead of other args.
+    ALL.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
+
   }
 
   private final String[] argNames;
@@ -227,6 +272,17 @@ public enum Arg
     return description;
   }
 
+  public static String booleanArgString(Arg a)
+  {
+    StringBuilder sb = new StringBuilder(a.argString());
+    if (a.hasOption(Opt.BOOLEAN))
+    {
+      sb.append('/');
+      sb.append(a.negateArgString());
+    }
+    return sb.toString();
+  }
+
   public static final String usage()
   {
     StringBuilder sb = new StringBuilder();
@@ -237,6 +293,8 @@ public enum Arg
     int maxArgLength = 0;
     for (Arg a : EnumSet.allOf(Arg.class))
     {
+      if (a.hasOption(Opt.PRIVATE))
+        continue;
       StringBuilder argSb = new StringBuilder();
       argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
               : a.argString());
@@ -246,9 +304,11 @@ public enum Arg
         maxArgLength = argSb.length();
     }
 
-    // might want to order these
+    // might want to sort these
     for (Arg a : EnumSet.allOf(Arg.class))
     {
+      if (a.hasOption(Opt.PRIVATE))
+        continue;
       StringBuilder argSb = new StringBuilder();
       argSb.append(a.hasOption(Opt.BOOLEAN) ? booleanArgString(a)
               : a.argString());
@@ -256,26 +316,43 @@ public enum Arg
         argSb.append("=value");
       sb.append(String.format("%-" + maxArgLength + "s  - %s",
               argSb.toString(), a.getDescription()));
+
+      List<String> options = new ArrayList<>();
+
       if (a.hasOption(Opt.BOOLEAN))
       {
-        sb.append(" (default ");
-        sb.append(a.getDefaultBoolValue() ? a.argString()
-                : a.negateArgString());
+        options.add("default " + (a.getDefaultBoolValue() ? a.argString()
+                : a.negateArgString()));
+      }
+
+      if (a.hasOption(Opt.MULTI))
+      {
+        options.add("multiple");
+      }
+
+      if (a.hasOption(Opt.LINKED))
+      {
+        options.add("can be linked");
+      }
+
+      if (a.hasOption(Opt.GLOB))
+      {
+        options.add("allows file globs");
+      }
+
+      if (a.hasOption(Opt.ALLOWSUBSTITUTIONS))
+      {
+        options.add("allows substitutions");
+      }
+
+      if (options.size() > 0)
+      {
+        sb.append(" (");
+        sb.append(String.join("; ", options));
         sb.append(')');
       }
       sb.append(System.lineSeparator());
     }
     return sb.toString();
   }
-
-  public static String booleanArgString(Arg a)
-  {
-    StringBuilder sb = new StringBuilder(a.argString());
-    if (a.hasOption(Opt.BOOLEAN))
-    {
-      sb.append('/');
-      sb.append(a.negateArgString());
-    }
-    return sb.toString();
-  }
 }
\ No newline at end of file