JAL-2937 Cygwin path preference, method refactoring
[jalview.git] / src / jalview / hmmer / HmmerCommand.java
index fe6c0f9..9bec181 100644 (file)
@@ -14,7 +14,9 @@ import jalview.gui.JvOptionPane;
 import jalview.gui.Preferences;
 import jalview.io.HMMFile;
 import jalview.io.StockholmFile;
+import jalview.util.FileUtils;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.ws.params.ArgumentI;
 
 import java.io.BufferedReader;
@@ -22,6 +24,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
 
@@ -63,7 +66,8 @@ public abstract class HmmerCommand implements Runnable
    */
   public static boolean isHmmerAvailable()
   {
-    File exec = getExecutable(HMMBUILD, Cache.getProperty(Preferences.HMMER_PATH));
+    File exec = FileUtils.getExecutable(HMMBUILD,
+            Cache.getProperty(Preferences.HMMER_PATH));
     return exec != null;
   }
 
@@ -100,9 +104,12 @@ public abstract class HmmerCommand implements Runnable
   public boolean runCommand(List<String> command)
           throws IOException
   {
+    List<String> commands = Platform.isWindows() ? wrapWithCygwin(command)
+            : command;
+
     try
     {
-      ProcessBuilder pb = new ProcessBuilder(command);
+      ProcessBuilder pb = new ProcessBuilder(commands);
       pb.redirectErrorStream(true); // merge syserr to sysout
       final Process p = pb.start();
       new Thread(new Runnable()
@@ -128,7 +135,13 @@ public abstract class HmmerCommand implements Runnable
       }).start();
 
       p.waitFor();
-      return p.exitValue() == 0; // 0 is success, by convention
+      int exitValue = p.exitValue();
+      if (exitValue != 0)
+      {
+        Cache.log.error("Command failed, return code = " + exitValue);
+        Cache.log.error("Command/args were: " + commands.toString());
+      }
+      return exitValue == 0; // 0 is success, by convention
     } catch (Exception e)
     {
       e.printStackTrace();
@@ -137,6 +150,40 @@ public abstract class HmmerCommand implements Runnable
   }
 
   /**
+   * Converts the given command to a Cygwin "run" command wrapper
+   * 
+   * @param command
+   * @return
+   */
+  protected List<String> wrapWithCygwin(List<String> command)
+  {
+    File runCygwin = FileUtils.getExecutable("run",
+            Cache.getProperty(Preferences.CYGWIN_PATH));
+    if (runCygwin == null)
+    {
+      Cache.log.error("Cygwin shell not found");
+      return command;
+    }
+
+    List<String> wrapped = new ArrayList<>();
+    wrapped.add(runCygwin.getAbsolutePath());
+    if (!command.isEmpty())
+    {
+      wrapped.add(command.get(0));
+      // wrapped.add("--quote");
+      StringBuilder args = new StringBuilder();
+      for (String arg : command.subList(1, command.size()))
+      {
+        args.append(" ").append(arg);
+      }
+      wrapped.add(args.toString());
+    }
+    // TODO this doesn't yet pass parameters successfully
+
+    return wrapped;
+  }
+
+  /**
    * Exports an alignment, and reference (RF) annotation if present, to the
    * specified file, in Stockholm format
    * 
@@ -204,7 +251,7 @@ public abstract class HmmerCommand implements Runnable
   protected String getCommandPath(String cmd)
   {
     String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH);
-    File file = getExecutable(cmd, binariesFolder);
+    File file = FileUtils.getExecutable(cmd, binariesFolder);
     if (file == null && af != null)
     {
         JvOptionPane.showInternalMessageDialog(af,
@@ -215,51 +262,6 @@ public abstract class HmmerCommand implements Runnable
   }
 
   /**
-   * Answers the executable file for the given hmmer command, or null if not
-   * found or not executable. The path to the executable is the command name
-   * prefixed by the hmmer binaries folder path, optionally with .exe appended.
-   * 
-   * @param cmd
-   *          hmmer command short name, for example hmmbuild
-   * @param binaryPath
-   *          parent folder containing hmmer executables
-   * @return
-   */
-  public static File getExecutable(String cmd, String binaryPath)
-  {
-    File file = new File(binaryPath, cmd);
-    if (!file.canExecute())
-    {
-      file = new File(binaryPath, cmd + ".exe");
-      {
-        if (!file.canExecute())
-        {
-          file = null;
-        }
-      }
-    }
-    return file;
-  }
-
-  /**
-   * A convenience method to create a temporary file that is deleted on exit of
-   * the JVM
-   * 
-   * @param prefix
-   * @param suffix
-   * @return
-   * @throws IOException
-   */
-  protected File createTempFile(String prefix, String suffix)
-          throws IOException
-  {
-    File f = File.createTempFile(prefix, suffix);
-    f.deleteOnExit();
-    return f;
-
-  }
-
-  /**
    * Exports an HMM to the specified file
    * 
    * @param hmm