JAL-629 added setprop. More filename based substitutions enabled. Test for these.
authorBen Soares <b.soares@dundee.ac.uk>
Mon, 3 Apr 2023 17:04:37 +0000 (18:04 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Mon, 3 Apr 2023 17:04:37 +0000 (18:04 +0100)
14 files changed:
src/jalview/bin/Jalview.java
src/jalview/bin/argparser/Arg.java
src/jalview/bin/argparser/ArgParser.java
src/jalview/bin/argparser/ArgValuesMap.java
src/jalview/bin/argparser/BootstrapArgs.java
src/jalview/util/FileUtils.java
test/jalview/bin/CommandsTest.java
test/jalview/bin/argparser/testfiles/dir1/argfile.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir1/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir1/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/argfile.txt [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test1.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test2.fa [new file with mode: 0644]
test/jalview/bin/argparser/testfiles/dir2/test3.fa [new file with mode: 0644]

index 689080e..0870ecb 100755 (executable)
@@ -39,7 +39,9 @@ import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.Policy;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
@@ -486,26 +488,40 @@ public class Jalview
       }
     }
 
-    String defs = aparser.getValue("setprop");
-    while (defs != null)
+    List<String> setprops = new ArrayList<>();
+    if (bootstrapArgs.contains(Arg.SETPROP))
     {
-      int p = defs.indexOf('=');
+      setprops = bootstrapArgs.getList(Arg.SETPROP);
+    }
+    else
+    {
+      String sp = aparser.getValue("setprop");
+      while (sp != null)
+      {
+        setprops.add(sp);
+        sp = aparser.getValue("setprop");
+      }
+    }
+    for (String setprop : setprops)
+    {
+      int p = setprop.indexOf('=');
       if (p == -1)
       {
-        System.err.println("Ignoring invalid setprop argument : " + defs);
+        System.err
+                .println("Ignoring invalid setprop argument : " + setprop);
       }
       else
       {
-        System.out.println("Executing setprop argument: " + defs);
+        System.out.println("Executing setprop argument: " + setprop);
         if (Platform.isJS())
         {
-          Cache.setProperty(defs.substring(0, p), defs.substring(p + 1));
+          Cache.setProperty(setprop.substring(0, p),
+                  setprop.substring(p + 1));
         }
         // DISABLED FOR SECURITY REASONS
         // TODO: add a property to allow properties to be overriden by cli args
         // Cache.setProperty(defs.substring(0,p), defs.substring(p+1));
       }
-      defs = aparser.getValue("setprop");
     }
     if (System.getProperty("java.awt.headless") != null
             && System.getProperty("java.awt.headless").equals("true"))
