From 871535152992c147f2175c3006b6bec4615fead4 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Thu, 7 Sep 2023 17:05:07 +0100 Subject: [PATCH] JAL-4277 Corrected choice of all or last opened linkedIds. Better wildcard syntactic sugar for output files. Fixed all tests for new defaults. --- src/jalview/bin/argparser/ArgParser.java | 14 +++--- src/jalview/bin/argparser/ArgValuesMap.java | 8 ++-- src/jalview/util/FileUtils.java | 63 ++++++++++++++++++++----- test/jalview/bin/CommandsTest.java | 25 +++++++--- test/jalview/bin/argparser/ArgParserTest.java | 30 +++++++++--- test/jalview/util/FileUtilsTest.java | 50 ++++++++++++++++++++ 6 files changed, 154 insertions(+), 36 deletions(-) diff --git a/src/jalview/bin/argparser/ArgParser.java b/src/jalview/bin/argparser/ArgParser.java index 947a49e..41189b8 100644 --- a/src/jalview/bin/argparser/ArgParser.java +++ b/src/jalview/bin/argparser/ArgParser.java @@ -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)) { diff --git a/src/jalview/bin/argparser/ArgValuesMap.java b/src/jalview/bin/argparser/ArgValuesMap.java index ab6fcc1..4aa8570 100644 --- a/src/jalview/bin/argparser/ArgValuesMap.java +++ b/src/jalview/bin/argparser/ArgValuesMap.java @@ -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); diff --git a/src/jalview/util/FileUtils.java b/src/jalview/util/FileUtils.java index e62a7d6..79cac0a 100644 --- a/src/jalview/util/FileUtils.java +++ b/src/jalview/util/FileUtils.java @@ -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 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(); + } } diff --git a/test/jalview/bin/CommandsTest.java b/test/jalview/bin/CommandsTest.java index fe40682..36522c4 100644 --- a/test/jalview/bin/CommandsTest.java +++ b/test/jalview/bin/CommandsTest.java @@ -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", diff --git a/test/jalview/bin/argparser/ArgParserTest.java b/test/jalview/bin/argparser/ArgParserTest.java index 9beba17..3ba096e 100644 --- a/test/jalview/bin/argparser/ArgParserTest.java +++ b/test/jalview/bin/argparser/ArgParserTest.java @@ -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 diff --git a/test/jalview/util/FileUtilsTest.java b/test/jalview/util/FileUtilsTest.java index 35853b0..e977efa 100644 --- a/test/jalview/util/FileUtilsTest.java +++ b/test/jalview/util/FileUtilsTest.java @@ -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" }, + // + }; + } + } -- 1.7.10.2