JAL-629 Fix --headless for new args. Fix progressbar for non-headless commands. Add...
authorBen Soares <b.soares@dundee.ac.uk>
Wed, 8 Mar 2023 13:32:44 +0000 (13:32 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Wed, 8 Mar 2023 13:32:44 +0000 (13:32 +0000)
src/jalview/bin/ArgParser.java
src/jalview/bin/Commands.java
src/jalview/bin/Jalview.java

index cc31f5b..c7527c8 100644 (file)
  */
 package jalview.bin;
 
+import java.io.File;
+import java.io.IOException;
 import java.net.URLDecoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -43,9 +47,16 @@ public class ArgParser
 
   private static enum Opt
   {
-    BOOLEAN, STRING, UNARY, MULTI, LINKED, ORDERED, NODUPLICATEVALUES
+    BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES
   }
 
+  // These bootstrap args are simply parsed before a full parse of arguments and
+  // so are accessible at an earlier stage to (e.g.) set debug log leve, provide
+  // a props file (that might set log level), run headlessly, read an argfile
+  // instead of other args.
+  private static final Collection<Arg> bootstrapArgs = new ArrayList(
+          Arrays.asList(Arg.PROPS, Arg.DEBUG, Arg.HEADLESS, Arg.ARGFILE));
+
   public enum Arg
   {
     /*
@@ -61,7 +72,7 @@ public class ArgParser
     USAGESTATS, OPEN, OPEN2, PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC,
     VSESS, OUTPUT, OUTPUTTYPE, SSANNOTATION, NOTEMPFAC, TEMPFAC,
     TEMPFAC_LABEL, TEMPFAC_DESC, TEMPFAC_SHADING, TITLE, PAEMATRIX, WRAP,
-    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d");
+    NOSTRUCTURE, STRUCTURE, IMAGE, QUIT, DEBUG("d"), ARGFILE;
 
     static
     {
@@ -114,6 +125,7 @@ public class ArgParser
       IMAGE.setOptions(Opt.STRING, Opt.LINKED);
       QUIT.setOptions(Opt.UNARY);
       DEBUG.setOptions(Opt.BOOLEAN);
+      ARGFILE.setOptions(Opt.STRING);
     }
 
     private final String[] argNames;
@@ -783,6 +795,8 @@ public class ArgParser
 
     public void parseVals(String item)
     {
+      if (item == null)
+        return;
       if (item.indexOf('[') == 0 && item.indexOf(']') > 1)
       {
         int openBracket = item.indexOf('[');
@@ -934,7 +948,8 @@ public class ArgParser
     {
       if (m == null || !m.containsKey(a))
         return false;
-      return getArgValue(a) != null;
+      return a.hasOption(Opt.STRING) ? getArgValue(a) != null
+              : this.getBoolean(a);
     }
 
     protected boolean hasValue(Arg a, String val)
@@ -1037,9 +1052,6 @@ public class ArgParser
     }
   }
 
-  private static final Collection<Arg> bootstrapArgs = new ArrayList(
-          Arrays.asList(Arg.PROPS, Arg.DEBUG));
-
   public static Map<Arg, String> bootstrapArgs(String[] args)
   {
     Map<Arg, String> bootstrapArgMap = new HashMap<>();
@@ -1070,4 +1082,26 @@ public class ArgParser
     }
     return bootstrapArgMap;
   }
+
+  public static ArgParser parseArgFile(String argFilename)
+  {
+    List<String> argsList = null;
+    File argFile = new File(argFilename);
+    if (!argFile.exists())
+    {
+      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
+              + "=\"" + argFilename + "\": File does not exist.");
+      System.exit(2);
+    }
+    try
+    {
+      argsList = Files.readAllLines(Paths.get(argFilename));
+    } catch (IOException e)
+    {
+      System.err.println("--" + Arg.ARGFILE.name().toLowerCase(Locale.ROOT)
+              + "=\"" + argFilename + "\": File could not be read.");
+      System.exit(3);
+    }
+    return new ArgParser((String[]) argsList.toArray());
+  }
 }
\ No newline at end of file
index 229df27..b42f08e 100644 (file)
@@ -56,6 +56,13 @@ public class Commands
 
   private Map<String, AlignFrame> afMap;
 
+  private static boolean commandArgsProvided = false;
+
+  public static boolean commandArgsProvided()
+  {
+    return commandArgsProvided;
+  }
+
   public static boolean processArgs(ArgParser ap, boolean h)
   {
     argParser = ap;
@@ -138,9 +145,11 @@ public class Commands
     */
     if (avm.containsArg(Arg.OPEN))
     {
+      commandArgsProvided = true;
       long progress = -1;
 
       boolean first = true;
+      boolean progressBarSet = false;
       AlignFrame af;
       for (ArgValue av : avm.getArgValueList(Arg.OPEN))
       {
@@ -158,6 +167,7 @@ public class Commands
                     MessageManager.getString(
                             "status.processing_commandline_args"),
                     progress = System.currentTimeMillis());
+            progressBarSet = true;
           }
         }
 
@@ -359,10 +369,10 @@ public class Commands
         else
         {
           Console.warn("No more files to open");
-          if (desktop != null)
-            desktop.setProgressBar(null, progress);
         }
       }
+      if (progressBarSet && desktop != null)
+        desktop.setProgressBar(null, progress);
 
     }
 
@@ -372,6 +382,7 @@ public class Commands
       AlignFrame af = afMap.get(id);
       if (avm.containsArg(Arg.STRUCTURE))
       {
+        commandArgsProvided = true;
         for (ArgValue av : avm.getArgValueList(Arg.STRUCTURE))
         {
           String val = av.getValue();
index 04cf2a3..c792a96 100755 (executable)
@@ -379,7 +379,16 @@ public class Jalview
     }
 
     // new ArgParser
-    ArgParser argparser = new ArgParser(args);
+    ArgParser argparser;
+    // --argfile=... -- OVERRIDES ALL NON-BOOTSTRAP ARGS
+    if (bootstrapArgs.containsKey(Arg.ARGFILE))
+    {
+      argparser = ArgParser.parseArgFile(bootstrapArgs.get(Arg.ARGFILE));
+    }
+    else
+    {
+      argparser = new ArgParser(args);
+    }
 
     if (!Platform.isJS())
     /**
@@ -608,7 +617,7 @@ public class Jalview
       }
     }
     // Run Commands from cli
-    boolean commandsSuccess = Commands.processArgs(argparser, headless);
+    boolean commandsSuccess = Commands.processArgs(argparser, headlessArg);
     if (commandsSuccess)
     {
       Console.info("Successfully completed commands");
@@ -937,7 +946,10 @@ public class Jalview
     // ////////////////////
 
     if (!Platform.isJS() && !headless && file == null
-            && Cache.getDefault("SHOW_STARTUP_FILE", true))
+            && Cache.getDefault("SHOW_STARTUP_FILE", true)
+            && !Commands.commandArgsProvided())
+    // don't open the startup file if command line args have been processed
+    // (&& !Commands.commandArgsProvided())
     /**
      * Java only
      *