index c19012b..e658434 100644 (file)
@@ -9,17 +9,17 @@ public enum Arg
 {
   HELP("h"), CALCULATION, MENUBAR, STATUS, SHOWOVERVIEW, ANNOTATIONS,
   COLOUR, FEATURES, GROOVY, GROUPS, HEADLESS, JABAWS, ANNOTATION,
-  ANNOTATION2, DISPLAY, GUI, NEWS, NOQUESTIONNAIRE, SORTBYTREE, USAGESTATS,
-  OPEN, OPENNEW, PROPS, QUESTIONNAIRE, SETPROP, TREE, VDOC, VSESS, OUTPUT,
-  OUTPUTTYPE, SSANNOTATION, NOTEMPFAC, TEMPFAC, TEMPFAC_LABEL, TEMPFAC_DESC,
+  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, NIL, SPLASH;
+  SUBSTITUTIONS, NIL, SPLASH, SETARGFILE, UNSETARGFILE;
 
   protected static enum Opt
   {
     BOOLEAN, STRING, UNARY, MULTI, LINKED, NODUPLICATEVALUES, BOOTSTRAP,
-    GLOB, NOACTION, ALLOWSUBSTITUTIONS
+    GLOB, NOACTION, ALLOWSUBSTITUTIONS, PRIVATE
   }
 
   static
@@ -45,8 +45,6 @@ public enum Arg
     GUI.setOptions(true, Opt.BOOLEAN);
     NEWS.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
     SPLASH.setOptions(true, Opt.BOOLEAN, Opt.BOOTSTRAP);
-    NOQUESTIONNAIRE.setOptions(Opt.UNARY, Opt.BOOTSTRAP); // unary as
-                                                          // --questionnaire=val
     // expects a string value
     SORTBYTREE.setOptions(true, Opt.BOOLEAN);
     USAGESTATS.setOptions(true, Opt.BOOLEAN);
@@ -55,8 +53,8 @@ public enum Arg
     OPENNEW.setOptions(Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
             Opt.ALLOWSUBSTITUTIONS);
     PROPS.setOptions(Opt.STRING, Opt.BOOTSTRAP);
-    QUESTIONNAIRE.setOptions(Opt.STRING);
-    SETPROP.setOptions(Opt.STRING);
+    QUESTIONNAIRE.setOptions(Opt.BOOLEAN, Opt.BOOTSTRAP);
+    SETPROP.setOptions(Opt.STRING, Opt.MULTI, Opt.BOOTSTRAP);
     TREE.setOptions(Opt.STRING);
 
     VDOC.setOptions(Opt.UNARY);
@@ -89,6 +87,8 @@ public enum Arg
     NPP.setOptions(Opt.UNARY, Opt.MULTI, Opt.NOACTION);
     SUBSTITUTIONS.setOptions(Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION);
     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
index 81ba0cc..c2568bb 100644 (file)
@@ -41,6 +41,8 @@ public class ArgParser
 {
   protected static final String DOUBLEDASH = "--";
 
+  protected static final char EQUALS = '=';
+
   protected static final String NEGATESTRING = "no";
 
   // the default linked id prefix used for no id (not even square braces)
@@ -55,13 +57,32 @@ public class ArgParser
   // the counter added to the default linked id prefix
   private int opennewLinkedIdCounter = 0;
 
-  // the linked id used to increment the idCounter (and use the incremented
-  // value)
+  // the linked id substitution string used to increment the idCounter (and use
+  // the incremented value)
   private static final String INCREMENTAUTOCOUNTERLINKEDID = "{++n}";
 
-  // the linked id used to use the idCounter
+  // the linked id substitution string used to use the idCounter
   private static final String AUTOCOUNTERLINKEDID = "{n}";
 
+  // the linked id substitution string used to use the base filename of --open
+  // or --opennew
+  private static final String LINKEDIDBASENAME = "{basename}";
+
+  // the linked id substitution string used to use the dir path of --open
+  // or --opennew
+  private static final String LINKEDIDDIRNAME = "{dirname}";
+
+  // the current argfile
+  private String argFile = null;
+
+  // the linked id substitution string used to use the dir path of the latest
+  // --argfile name
+  private static final String ARGFILEBASENAME = "{argfilebasename}";
+
+  // the linked id substitution string used to use the dir path of the latest
+  // --argfile name
+  private static final String ARGFILEDIRNAME = "{argfiledirname}";
+
   private int linkedIdAutoCounter = 0;
 
   // flag to say whether {n} subtitutions in output filenames should be made.
@@ -115,6 +136,11 @@ public class ArgParser
 
   public ArgParser(List<String> args)
   {
+    this(args, false);
+  }
+
+  public ArgParser(List<String> args, boolean allowPrivate)
+  {
     // do nothing if there are no "--" args and some "-" args
     boolean d = false;
     boolean dd = false;
@@ -133,13 +159,13 @@ public class ArgParser
     if (d && !dd)
     {
       // leave it to the old style -- parse an empty list
-      parse(new ArrayList<String>());
+      parse(new ArrayList<String>(), allowPrivate);
       return;
     }
-    parse(args);
+    parse(args, allowPrivate);
   }
 
-  private void parse(List<String> args)
+  private void parse(List<String> args, boolean allowPrivate)
   {
     int argIndex = 0;
     boolean openEachInitialFilenames = true;
@@ -169,7 +195,7 @@ public class ArgParser
       String linkedId = null;
       if (arg.startsWith(DOUBLEDASH))
       {
-        int equalPos = arg.indexOf('=');
+        int equalPos = arg.indexOf(EQUALS);
         if (equalPos > -1)
         {
           argName = arg.substring(DOUBLEDASH.length(), equalPos);
@@ -206,17 +232,23 @@ public class ArgParser
           Console.error("Argument '" + arg + "' not recognised. Ignoring.");
           continue;
         }
+        if (a.hasOption(Opt.PRIVATE) && !allowPrivate)
+        {
+          Console.error("Argument '" + DOUBLEDASH + argName
+                  + "' is private. Ignoring.");
+          continue;
+        }
         if (!a.hasOption(Opt.BOOLEAN) && negated)
         {
           // used "no" with a non-boolean option
-          Console.error("Argument '--" + NEGATESTRING + argName
+          Console.error("Argument '" + DOUBLEDASH + NEGATESTRING + argName
                   + "' not a boolean option. Ignoring.");
           continue;
         }
         if (!a.hasOption(Opt.STRING) && equalPos > -1)
         {
           // set --argname=value when arg does not accept values
-          Console.error("Argument '--" + argName
+          Console.error("Argument '" + DOUBLEDASH + argName
                   + "' does not expect a value (given as '" + arg
                   + "').  Ignoring.");
           continue;
@@ -224,7 +256,7 @@ public class ArgParser
         if (!a.hasOption(Opt.LINKED) && linkedId != null)
         {
           // set --argname[linkedId] when arg does not use linkedIds
-          Console.error("Argument '--" + argName
+          Console.error("Argument '" + DOUBLEDASH + argName
                   + "' does not expect a linked id (given as '" + arg
                   + "'). Ignoring.");
           continue;
@@ -239,8 +271,10 @@ public class ArgParser
             {
               // strip off and save the SubVals to be added individually later
               globSubVals = ArgParser.getSubVals(val);
-              globVals = FileUtils
-                      .getFilenamesFromGlob(globSubVals.getContent());
+              // make substitutions before looking for files
+              String fileGlob = makeSubstitutions(globSubVals.getContent(),
+                      linkedId);
+              globVals = FileUtils.getFilenamesFromGlob(fileGlob);
             }
             else
             {
@@ -291,6 +325,14 @@ public class ArgParser
         {
           substitutions = !negated;
         }
+        else if (a == Arg.SETARGFILE)
+        {
+          argFile = val;
+        }
+        else if (a == Arg.UNSETARGFILE)
+        {
+          argFile = null;
+        }
 
         String autoCounterString = null;
         boolean usingAutoCounterLinkedId = false;
@@ -353,7 +395,7 @@ public class ArgParser
         // not dealing with both NODUPLICATEVALUES and GLOB
         if (a.hasOption(Opt.NODUPLICATEVALUES) && avm.hasValue(a, val))
         {
-          Console.error("Argument '--" + argName
+          Console.error("Argument '" + DOUBLEDASH + argName
                   + "' cannot contain a duplicate value ('" + val
                   + "'). Ignoring this and subsequent occurrences.");
           continue;
@@ -364,8 +406,8 @@ public class ArgParser
         String id = idsv.get(ArgValues.ID);
         if (id != null && avm.hasId(a, id))
         {
-          Console.error("Argument '--" + argName + "' has a duplicate id ('"
-                  + id + "'). Ignoring.");
+          Console.error("Argument '" + DOUBLEDASH + argName
+                  + "' has a duplicate id ('" + id + "'). Ignoring.");
           continue;
         }
 
@@ -380,7 +422,7 @@ public class ArgParser
           {
             for (String v : globVals)
             {
-              v = makeSubstitutions(v);
+              v = makeSubstitutions(v, linkedId);
               SubVals vsv = new SubVals(globSubVals, v);
               avs.addValue(vsv, v, argIndex++);
               argIndexIncremented = true;
@@ -388,7 +430,7 @@ public class ArgParser
           }
           else
           {
-            avs.addValue(makeSubstitutions(val), argIndex);
+            avs.addValue(makeSubstitutions(val, linkedId), argIndex);
           }
         }
         else if (a.hasOption(Opt.BOOLEAN))
@@ -424,7 +466,7 @@ public class ArgParser
     }
   }
 
-  private String makeSubstitutions(String val)
+  private String makeSubstitutions(String val, String linkedId)
   {
     if (!this.substitutions)
       return val;
@@ -444,14 +486,39 @@ public class ArgParser
       subvals = "";
       rest = val;
     }
-    if ((rest.contains(AUTOCOUNTERLINKEDID)))
+    if (rest.contains(AUTOCOUNTERLINKEDID))
       rest = rest.replace(AUTOCOUNTERLINKEDID,
               String.valueOf(linkedIdAutoCounter));
-    if ((rest.contains(INCREMENTAUTOCOUNTERLINKEDID)))
+    if (rest.contains(INCREMENTAUTOCOUNTERLINKEDID))
       rest = rest.replace(INCREMENTAUTOCOUNTERLINKEDID,
               String.valueOf(++linkedIdAutoCounter));
-    if ((rest.contains("{}")))
+    if (rest.contains("{}"))
       rest = rest.replace("{}", String.valueOf(defaultLinkedIdCounter));
+    ArgValuesMap avm = linkedArgs.get(linkedId);
+    if (avm != null)
+    {
+      if (rest.contains(LINKEDIDBASENAME))
+      {
+        rest = rest.replace(LINKEDIDBASENAME, avm.getBasename());
+      }
+      if (rest.contains(LINKEDIDDIRNAME))
+      {
+        rest = rest.replace(LINKEDIDDIRNAME, avm.getDirname());
+      }
+    }
+    if (argFile != null)
+    {
+      if (rest.contains(ARGFILEBASENAME))
+      {
+        rest = rest.replace(ARGFILEBASENAME,
+                FileUtils.getBasename(new File(argFile)));
+      }
+      if (rest.contains(ARGFILEDIRNAME))
+      {
+        rest = rest.replace(ARGFILEDIRNAME,
+                FileUtils.getDirname(new File(argFile)));
+      }
+    }
 
     return new StringBuilder(subvals).append(rest).toString();
   }
@@ -582,13 +649,19 @@ public class ArgParser
       if (!argFile.exists())
       {
         String message = DOUBLEDASH
-                + Arg.ARGFILE.name().toLowerCase(Locale.ROOT) + "=\""
-                + argFile.getPath() + "\": File does not exist.";
+                + Arg.ARGFILE.name().toLowerCase(Locale.ROOT) + EQUALS
+                + "\"" + argFile.getPath() + "\": File does not exist.";
         Jalview.exit(message, 2);
       }
       try
       {
+        String setargfile = new StringBuilder(ArgParser.DOUBLEDASH)
+                .append(Arg.SETARGFILE.getName()).append(EQUALS)
+                .append(argFile.getCanonicalPath()).toString();
+        argsList.add(setargfile);
         argsList.addAll(Files.readAllLines(Paths.get(argFile.getPath())));
+        argsList.add(new StringBuilder(ArgParser.DOUBLEDASH)
+                .append(Arg.UNSETARGFILE.getName()).toString());
       } catch (IOException e)
       {
         String message = DOUBLEDASH
@@ -597,7 +670,9 @@ public class ArgParser
         Jalview.exit(message, 3);
       }
     }
-    return new ArgParser(argsList);
+    // Second param "true" uses Opt.PRIVATE args --setargile=argfile and
+    // --unsetargfile
+    return new ArgParser(argsList, true);
   }
 
 }
\ No newline at end of file
index 22d85a8..2117ee9 100644 (file)
@@ -1,5 +1,6 @@
 package jalview.bin.argparser;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -7,6 +8,7 @@ import java.util.Map;
 import java.util.Set;
 
 import jalview.bin.argparser.Arg.Opt;
+import jalview.util.FileUtils;
 
 /**
  * Helper class to allow easy extraction of information about specific argument
@@ -190,4 +192,39 @@ public class ArgValuesMap
     ArgValues avs = this.getArgValues(a);
     return avs == null ? null : avs.getId(id);
   }
+
+  /*
+   * This method returns the basename of the first --open or --opennew value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public String getBasename()
+  {
+    return getDirOrBasename(false);
+  }
+
+  /*
+   * This method returns the dirname of the first --open or --opennew value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public String getDirname()
+  {
+    return getDirOrBasename(true);
+  }
+
+  public String getDirOrBasename(boolean dirname)
+  {
+    String filename = null;
+    String openVal = getValue(Arg.OPEN);
+    String opennewVal = getValue(Arg.OPENNEW);
+    if (openVal != null)
+      filename = openVal;
+    if (filename == null && opennewVal != null)
+      filename = opennewVal;
+    if (filename == null)
+      return null;
+
+    File file = new File(filename);
+    return dirname ? FileUtils.getDirname(file)
+            : FileUtils.getBasename(file);
+  }
 }
index f6b592b..0d648a4 100644 (file)
@@ -38,7 +38,7 @@ public class BootstrapArgs
       {
         // remove "--"
         arg = arg.substring(ArgParser.DOUBLEDASH.length());
-        int equalPos = arg.indexOf('=');
+        int equalPos = arg.indexOf(ArgParser.EQUALS);
         if (equalPos > -1
                 && ArgParser.argMap.containsKey(arg.substring(0, equalPos)))
         {
@@ -152,11 +152,22 @@ public class BootstrapArgs
     return (aL == null || aL.size() == 0) ? null : aL.get(0);
   }
 
+  public boolean getBoolean(Arg a, boolean d)
+  {
+    if (!bootstrapArgMap.containsKey(a))
+      return d;
+    return Boolean.parseBoolean(get(a));
+  }
+
   public boolean getBoolean(Arg a)
   {
-    if (!bootstrapArgMap.containsKey(a)
-            || !(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
+    if (!(a.hasOption(Opt.BOOLEAN) || a.hasOption(Opt.UNARY)))
+    {
       return false;
-    return Boolean.parseBoolean(get(a));
+    }
+    if (bootstrapArgMap.containsKey(a))
+      return Boolean.parseBoolean(get(a));
+    else
+      return a.getDefaultBoolValue();
   }
 }
index 63af0bc..b6f4e90 100644 (file)
@@ -16,6 +16,8 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import jalview.bin.Console;
+
 public class FileUtils
 {
   /*
@@ -123,4 +125,50 @@ public class FileUtils
             ? System.getProperty("user.home") + path.substring(1)
             : path;
   }
+
+  /*
+   * This method returns the basename of the first --open or --opennew value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public static String getBasename(File file)
+  {
+    if (file == null)
+      return null;
+
+    String basename = null;
+    String filename = file.getName();
+    int lastDot = filename.lastIndexOf('.');
+    if (lastDot > 0) // don't truncate if starts with '.'
+    {
+      basename = filename.substring(0, lastDot);
+    }
+    else
+    {
+      basename = filename;
+    }
+    return basename;
+  }
+
+  /*
+   * This method returns the dirname of the first --open or --opennew value. 
+   * Used primarily for substitutions in output filenames.
+   */
+  public static String getDirname(File file)
+  {
+    if (file == null)
+      return null;
+
+    String dirname = null;
+    try
+    {
+      dirname = file.getParentFile().getCanonicalPath();
+    } catch (IOException e)
+    {
+      Console.debug(
+              "Exception when getting dirname of '" + file.getPath() + "'",
+              e);
+      dirname = "";
+    }
+    return dirname;
+  }
 }
index b37c6e3..91e3205 100644 (file)
@@ -1,5 +1,8 @@
 package jalview.bin;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
@@ -19,6 +22,12 @@ import jalview.util.ArrayUtils;
 @Test(singleThreaded = true)
 public class CommandsTest
 {
+  private static final String testfiles = "test/jalview/bin/argparser/testfiles";
+
+  private static final String png1 = testfiles + "/dir1/test2.png";
+
+  private static final String png2 = testfiles + "/dir2/test2.png";
+
   @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
@@ -48,6 +57,19 @@ public class CommandsTest
       Desktop.instance.closeAll_actionPerformed(null);
   }
 
+  /* --setprop currently disabled
+  @Test(groups = "Functional")
+  public void setpropsTest()
+  {
+    String MOSTLY_HARMLESS = "MOSTLY_HARMLESS";
+    String cmdLine = "--setprop=" + MOSTLY_HARMLESS + "=Earth";
+    String[] args = cmdLine.split("\\s+");
+    Jalview.main(args);
+    Assert.assertEquals(Cache.getDefault(MOSTLY_HARMLESS, "Magrathea"),
+            "Earth");
+  }
+  */
+
   @Test(groups = "Functional", dataProvider = "cmdLines")
   public void commandsOpenTest(String cmdLine, boolean cmdArgs,
           int numFrames, String[] sequences)
@@ -86,6 +108,29 @@ public class CommandsTest
             lookForSequenceName("THIS_SEQUENCE_ID_DOESN'T_EXIST"));
   }
 
+  @Test(groups = "Functional")
+  public void argFilesGlobAndSubstitutionsTest() throws IOException
+  {
+    cleanupArgfilesImages();
+    String cmdLine = "--headless --argfile=" + testfiles
+            + "/dir*/argfile.txt";
+    String[] args = cmdLine.split("\\s+");
+    Jalview.main(args);
+    Commands cmds = Jalview.getInstance().getCommands();
+    File file1 = new File(png1);
+    File file2 = new File(png2);
+    Assert.assertTrue(file1.exists(),
+            "Did not make file " + png1 + " from argfile");
+    Assert.assertTrue(file2.exists(),
+            "Did not make file " + png2 + " from argfile");
+    long size1 = Files.size(file1.toPath());
+    long size2 = Files.size(file2.toPath());
+    Assert.assertTrue(file1.isFile() && size1 > 0);
+    Assert.assertTrue(file2.isFile() && size2 > 0);
+    Assert.assertTrue(size2 > size1); // png2 has three sequences, png1 has 2
+    cleanupArgfilesImages();
+  }
+
   @DataProvider(name = "cmdLines")
   public Object[][] cmdLines()
   {
@@ -104,16 +149,15 @@ public class CommandsTest
         { "--open=[new]examples/uniref50*.fa", true, 2, someUniref50Seqs },
         { "--opennew=examples/uniref50*.fa", true, 2, someUniref50Seqs },
         { "examples/uniref50.fa", true, 1, someUniref50Seqs },
-        { "examples/uniref50.fa test/jalview/bin/argparser/testfiles/test1.fa",
-            true, 2, ArrayUtils.concatArrays(someUniref50Seqs, t1) },
-        { "examples/uniref50.fa test/jalview/bin/argparser/testfiles/test1.fa",
-            true, 2, t1 },
-        { "--argfile=test/jalview/bin/argparser/testfiles/argfile0.txt",
-            true, 1, ArrayUtils.concatArrays(t1, t3) },
-        { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
-            true, 4, ArrayUtils.concatArrays(t1, t2, t3) },
-        { "--argfile=test/jalview/bin/argparser/testfiles/argfile.autocounter",
-            true, 3, ArrayUtils.concatArrays(t1, t2) } };
+        { "examples/uniref50.fa " + testfiles + "/test1.fa", true, 2,
+            ArrayUtils.concatArrays(someUniref50Seqs, t1) },
+        { "examples/uniref50.fa " + testfiles + "/test1.fa", true, 2, t1 },
+        { "--argfile=" + testfiles + "/argfile0.txt", true, 1,
+            ArrayUtils.concatArrays(t1, t3) },
+        { "--argfile=" + testfiles + "/argfile*.txt", true, 4,
+            ArrayUtils.concatArrays(t1, t2, t3) },
+        { "--argfile=" + testfiles + "/argfile.autocounter", true, 3,
+            ArrayUtils.concatArrays(t1, t2) } };
   }
 
   public static boolean lookForSequenceName(String sequenceName)
@@ -132,4 +176,18 @@ public class CommandsTest
     return false;
   }
 
