JAL-4277 Corrected choice of all or last opened linkedIds. Better wildcard syntactic...
authorBen Soares <b.soares@dundee.ac.uk>
Thu, 7 Sep 2023 16:05:07 +0000 (17:05 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Thu, 7 Sep 2023 16:05:07 +0000 (17:05 +0100)
src/jalview/bin/argparser/ArgParser.java
src/jalview/bin/argparser/ArgValuesMap.java
src/jalview/util/FileUtils.java
test/jalview/bin/CommandsTest.java
test/jalview/bin/argparser/ArgParserTest.java
test/jalview/util/FileUtilsTest.java

index 947a49e..41189b8 100644 (file)
@@ -505,14 +505,16 @@ public class ArgParser
           if (linkedId == null)
           {
             if (a.hasOption(Opt.OUTPUTFILE) && a.hasOption(Opt.ALLOWMULTIID)
-                    && val.startsWith(MATCHALLLINKEDIDS))
+                    && val.contains(MATCHALLLINKEDIDS))
             {
-              // --output=*.ext is shorthand for --all --output {basename}.ext
+              // --output=*.ext is shorthand for --output {basename}.ext
+              // --output=*/*.ext is shorthand for
+              // --output {dirname}/{basename}.ext
               // (or --image=*.ext)
-              allLinkedIds = true;
-              linkedId = MATCHALLLINKEDIDS;
-              val = LINKEDIDDIRNAME + File.separator + LINKEDIDBASENAME
-                      + val.substring(MATCHALLLINKEDIDS.length());
+              linkedId = allLinkedIds ? MATCHALLLINKEDIDS
+                      : MATCHOPENEDLINKEDIDS;
+              val = FileUtils.convertWildcardsToPath(val, MATCHALLLINKEDIDS,
+                      LINKEDIDDIRNAME, LINKEDIDBASENAME);
             }
             else if (allLinkedIds && a.hasOption(Opt.ALLOWMULTIID))
             {
index ab6fcc1..4aa8570 100644 (file)
@@ -226,7 +226,7 @@ public class ArgValuesMap
    */
   public String getBasename()
   {
-    return getDirBasenameOrExtension(false, false);
+    return getDirBasenameOrExtension(false, false, false);
   }
 
   /*
@@ -235,7 +235,7 @@ public class ArgValuesMap
    */
   public String getExtension()
   {
-    return getDirBasenameOrExtension(false, true);
+    return getDirBasenameOrExtension(false, true, false);
   }
 
   /*
@@ -244,11 +244,11 @@ public class ArgValuesMap
    */
   public String getDirname()
   {
-    return getDirBasenameOrExtension(true, false);
+    return getDirBasenameOrExtension(true, false, false);
   }
 
   public String getDirBasenameOrExtension(boolean dirname,
-          boolean extension)
+          boolean extension, boolean absoluteDirname)
   {
     String filename = null;
     String appendVal = getValue(Arg.APPEND);
index e62a7d6..79cac0a 100644 (file)
@@ -17,8 +17,6 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import jalview.bin.Console;
-
 public class FileUtils
 {
   /*
@@ -36,6 +34,8 @@ public class FileUtils
           boolean allowSingleFilenameThatDoesNotExist)
   {
     pattern = substituteHomeDir(pattern);
+    String relativePattern = pattern.startsWith(File.separator) ? null
+            : pattern;
     List<File> files = new ArrayList<>();
     /*
      * For efficiency of the Files.walkFileTree(), let's find the longest path that doesn't need globbing.
@@ -60,7 +60,11 @@ public class FileUtils
     {
       String pS = pattern.substring(0, lastFS + 1);
       String rest = pattern.substring(lastFS + 1);
-      Path parentDir = Paths.get(pS).toAbsolutePath();
+      if ("".equals(pS))
+      {
+        pS = ".";
+      }
+      Path parentDir = Paths.get(pS);
       if (parentDir.toFile().exists())
       {
         try
@@ -175,18 +179,51 @@ public class FileUtils
       return null;
 
     String dirname = null;
-    try
+    File p = file.getParentFile();
+    if (p == null)
     {
-      File p = file.getParentFile();
-      File d = new File(substituteHomeDir(p.getPath()));
-      dirname = d.getCanonicalPath();
-    } catch (IOException e)
-    {
-      Console.debug(
-              "Exception when getting dirname of '" + file.getPath() + "'",
-              e);
-      dirname = "";
+      p = new File(".");
     }
+    File d = new File(substituteHomeDir(p.getPath()));
+    dirname = d.getPath();
     return dirname;
   }
+
+  public static String convertWildcardsToPath(String value, String wildcard,
+          String dirname, String basename)
+  {
+    if (value == null)
+    {
+      return null;
+    }
+    StringBuilder path = new StringBuilder();
+    int lastFileSeparatorIndex = value.lastIndexOf(File.separatorChar);
+    int wildcardBeforeIndex = value.indexOf(wildcard);
+    if (lastFileSeparatorIndex > wildcard.length() - 1
+            && wildcardBeforeIndex < lastFileSeparatorIndex)
+    {
+      path.append(value.substring(0, wildcardBeforeIndex));
+      path.append(dirname);
+      path.append(value.substring(wildcardBeforeIndex + wildcard.length(),
+              lastFileSeparatorIndex + 1));
+    }
+    else
+    {
+      path.append(value.substring(0, lastFileSeparatorIndex + 1));
+    }
+    int wildcardAfterIndex = value.indexOf(wildcard,
+            lastFileSeparatorIndex);
+    if (wildcardAfterIndex > lastFileSeparatorIndex)
+    {
+      path.append(value.substring(lastFileSeparatorIndex + 1,
+              wildcardAfterIndex));
+      path.append(basename);
+      path.append(value.substring(wildcardAfterIndex + wildcard.length()));
+    }
+    else
+    {
+      path.append(value.substring(lastFileSeparatorIndex + 1));
+    }
+    return path.toString();
+  }
 }
index fe40682..36522c4 100644 (file)
@@ -364,8 +364,6 @@ public class CommandsTest
   {
     return new Object[][] {
         //
-        /*
-         */
         { "--gui --open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/test1.stk",
@@ -408,7 +406,7 @@ public class CommandsTest
                 "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
                 "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
             null },
-        { "--gui --open=test/jalview/bin/argparser/**/*.fa --output=*.stk --close",
+        { "--gui --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",
@@ -423,7 +421,7 @@ public class CommandsTest
                 "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
                 "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk", },
             null },
-        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=*.stk --close",
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --all --output=*/*.stk --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
                 "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
@@ -438,7 +436,20 @@ public class CommandsTest
                 "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", }, },
-        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=open*.stk --close",
+        { "--gui --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/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", }, },
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output={dirname}/{basename}.stk --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
                 "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
@@ -453,7 +464,7 @@ public class CommandsTest
                 "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", }, },
-        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --opened --output={dirname}/{basename}.stk --close",
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output={dirname}/{basename}.stk --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
                 "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
@@ -468,7 +479,7 @@ public class CommandsTest
                 "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", }, },
-        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --output open*.stk --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output=open*.aln --close",
+        { "--gui --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --output {dirname}/{basename}.stk --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output={dirname}/{basename}.aln --close",
             new String[]
             { "test/jalview/bin/argparser/testfiles/dir1/test1.stk",
                 "test/jalview/bin/argparser/testfiles/dir1/test2.stk",
index 9beba17..3ba096e 100644 (file)
@@ -279,9 +279,15 @@ public class ArgParserTest
   }
 
   @Test(groups = "Functional", dataProvider = "allLinkedIdsData")
-  public void allLinkedIdsTest(String commandLineArgs, Arg a,
+  public void allLinkedIdsTest(String pwd, String commandLineArgs, Arg a,
           String[] values, String[] nonvalues)
   {
+    String userDir = System.getProperty("user.dir");
+    if (pwd != null)
+    {
+      File pwdFile = new File(pwd);
+      System.setProperty("user.dir", pwdFile.getAbsolutePath());
+    }
     String[] args = commandLineArgs.split("\\s+");
     ArgParser argparser = new ArgParser(args);
 
@@ -306,12 +312,13 @@ public class ArgParserTest
         ArgValues avs = avm.getArgValues(a);
         ArgValue av = avs.getArgValue();
         String v = av.getValue();
-        value = new File(value).getAbsolutePath();
+        value = new File(value).getPath();
         Assert.assertEquals(v, value, "Arg value for " + a.argString()
                 + " not applied correctly to linkedId '" + linkedId + "'");
       }
     }
 
+    System.setProperty("user.dir", userDir);
   }
 
   @DataProvider(name = "allLinkedIdsData")
@@ -321,22 +328,33 @@ public class ArgParserTest
         //
         /*
         */
-        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
+        { null,
+            "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
             Arg.CLOSE, new String[]
             { null, null, null },
             null },
-        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
+        { 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", },
             null },
-        { "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
+        { 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", },
             null },
+        /*
+         * Find a way to change pwd reliably -- need to match "*.fa" against some files!
+         { "test/jalview/bin/argparser/testfiles",
+         
+            "--open=*.fa --image={dirname}/{basename}.png --close",
+            Arg.IMAGE, new String[]
+            { "./test1.png", "./test2.png", "./test3.png", }, null },
+            */
         //
     };
   }
@@ -414,4 +432,4 @@ public class ArgParserTest
     };
   }
 
