JAL-629 Added --opened arg which is like limiting --all to only the previously -...
authorBen Soares <b.soares@dundee.ac.uk>
Fri, 12 May 2023 14:34:06 +0000 (15:34 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Fri, 12 May 2023 14:34:06 +0000 (15:34 +0100)
src/jalview/bin/Commands.java
src/jalview/bin/argparser/Arg.java
src/jalview/bin/argparser/ArgParser.java
test/jalview/bin/CommandsTest.java
test/jalview/bin/argparser/ArgParserTest.java

index 679fbf4..50ff7c3 100644 (file)
@@ -693,6 +693,8 @@ public class Commands
         Cache.setPropsAreReadOnly(true);
         Cache.setProperty("EXPORT_EMBBED_BIOJSON", "false");
 
+        Console.info("Writing " + file);
+
         switch (type)
         {
 
@@ -838,6 +840,9 @@ public class Commands
         Console.debug("Setting backups to " + backups);
         Cache.applicationProperties.put(BackupFiles.ENABLED,
                 Boolean.toString(backups));
+
+        Console.info("Writing " + fileName);
+
         af.saveAlignment(fileName, ff);
         Console.debug("Returning backups to " + savedBackupsPreference);
         if (savedBackupsPreference != null)
index ba981fb..46de01b 100644 (file)
@@ -54,20 +54,23 @@ public enum Arg
   // Opening an alignment
   OPEN("Opens one or more alignment files or URLs in new alignment windows.",
           Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER, Opt.MULTI,
-          Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT),
+          Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.STORED),
   APPEND("Appends one or more alignment files or URLs to the open alignment window (or opens a new alignment if none already open).",
           Opt.STRING, Opt.LINKED, Opt.MULTI, Opt.GLOB,
           Opt.ALLOWSUBSTITUTIONS, Opt.INPUT),
   TITLE("Specifies the title for the open alignment window as string.",
           Opt.STRING, Opt.LINKED),
-  COLOUR("Applies the colour scheme to the open alignment window. Valid values are:\n"
-          + "clustal,\n" + "blosum62,\n" + "pc-identity,\n" + "zappo,\n"
-          + "taylor,\n" + "gecos-flower,\n" + "gecos-blossom,\n"
-          + "gecos-sunset,\n" + "gecos-ocean,\n" + "hydrophobic,\n"
-          + "helix-propensity,\n" + "strand-propensity,\n"
-          + "turn-propensity,\n" + "buried-index,\n" + "nucleotide,\n"
-          + "nucleotide-ambiguity,\n" + "purine-pyrimidine,\n"
-          + "rna-helices,\n" + "t-coffee-scores,\n" + "sequence-id.",
+  COLOUR("color", // being a bit soft on the Americans!
+          "Applies the colour scheme to the open alignment window. Valid values are:\n"
+                  + "clustal,\n" + "blosum62,\n" + "pc-identity,\n"
+                  + "zappo,\n" + "taylor,\n" + "gecos-flower,\n"
+                  + "gecos-blossom,\n" + "gecos-sunset,\n"
+                  + "gecos-ocean,\n" + "hydrophobic,\n"
+                  + "helix-propensity,\n" + "strand-propensity,\n"
+                  + "turn-propensity,\n" + "buried-index,\n"
+                  + "nucleotide,\n" + "nucleotide-ambiguity,\n"
+                  + "purine-pyrimidine,\n" + "rna-helices,\n"
+                  + "t-coffee-scores,\n" + "sequence-id.",
           Opt.STRING, Opt.LINKED, Opt.ALLOWALL),
   FEATURES("Add a feature file or URL to the open alignment.", Opt.STRING,
           Opt.LINKED, Opt.MULTI, Opt.ALLOWSUBSTITUTIONS),
@@ -173,6 +176,8 @@ public enum Arg
           Opt.UNARY, Opt.MULTI, Opt.NOACTION),
   ALL("Apply the following output arguments to all sets of linked arguments.",
           Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
+  OPENED("Apply the following output arguments to all of the last --open'ed set of linked arguments.",
+          Opt.BOOLEAN, Opt.MULTI, Opt.NOACTION),
   QUIT("After all files have been opened, appended and output, quit Jalview. In ‑‑headless mode this already happens.",
           Opt.UNARY),
 
@@ -256,6 +261,7 @@ public enum Arg
                   // input (i.e. --open or --append)
     OUTPUT, // This Arg provides an output filename. With Opt.ALLOWALL *.ext is
             // shorthand for --all --output={basename}.ext
+    STORED, // This Arg resets and creates a new set of "opened" linkedIds
   }
 
   private final String[] argNames;
index 3ca5d3d..7132e89 100644 (file)
@@ -55,6 +55,9 @@ public class ArgParser
   // the linkedId string used to match all linkedIds seen so far
   protected static final String MATCHALLLINKEDIDS = "*";
 
+  // the linkedId string used to match all of the last --open'ed linkedIds
+  protected static final String MATCHOPENEDLINKEDIDS = "open*";
+
   // the counter added to the default linked id prefix
   private int defaultLinkedIdCounter = 0;
 
@@ -110,12 +113,18 @@ public class ArgParser
   // or ALL linkedIds
   private boolean allLinkedIds = false;
 
+  // flag to say whether the default linkedId is the current default linked id
+  // or OPENED linkedIds
+  private boolean openedLinkedIds = false;
+
   protected static final Map<String, Arg> argMap;
 
   protected Map<String, ArgValuesMap> linkedArgs = new HashMap<>();
 
   protected List<String> linkedOrder = new ArrayList<>();
 
+  protected List<String> storedLinkedIds = new ArrayList<>();
+
   protected List<Arg> argList = new ArrayList<>();
 
   private static final char ARGFILECOMMENT = '#';
@@ -380,6 +389,18 @@ public class ArgParser
         else if (a == Arg.ALL)
         {
           allLinkedIds = !negated;
+          openedLinkedIds = false;
+        }
+        else if (a == Arg.OPENED)
+        {
+          openedLinkedIds = !negated;
+          allLinkedIds = false;
+        }
+
+        if (a.hasOption(Opt.STORED))
+        {
+          // reset the lastOpenedLinkedIds list
+          this.storedLinkedIds = new ArrayList<>();
         }
 
         // this is probably only Arg.NEW and Arg.OPEN
@@ -398,20 +419,36 @@ public class ArgParser
           if (linkedId == null)
           {
             if (a.hasOption(Opt.OUTPUT) && a.hasOption(Opt.ALLOWALL)
-                    && val.startsWith(OUTPUTWILDCARD))
+                    && val.startsWith(MATCHALLLINKEDIDS))
             {
               // --output=*.ext is shorthand for --all --output {basename}.ext
               // (or --image=*.ext)
               allLinkedIds = true;
+              openedLinkedIds = false;
               linkedId = MATCHALLLINKEDIDS;
-              String oldval = val;
-              val = LINKEDIDBASENAME
-                      + val.substring(OUTPUTWILDCARD.length() - 1);
+              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
+                      + val.substring(MATCHALLLINKEDIDS.length());
+            }
+            else if (a.hasOption(Opt.OUTPUT) && a.hasOption(Opt.ALLOWALL)
+                    && val.startsWith(MATCHOPENEDLINKEDIDS))
+            {
+              // --output=open*.ext is shorthand for --opened --output
+              // {basename}.ext
+              // (or --image=open*.ext)
+              openedLinkedIds = true;
+              allLinkedIds = false;
+              linkedId = MATCHOPENEDLINKEDIDS;
+              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
+                      + val.substring(MATCHOPENEDLINKEDIDS.length());
             }
             else if (allLinkedIds && a.hasOption(Opt.ALLOWALL))
             {
               linkedId = MATCHALLLINKEDIDS;
             }
+            else if (openedLinkedIds && a.hasOption(Opt.ALLOWALL))
+            {
+              linkedId = MATCHOPENEDLINKEDIDS;
+            }
             else
             {
               // use default linkedId for linked arguments
@@ -514,9 +551,12 @@ public class ArgParser
           setBoolean(linkedId, avs, true, argIndex);
         }
 
-        // remove the '*' linkedId that should be empty if it was created
-        if (MATCHALLLINKEDIDS.equals(linkedId)
+        // remove the '*' or 'open*' linkedId that should be empty if it was
+        // created
+        if ((MATCHALLLINKEDIDS.equals(linkedId)
                 && linkedArgs.containsKey(linkedId))
+                || (MATCHOPENEDLINKEDIDS.equals(linkedId)
+                        && linkedArgs.containsKey(linkedId)))
         {
           linkedArgs.remove(linkedId);
         }
@@ -930,16 +970,52 @@ public class ArgParser
   }
 
   // the following methods look for the "*" linkedId and add the argvalue to all
-  // linkedId ArgValues if it does
+  // linkedId ArgValues if it does.
+  // This version inserts the subvals sv into all created values
   private void addValue(String linkedId, ArgValues avs, SubVals sv,
           String v, int argIndex, boolean doSubs)
   {
+    this.argValueOperation(Op.ADDVALUE, linkedId, avs, sv, v, false,
+            argIndex, doSubs);
+  }
+
+  private void NOTaddValue(String linkedId, ArgValues avs, SubVals sv,
+          String v, int argIndex, boolean doSubs)
+  {
     Arg a = avs.arg();
-    if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL))
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
     {
-      for (String id : getLinkedIds())
+      switch (linkedId)
       {
-        if (id == null || MATCHALLLINKEDIDS.equals(id))
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
           continue;
         ArgValuesMap avm = linkedArgs.get(id);
         if (a.hasOption(Opt.REQUIREINPUT)
@@ -972,12 +1048,54 @@ public class ArgParser
   private void addValue(String linkedId, ArgValues avs, String v,
           int argIndex, boolean doSubs)
   {
+    this.argValueOperation(Op.ADDVALUE, linkedId, avs, null, v, false,
+            argIndex, doSubs);
+  }
+
+  // the following methods look for the "*" linkedId and add the argvalue to all
+  // linkedId ArgValues if it does.
+  private void NOTaddValue(String linkedId, ArgValues avs, String v,
+          int argIndex, boolean doSubs)
+  {
     Arg a = avs.arg();
-    if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL))
+    if (linkedId != null && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
     {
-      for (String id : getLinkedIds())
+      storedLinkedIds.add(linkedId);
+    }
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
+    {
+      switch (linkedId)
       {
-        if (id == null || MATCHALLLINKEDIDS.equals(id))
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
           continue;
         ArgValuesMap avm = linkedArgs.get(id);
         // don't set an output if there isn't an input
@@ -1001,12 +1119,52 @@ public class ArgParser
   private void setBoolean(String linkedId, ArgValues avs, boolean b,
           int argIndex)
   {
+    this.argValueOperation(Op.SETBOOLEAN, linkedId, avs, null, null, b,
+            argIndex, false);
+  }
+
+  private void NOTsetBoolean(String linkedId, ArgValues avs, boolean b,
+          int argIndex)
+  {
     Arg a = avs.arg();
-    if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL))
+    if (linkedId != null && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
     {
-      for (String id : getLinkedIds())
+      storedLinkedIds.add(linkedId);
+    }
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
+    {
+      switch (linkedId)
+      {
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
       {
-        if (id == null || MATCHALLLINKEDIDS.equals(id))
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
           continue;
         ArgValuesMap avm = linkedArgs.get(id);
         if (a.hasOption(Opt.REQUIREINPUT)
@@ -1026,12 +1184,51 @@ public class ArgParser
 
   private void setNegated(String linkedId, ArgValues avs, boolean b)
   {
+    this.argValueOperation(Op.SETNEGATED, linkedId, avs, null, null, b, 0,
+            false);
+  }
+
+  private void NOTsetNegated(String linkedId, ArgValues avs, boolean b)
+  {
     Arg a = avs.arg();
-    if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL))
+    if (linkedId != null && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
     {
-      for (String id : getLinkedIds())
+      storedLinkedIds.add(linkedId);
+    }
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
+    {
+      switch (linkedId)
       {
-        if (id == null || MATCHALLLINKEDIDS.equals(id))
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
           continue;
         ArgValuesMap avm = linkedArgs.get(id);
         if (a.hasOption(Opt.REQUIREINPUT)
@@ -1049,12 +1246,46 @@ public class ArgParser
 
   private void incrementCount(String linkedId, ArgValues avs)
   {
+    this.argValueOperation(Op.INCREMENTCOUNT, linkedId, avs, null, null,
+            false, 0, false);
+  }
+
+  private void NOTincrementCount(String linkedId, ArgValues avs)
+  {
     Arg a = avs.arg();
-    if (MATCHALLLINKEDIDS.equals(linkedId) && a.hasOption(Opt.ALLOWALL))
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
     {
-      for (String id : getLinkedIds())
+      switch (linkedId)
       {
-        if (id == null || MATCHALLLINKEDIDS.equals(id))
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
           continue;
         ArgValuesMap avm = linkedArgs.get(id);
         if (a.hasOption(Opt.REQUIREINPUT)
@@ -1070,6 +1301,149 @@ public class ArgParser
     }
   }
 
+  private enum Op
+  {
+    ADDVALUE, SETBOOLEAN, SETNEGATED, INCREMENTCOUNT
+  }
+
+  // The following operations look for the "*" and "open*" linkedIds and add the
+  // argvalue to all appropriate linkedId ArgValues if it does.
+  // If subvals are supplied, they are inserted into all new set values.
+  private void argValueOperation(Op op, String linkedId, ArgValues avs,
+          SubVals sv, String v, boolean b, int argIndex, boolean doSubs)
+  {
+    Arg a = avs.arg();
+
+    List<String> wildcardLinkedIds = null;
+    if (a.hasOption(Opt.ALLOWALL))
+    {
+      switch (linkedId)
+      {
+      case MATCHALLLINKEDIDS:
+        wildcardLinkedIds = getLinkedIds();
+        break;
+      case MATCHOPENEDLINKEDIDS:
+        wildcardLinkedIds = this.storedLinkedIds;
+        break;
+      }
+    }
+
+    // if we're not a wildcard linkedId and the arg is marked to be stored, add
+    // to storedLinkedIds
+    if (linkedId != null && wildcardLinkedIds == null
+            && a.hasOption(Opt.STORED)
+            && !storedLinkedIds.contains(linkedId))
+    {
+      storedLinkedIds.add(linkedId);
+    }
+
+    // if we are a wildcard linkedId, apply the arg and value to all appropriate
+    // linkedIds
+    if (wildcardLinkedIds != null)
+    {
+      for (String id : wildcardLinkedIds)
+      {
+        // skip incorrectly stored wildcard ids!
+        if (id == null || MATCHALLLINKEDIDS.equals(id)
+                || MATCHOPENEDLINKEDIDS.equals(id))
+          continue;
+        ArgValuesMap avm = linkedArgs.get(id);
+        // don't set an output if there isn't an input
+        if (a.hasOption(Opt.REQUIREINPUT)
+                && !avm.hasArgWithOption(Opt.INPUT))
+          continue;
+
+        ArgValues tavs = avm.getOrCreateArgValues(a);
+        switch (op)
+        {
+
+        case ADDVALUE:
+          String val = v;
+          if (sv != null)
+          {
+            if (doSubs)
+            {
+              val = makeSubstitutions(v, id);
+              sv = new SubVals(sv, val);
+            }
+            tavs.addValue(sv, val, argIndex);
+          }
+          else
+          {
+            if (doSubs)
+            {
+              val = makeSubstitutions(v, id);
+            }
+            tavs.addValue(val, argIndex);
+          }
+          finaliseStoringArgValue(id, tavs);
+          break;
+
+        case SETBOOLEAN:
+          tavs.setBoolean(b, argIndex);
+          finaliseStoringArgValue(id, tavs);
+          break;
+
+        case SETNEGATED:
+          tavs.setNegated(b);
+          break;
+
+        case INCREMENTCOUNT:
+          tavs.incrementCount();
+          break;
+
+        default:
+          break;
+
+        }
+
+      }
+    }
+    else // no wildcard linkedId -- do it simpler
+    {
+      switch (op)
+      {
+      case ADDVALUE:
+        String val = v;
+        if (sv != null)
+        {
+          if (doSubs)
+          {
+            val = makeSubstitutions(v, linkedId);
+            sv = new SubVals(sv, val);
+          }
+          avs.addValue(sv, val, argIndex);
+        }
+        else
+        {
+          if (doSubs)
+          {
+            val = makeSubstitutions(v, linkedId);
+          }
+          avs.addValue(val, argIndex);
+        }
+        finaliseStoringArgValue(linkedId, avs);
+        break;
+
+      case SETBOOLEAN:
+        avs.setBoolean(b, argIndex);
+        finaliseStoringArgValue(linkedId, avs);
+        break;
+
+      case SETNEGATED:
+        avs.setNegated(b);
+        break;
+
+      case INCREMENTCOUNT:
+        avs.incrementCount();
+        break;
+
+      default:
+        break;
+      }
+    }
+  }
+
   private ArgValuesMap getOrCreateLinkedArgValuesMap(String linkedId)
   {
     if (linkedArgs.containsKey(linkedId)
index fed1976..8767098 100644 (file)
@@ -24,10 +24,6 @@ public class CommandsTest
 {
   private static final String testfiles = "test/jalview/bin/argparser/testfiles";
 
-  private static final String png1 = testfiles + "/dir1/test1.png";
-
-  private static final String png2 = testfiles + "/dir2/test1.png";
-
   @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
@@ -224,7 +220,8 @@ public class CommandsTest
   }
 
   @Test(groups = "Functional", dataProvider = "allLinkedIdsData")
-  public void allLinkedIdsTest(String cmdLine, String[] filenames)
+  public void allLinkedIdsTest(String cmdLine, String[] filenames,
+          String[] nonfilenames)
   {
     String[] args = cmdLine.split("\\s+");
     Jalview.main(args);
@@ -236,6 +233,15 @@ public class CommandsTest
               "File '" + filename + "' was not created");
     }
     cleanupFiles(filenames);
+    if (nonfilenames != null)
+    {
+      for (String nonfilename : nonfilenames)
+      {
+        File nonfile = new File(nonfilename);
+        Assert.assertFalse(nonfile.exists(),
+                "File " + nonfilename + " exists when it shouldn't!");
+      }
+    }
   }
 
   @DataProvider(name = "allLinkedIdsData")
@@ -244,22 +250,109 @@ public class CommandsTest
     return new Object[][] {
         //
         /*
+         */
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
-            Arg.OUTPUT, new String[]
+            new String[]
             { "test/jalview/bin/argparser/testfiles/test1.stk",
                 "test/jalview/bin/argparser/testfiles/test2.stk",
-                "test/jalview/bin/argparser/testfiles/test3.stk", } },
-        */
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            null },
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/test1.png",
                 "test/jalview/bin/argparser/testfiles/test2.png",
-                "test/jalview/bin/argparser/testfiles/test3.png", } },
+                "test/jalview/bin/argparser/testfiles/test3.png", },
+            null },
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --all --output={dirname}/{basename}.stk --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/test1.stk",
                 "test/jalview/bin/argparser/testfiles/test2.stk",
-                "test/jalview/bin/argparser/testfiles/test3.stk", } },
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--open=test/jalview/bin/argparser/**/*.fa --all --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
+            null },
+        { "--open=test/jalview/bin/argparser/**/*.fa --output=*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
+            null },
+        { "--open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=open*.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
+        { "--open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --opened --output={dirname}/{basename}.stk --close",
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir2/test3.stk", },
+            new String[]
+            { "test/jalview/bin/argparser/testfiles/test1.stk",
+                "test/jalview/bin/argparser/testfiles/test2.stk",
+                "test/jalview/bin/argparser/testfiles/test3.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+                "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", }, },
         //
     };
   }
index 17f19b7..259acac 100644 (file)
@@ -273,7 +273,7 @@ public class ArgParserTest
 
   @Test(groups = "Functional", dataProvider = "allLinkedIdsData")
   public void allLinkedIdsTest(String commandLineArgs, Arg a,
-          String[] values)
+          String[] values, String[] nonvalues)
   {
     String[] args = commandLineArgs.split("\\s+");
     ArgParser argparser = new ArgParser(args);
@@ -316,18 +316,20 @@ public class ArgParserTest
         */
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
             Arg.CLOSE, new String[]
-            { null, null,
-                null } },
+            { null, null, null },
+            null },
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
             Arg.OUTPUT, new String[]
             { "test/jalview/bin/argparser/testfiles/test1.stk",
                 "test/jalview/bin/argparser/testfiles/test2.stk",
-                "test/jalview/bin/argparser/testfiles/test3.stk", } },
+                "test/jalview/bin/argparser/testfiles/test3.stk", },
+            null },
         { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
             Arg.IMAGE, new String[]
             { "test/jalview/bin/argparser/testfiles/test1.png",
                 "test/jalview/bin/argparser/testfiles/test2.png",
-                "test/jalview/bin/argparser/testfiles/test3.png", } },
+                "test/jalview/bin/argparser/testfiles/test3.png", },
+            null },
         //
     };
   }