+  public static void cleanupArgfilesImages()
+  {
+    File png1File = new File(png1);
+    File png2File = new File(png2);
+    if (png1File.exists())
+    {
+      png1File.delete();
+    }
+    if (png2File.exists())
+    {
+      png2File.delete();
+    }
+  }
+
 }
diff --git a/test/jalview/bin/argparser/testfiles/dir1/argfile.txt b/test/jalview/bin/argparser/testfiles/dir1/argfile.txt
new file mode 100644 (file)
index 0000000..961c1d2
--- /dev/null
@@ -0,0 +1,5 @@
+--substitutions
+--increment
+--open={argfiledirname}/*.fa
+--colour=gecos:flower
+--image={argfiledirname}/{basename}.png
diff --git a/test/jalview/bin/argparser/testfiles/dir1/test1.fa b/test/jalview/bin/argparser/testfiles/dir1/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir1/test2.fa b/test/jalview/bin/argparser/testfiles/dir1/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/dir2/argfile.txt b/test/jalview/bin/argparser/testfiles/dir2/argfile.txt
new file mode 100644 (file)
index 0000000..961c1d2
--- /dev/null
@@ -0,0 +1,5 @@
+--substitutions
+--increment
+--open={argfiledirname}/*.fa
+--colour=gecos:flower
+--image={argfiledirname}/{basename}.png
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test1.fa b/test/jalview/bin/argparser/testfiles/dir2/test1.fa
new file mode 100644 (file)
index 0000000..c9e687f
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST1
+AAAA
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test2.fa b/test/jalview/bin/argparser/testfiles/dir2/test2.fa
new file mode 100644 (file)
index 0000000..fbd15c3
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST2
+LLLL
diff --git a/test/jalview/bin/argparser/testfiles/dir2/test3.fa b/test/jalview/bin/argparser/testfiles/dir2/test3.fa
new file mode 100644 (file)
index 0000000..f9503d4
--- /dev/null
@@ -0,0 +1,2 @@
+>TEST3
+AAARG