private boolean argsWereParsed = false;
+ private List<String> errors = new ArrayList<>();
+
public Commands(ArgParser argparser, boolean headless)
{
this(Desktop.instance, argparser, headless);
}
}
+
+ // report errors
+ StringBuilder sb = new StringBuilder();
+ for (String error : errors)
+ {
+ sb.append("- " + error);
+ sb.append("\n");
+ }
+ if (Platform.isHeadless())
+ {
+ Console.debug("All errors from command line argument commands:\n"
+ + sb.toString());
+ }
+ else
+ {
+ // scrollable dialog box
+
+ }
+
if (argParser.getBoolean(Arg.QUIT))
{
Jalview.getInstance().exit(
boolean theseArgsWereParsed = false;
ArgValuesMap avm = argParser.getLinkedArgs(id);
if (avm == null)
+ {
return true;
+ }
+
+ boolean isError = false;
// set wrap scope here so it can be applied after structures are opened
boolean wrap = false;
{
if (!(new File(openFile)).exists())
{
- Console.warn("Can't find file '" + openFile + "'");
+ addError("Can't find file '" + openFile + "'");
+ isError = true;
continue;
}
}
format = new IdentifyFile().identify(openFile, protocol);
} catch (FileFormatException e1)
{
- Console.error("Unknown file format for '" + openFile + "'");
+ addError("Unknown file format for '" + openFile + "'");
+ isError = true;
continue;
}
} catch (Throwable thr)
{
xception = true;
- Console.error("Couldn't open '" + openFile + "' as " + format
- + " " + thr.getLocalizedMessage()
+ addError("Couldn't open '" + openFile + "' as " + format + " "
+ + thr.getLocalizedMessage()
+ " (Enable debug for full stack trace)");
+ isError = true;
Console.debug("Exception when opening '" + openFile + "'", thr);
} finally
{
if (af == null && !xception)
{
- Console.info("Ignoring '" + openFile
+ addInfo("Ignoring '" + openFile
+ "' - no alignment data found.");
continue;
}
if (cs == null && !"None".equals(colour))
{
- Console.warn(
- "Couldn't parse '" + colour + "' as a colourscheme.");
+ addWarn("Couldn't parse '" + colour + "' as a colourscheme.");
}
else
{
"examples/testdata/uniref50_test_tree", treefile);
} catch (IOException e)
{
- Console.warn("Couldn't add tree " + treefile, e);
+ addError("Couldn't add tree " + treefile, e);
+ isError = true;
}
}
}
else
{
- Console.warn("No more files to open");
+ Console.info("No more files to open");
}
}
if (progressBarSet && desktop != null)
if (seq == null)
{
- Console.warn("Could not find sequence for argument "
+ addWarn("Could not find sequence for argument "
+ Arg.STRUCTURE.argString() + "=" + val);
- // you probably want to continue here, not break
- // break;
continue;
}
File structureFile = null;
if (structureFile == null)
{
- Console.warn("Not provided structure file with '" + val + "'");
+ addWarn("Not provided structure file with '" + val + "'");
continue;
}
if (!structureFile.exists())
{
- Console.warn("Structure file '"
- + structureFile.getAbsoluteFile() + "' not found.");
+ addWarn("Structure file '" + structureFile.getAbsoluteFile()
+ + "' not found.");
continue;
}
} catch (IOException e)
{
paeFilepath = paeFile.getAbsolutePath();
- Console.warn("Problem with the PAE file path: '"
+ addWarn("Problem with the PAE file path: '"
+ paeFile.getPath() + "'");
}
}
if (it.hasNext())
sb.append(", ");
}
- Console.warn(sb.toString());
+ addWarn(sb.toString());
}
}
if (sv == null)
{
- Console.error("Failed to import and open structure view.");
+ addError("Failed to import and open structure view for file '"
+ + structureFile + "'.");
continue;
}
try
}
if (tries == 0 && sv.isBusy())
{
- Console.warn(
- "Gave up waiting for structure viewer to load. Something may have gone wrong.");
+ addWarn("Gave up waiting for structure viewer to load file '"
+ + structureFile
+ + "'. Something may have gone wrong.");
}
} catch (Exception x)
{
- Console.warn("Exception whilst waiting for structure viewer "
+ addError("Exception whilst waiting for structure viewer "
+ structureFilepath, x);
+ isError = true;
}
// add StructureViewer to svMap list
typeS.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e)
{
- Console.warn("Do not know image format '" + typeS
+ addWarn("Do not know image format '" + typeS
+ "', using PNG");
imageType = TYPE.PNG;
}
AppJmol jmol = (AppJmol) sview;
try
{
+ whatNext wn = this.checksBeforeWritingToFile(avm, subVals,
+ false, structureImageFilename, "structure image");
+ if (wn == whatNext.ERROR)
+ {
+ isError = true;
+ continue;
+ }
+ else if (wn == whatNext.CONTINUE)
+ {
+ continue;
+ }
+
Console.debug("Rendering image to " + structureImageFile);
jmol.makePDBImage(structureImageFile, imageType, renderer,
userBis);
} catch (ImageOutputException ioexc)
{
- Console.warn("Unexpected error whilst exporting image to "
+ addError("Unexpected error whilst exporting image to "
+ structureImageFile, ioexc);
+ isError = true;
+ continue;
}
}
break;
default:
- Console.warn("Cannot export image for structure viewer "
+ addWarn("Cannot export image for structure viewer "
+ sv.getViewerType() + " yet");
- break;
+ continue;
}
}
}
}
*/
- return theseArgsWereParsed;
+ return theseArgsWereParsed && !isError;
}
protected void processGroovyScript(String id)
if (af == null)
{
- Console.warn("Did not have an alignment window for id=" + id);
+ addWarn("Did not have an alignment window for id=" + id);
return;
}
if (af == null)
{
- Console.warn("Did not have an alignment window for id=" + id);
+ addWarn("Did not have an alignment window for id=" + id);
return false;
}
+ boolean isError = false;
if (avm.containsArg(Arg.IMAGE))
{
for (ArgValue av : avm.getArgValueList(Arg.IMAGE))
Cache.setProperty("EXPORT_EMBBED_BIOJSON", "false");
Console.info("Writing " + file);
+
+ whatNext wn = this.checksBeforeWritingToFile(avm, subVal, false,
+ fileName, "image");
+ if (wn == whatNext.ERROR)
+ {
+ isError = true;
+ continue;
+ }
+ else if (wn == whatNext.CONTINUE)
+ {
+ continue;
+ }
+
try
{
switch (type)
break;
default:
- Console.warn(Arg.IMAGE.argString() + " type '" + type
+ addWarn(Arg.IMAGE.argString() + " type '" + type
+ "' not known. Ignoring");
break;
}
} catch (Exception ioex)
{
- Console.warn("Unexpected error during export", ioex);
+ addError("Unexpected error during export to '" + fileName + "'",
+ ioex);
+ isError = true;
}
}
}
- return true;
+ return !isError;
}
protected boolean processOutput(String id)
if (af == null)
{
- Console.warn("Did not have an alignment window for id=" + id);
+ addWarn("Did not have an alignment window for id=" + id);
return false;
}
+ boolean isError = false;
+
if (avm.containsArg(Arg.OUTPUT))
{
for (ArgValue av : avm.getArgValueList(Arg.OUTPUT))
String fileName = subVals.getContent();
boolean stdout = ArgParser.STDOUTFILENAME.equals(fileName);
File file = new File(fileName);
- boolean overwrite = ArgParser.getFromSubValArgOrPref(avm,
- Arg.OVERWRITE, subVals, null, "OVERWRITE_OUTPUT", false);
- // backups. Use the Arg.BACKUPS or subval "backups" setting first,
- // otherwise if headless assume false, if not headless use the user
- // preference with default true.
- boolean backups = ArgParser.getFromSubValArgOrPref(avm, Arg.BACKUPS,
- subVals, null,
- Platform.isHeadless() ? null : BackupFiles.ENABLED,
- !Platform.isHeadless());
-
- // if backups is not true then --overwrite must be specified
- if (file.exists() && !(overwrite || backups || stdout))
- {
- Console.error("Won't overwrite file '" + fileName + "' without "
- + Arg.OVERWRITE.argString() + " or "
- + Arg.BACKUPS.argString() + " set");
- return false;
- }
String name = af.getName();
String format = ArgParser.getValueFromSubValOrArg(avm, av,
validSB.append(")");
}
- Jalview.exit("No valid format specified for "
+ addError("No valid format specified for "
+ Arg.OUTPUT.argString() + ". Valid formats are "
- + validSB.toString() + ".", ExitCode.INVALID_FORMAT);
- // this return really shouldn't happen
- return false;
+ + validSB.toString() + ".");
+ continue;
}
}
- String savedBackupsPreference = Cache
- .getDefault(BackupFiles.ENABLED, null);
- Console.debug("Setting backups to " + backups);
- Cache.applicationProperties.put(BackupFiles.ENABLED,
- Boolean.toString(backups));
+ whatNext wn = this.checksBeforeWritingToFile(avm, subVals, true,
+ fileName, ff.getName());
+ if (wn == whatNext.ERROR)
+ {
+ isError = true;
+ continue;
+ }
+ else if (wn == whatNext.CONTINUE)
+ {
+ continue;
+ }
+
+ boolean backups = ArgParser.getFromSubValArgOrPref(avm, Arg.BACKUPS,
+ subVals, null,
+ Platform.isHeadless() ? null : BackupFiles.ENABLED,
+ !Platform.isHeadless());
Console.info("Writing " + fileName);
- af.saveAlignment(fileName, ff, stdout);
- Console.debug("Returning backups to " + savedBackupsPreference);
- if (savedBackupsPreference != null)
- Cache.applicationProperties.put(BackupFiles.ENABLED,
- savedBackupsPreference);
+ af.saveAlignment(fileName, ff, stdout, backups);
if (af.isSaveAlignmentSuccessful())
{
Console.debug("Written alignment '" + name + "' in "
- + ff.getName() + " format to " + file);
+ + ff.getName() + " format to '" + file + "'");
}
else
{
- Console.warn("Error writing file " + file + " in " + ff.getName()
+ addError("Error writing file '" + file + "' in " + ff.getName()
+ " format!");
+ isError = true;
+ continue;
}
}
}
- return true;
+ return !isError;
}
private SequenceI getSpecifiedSequence(AlignFrame af, ArgValuesMap avm,
}
return svs;
}
+
+ private void addInfo(String errorMessage)
+ {
+ Console.info(errorMessage);
+ errors.add(errorMessage);
+ }
+
+ private void addWarn(String errorMessage)
+ {
+ Console.warn(errorMessage);
+ errors.add(errorMessage);
+ }
+
+ private void addError(String errorMessage)
+ {
+ addError(errorMessage, null);
+ }
+
+ private void addError(String errorMessage, Exception e)
+ {
+ Console.error(errorMessage, e);
+ errors.add(errorMessage);
+ }
+
+ private enum whatNext
+ {
+ OKAY, CONTINUE, ERROR;
+ }
+
+ private whatNext checksBeforeWritingToFile(ArgValuesMap avm,
+ SubVals subVal, boolean includeBackups, String filename,
+ String adjective)
+ {
+ File file = new File(filename);
+
+ boolean overwrite = ArgParser.getFromSubValArgOrPref(avm, Arg.OVERWRITE,
+ subVal, null, "OVERWRITE_OUTPUT", false);
+ boolean stdout = false;
+ boolean backups = false;
+ if (includeBackups)
+ {
+ stdout = ArgParser.STDOUTFILENAME.equals(filename);
+ // backups. Use the Arg.BACKUPS or subval "backups" setting first,
+ // otherwise if headless assume false, if not headless use the user
+ // preference with default true.
+ backups = ArgParser.getFromSubValArgOrPref(avm, Arg.BACKUPS, subVal,
+ null, Platform.isHeadless() ? null : BackupFiles.ENABLED,
+ !Platform.isHeadless());
+ }
+
+ if (file.exists() && !(overwrite || backups || stdout))
+ {
+ addWarn("Won't overwrite file '" + filename + "' without "
+ + Arg.OVERWRITE.argString()
+ + (includeBackups ? " or " + Arg.BACKUPS.argString() : "")
+ + " set");
+ return whatNext.CONTINUE;
+ }
+
+ boolean mkdirs = ArgParser.getFromSubValArgOrPref(avm, Arg.MKDIRS,
+ subVal, null, "MKDIRS_OUTPUT", false);
+
+ if (!FileUtils.checkParentDir(file, mkdirs))
+ {
+ addError("Directory '"
+ + FileUtils.getParentDir(file).getAbsolutePath()
+ + "' does not exist for " + adjective + " file '" + filename
+ + "'."
+ + (mkdirs ? "" : " Try using " + Arg.MKDIRS.argString()));
+ return whatNext.ERROR;
+ }
+
+ return whatNext.OKAY;
+ }
}
true, Opt.BOOLEAN, Opt.BOOTSTRAP, Opt.NOACTION, Opt.SECRET),
P(Type.CONFIG, "Set a Jalview preference value for this session.",
Opt.PREFIXKEV, Opt.PRESERVECASE, Opt.STRING, Opt.BOOTSTRAP,
- Opt.MULTIVALUE, Opt.NOACTION, Opt.SECRET), // keep this secret for now.
+ Opt.MULTIVALUE, Opt.NOACTION, Opt.SECRET), // keep this secret for
+ // now.
// Opening an alignment
OPEN(Type.OPENING,
"Opens one or more alignment files or URLs in new alignment windows.",
- Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER, Opt.MULTIVALUE,
- Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT, Opt.STORED,
- Opt.PRIMARY),
+ Opt.STRING, Opt.LINKED, Opt.INCREMENTDEFAULTCOUNTER,
+ Opt.MULTIVALUE, Opt.GLOB, Opt.ALLOWSUBSTITUTIONS, Opt.INPUT,
+ Opt.STORED, Opt.PRIMARY),
APPEND(Type.OPENING,
"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.MULTIVALUE, Opt.GLOB,
Opt.STRING, Opt.LINKED, Opt.MULTIVALUE, Opt.ALLOWMULTIID),
NOTEMPFAC(Type.STRUCTURE,
"Do not show the temperature factor annotation for the preceding --structure.",
- Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID, Opt.SECRET), // keep this secret
- // until it works!
+ Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID, Opt.SECRET), // keep this
+ // secret
+ // until it works!
SHOWSSANNOTATIONS(Type.STRUCTURE, null, Opt.BOOLEAN, Opt.LINKED,
Opt.ALLOWMULTIID),
CLOSE(Type.OPENING,
"Close the current open alignment window. This occurs after other output arguments. This applies to the current open alignment. To apply to all ‑‑output and ‑‑image files, use after ‑‑all.",
Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID),
+ MKDIRS(Type.OUTPUT,
+ "Automatically create directories when outputting a file to a new directory.",
+ Opt.UNARY, Opt.LINKED, Opt.ALLOWMULTIID),
// controlling flow of arguments
NEW(Type.FLOW,
"Move on to a new alignment window. This will ensure --append will start a new alignment window and other linked arguments will apply to the new alignment window.",
- Opt.UNARY, Opt.MULTIVALUE, Opt.NOACTION, Opt.INCREMENTDEFAULTCOUNTER),
+ Opt.UNARY, Opt.MULTIVALUE, Opt.NOACTION,
+ Opt.INCREMENTDEFAULTCOUNTER),
SUBSTITUTIONS(Type.FLOW,
"The following argument values allow (or don't allow) subsituting filename parts. This is initially true. Valid substitutions are:\n"
+ "{basename} - the filename-without-extension of the currently --opened file (or first --appended file),\n"
"Allow specific stdout information. For testing purposes only.",
Opt.UNARY, Opt.BOOTSTRAP, Opt.SECRET), // do not show this to the user
SETPROP(Type.CONFIG, "Set an individual Java System property.",
- Opt.STRING, Opt.MULTIVALUE, Opt.BOOTSTRAP, Opt.SECRET), // not in use yet
+ Opt.STRING, Opt.MULTIVALUE, Opt.BOOTSTRAP, Opt.SECRET), // not in use
+ // yet
NIL(Type.FLOW,
"This argument does nothing on its own, but can be used with linkedIds.",
Opt.UNARY, Opt.LINKED, Opt.MULTIVALUE, Opt.NOACTION, Opt.SECRET),
}
}
+ private final String deleteDir = "test/deleteAfter";
+
@Test(
groups = "Functional",
dataProvider = "allLinkedIdsData",
"File " + nonfilename + " exists when it shouldn't!");
}
}
+
+ File deleteDirF = new File(deleteDir);
+ if (deleteDirF.exists())
+ {
+ deleteDirF.delete();
+ }
}
@DataProvider(name = "allLinkedIdsData")
"test/jalview/bin/argparser/testfiles/dir3/subdir/test1.aln",
"test/jalview/bin/argparser/testfiles/dir3/subdir/test2.aln",
"test/jalview/bin/argparser/testfiles/dir3/subdir/test3.aln", }, },
+ // --mkdirs
+ { "--headless --open=test/jalview/bin/argparser/testfiles/dir1/*.fa --output "
+ + deleteDir
+ + "/{dirname}/{basename}.stk --open=test/jalview/bin/argparser/testfiles/dir2/*.fa --output="
+ + deleteDir
+ + "/{dirname}/{basename}.aln --close --all --mkdirs",
+ new String[]
+ { deleteDir
+ + "/test/jalview/bin/argparser/testfiles/dir1/test1.stk",
+ deleteDir
+ + "/test/jalview/bin/argparser/testfiles/dir1/test2.stk",
+ deleteDir
+ + "/test/jalview/bin/argparser/testfiles/dir2/test1.aln",
+ deleteDir
+ + "/test/jalview/bin/argparser/testfiles/dir2/test2.aln",
+ deleteDir
+ + "/test/jalview/bin/argparser/testfiles/dir2/test3.aln", },
+ 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/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",
+ "test/jalview/bin/argparser/testfiles/test1.aln",
+ "test/jalview/bin/argparser/testfiles/test2.aln",
+ "test/jalview/bin/argparser/testfiles/test3.aln",
+ "test/jalview/bin/argparser/testfiles/dir1/test1.aln",
+ "test/jalview/bin/argparser/testfiles/dir1/test2.aln",
+ "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.aln",
+ "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.aln",
+ "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.aln",
+ "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test1.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test2.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test3.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir2/test1.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir2/test2.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir2/test3.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.stk",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test1.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test2.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/test3.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir1/test1.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir1/test2.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test0.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test1.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test2.aln",
+ deleteDir
+ + "test/jalview/bin/argparser/testfiles/dir3/subdir/test3.aln", }, },
//
};
}