-}
+}
\ No newline at end of file
index 35853b0..e977efa 100644 (file)
@@ -119,4 +119,54 @@ public class FileUtilsTest
         { "examples/uniref50.fa", 1, "/examples", "uniref50", ".fa" }, //
     };
   }
+
+  @Test(groups = "Functional", dataProvider = "convertWildcardsToPathData")
+  public void convertWildcardsToPathTest(String value, String wildcard,
+          String dirname, String basename, String path)
+  {
+
+    Assert.assertEquals(
+            FileUtils.convertWildcardsToPath(value, wildcard, dirname,
+                    basename),
+            path, "Conversion of wildcard output path is not right.");
+
+  }
+
+  @DataProvider(name = "convertWildcardsToPathData")
+  public Object[][] convertWildcardsToPathData()
+  {
+    return new Object[][] {
+        /*
+         * cmdline args
+         * Arg (null if only testing headless)
+         * String value if there is one (null otherwise)
+         * boolean value if String value is null
+         * expected value of isHeadless()
+         */
+        /*
+        */
+        { "*/*", "*", "{dirname}", "{basename}", "{dirname}/{basename}" },
+        { "*/", "*", "{dirname}", "{basename}", "{dirname}/" },
+        { "/*", "*", "{dirname}", "{basename}", "/{basename}" },
+        { "*", "*", "{dirname}", "{basename}", "{basename}" },
+        { "tmp/output/*/file-*.stk", "*", "{dirname}", "{basename}",
+            "tmp/output/{dirname}/file-{basename}.stk" },
+        { "/*.file", "*", "{dirname}", "{basename}", "/{basename}.file" },
+        { "*/file.stk", "*", "{dirname}", "{basename}",
+            "{dirname}/file.stk" },
+        { "tmp/abc*def/file.stk", "*", "{dirname}", "{basename}",
+            "tmp/abc{dirname}def/file.stk" },
+        { "a*b/c*d", "*", "{dirname}", "{basename}",
+            "a{dirname}b/c{basename}d" },
+        { "a*b/c", "*", "{dirname}", "{basename}", "a{dirname}b/c" },
+        { "a/b*c", "*", "{dirname}", "{basename}", "a/b{basename}c" },
+        { "a*b", "*", "{dirname}", "{basename}", "a{basename}b" },
+        { "aSTARb/cSTARd", "STAR", "BEFORE", "AFTER", "aBEFOREb/cAFTERd" },
+        { "aSTARb/c", "STAR", "BEFORE", "AFTER", "aBEFOREb/c" },
+        { "a/bSTARc", "STAR", "BEFORE", "AFTER", "a/bAFTERc" },
+        { "aSTARb", "STAR", "BEFORE", "AFTER", "aAFTERb" },
+        //
+    };
+  }
+
 }