From dab1d3984d31ff1c3d3f4d4e1b4105481def7e82 Mon Sep 17 00:00:00 2001
From: Martin Craig <martin.craig@eng.ox.ac.uk>
Date: Tue, 25 Feb 2020 14:26:20 +0000
Subject: [PATCH] Moved fsl command code out of main run function for clarity

---
 fsl/utils/run.py | 55 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/fsl/utils/run.py b/fsl/utils/run.py
index 6d4b33ee3..abba42f0e 100644
--- a/fsl/utils/run.py
+++ b/fsl/utils/run.py
@@ -362,24 +362,9 @@ def runfsl(*args, **kwargs):
     for prefix in prefixes:
         cmdpath = op.join(prefix, args[0])
         if fslplatform.fslwsl:
-            # We want to run the command from FSL installed in the Windows Subsystem for Linux
-            # First we check it exists in WSL (translating Windows path separators to Unix)
-            # Then we convert any Windows paths in the arguments (e.g. temp files) to the
-            # corresponding WSL Unix paths (C:/ -> /mnt/c)
-            # Then we prepend important environment variables - note that it seems we cannot
-            # use WSLENV for this due to its insistance on path mapping.
-            # Finally we append the command and its arguments
-            cmdpath = cmdpath.replace("\\", "/")
-            retcode = sp.call(["wsl", "test", "-x", cmdpath])
-            if retcode == 0:
-                args[0] = cmdpath
-                args = [wslpath(arg) for arg in args]
-                args = [
-                    "wsl",
-                    "PATH=$PATH:%s/bin" % fslplatform.fsldir,
-                    "FSLDIR=%s" % fslplatform.fsldir,
-                    "FSLOUTPUTTYPE=%s" % os.environ.get("FSLOUTPUTTYPE", "NIFTI_GZ")
-                ] + args
+            wslargs = wslcmd(cmdpath, *args)
+            if wslargs is not None:
+                args = wslargs
                 break
         elif op.isfile(cmdpath):
             args[0] = cmdpath
@@ -393,6 +378,40 @@ def runfsl(*args, **kwargs):
 
     return run(*args, **kwargs)
 
+def wslcmd(cmdpath, *args):
+    """
+    Convert a command + arguments into an equivalent set of arguments that will run the command
+    under Windows Subsystem for Linux
+    
+    :param cmdpath: Fully qualified path to the command. This is essentially a WSL path not a Windows
+                    one since FSLDIR is specified as a WSL path, however it may have backslashes
+                    as path separators due to previous use of ``os.path.join``
+    :param args: Sequence of command arguments (the first of which is the unqualified command name)
+    
+    :return: If ``cmdpath`` exists and is executable in WSL, return a sequence of command arguments
+             which when executed will run the command in WSL. Windows paths in the argument list will
+             be converted to WSL paths. If ``cmdpath`` was not executable in WSL, returns None
+    """
+    # Check if command exists in WSL (translating Windows path separators to Unix as os.path.join 
+    # may have inserted some backslashes)
+    cmdpath = cmdpath.replace("\\", "/")
+    retcode = sp.call(["wsl", "test", "-x", cmdpath])
+    if retcode == 0:
+        # Form a new argument list and convert any Windows paths in it into WSL paths
+        wslargs = [wslpath(arg) for arg in args]
+        wslargs[0] = cmdpath
+        # Prepend important environment variables - note that it seems we cannot
+        # use WSLENV for this due to its insistance on path mapping.
+        return [
+            "wsl",
+            "PATH=$PATH:%s/bin" % fslplatform.fsldir,
+            "FSLDIR=%s" % fslplatform.fsldir,
+            "FSLOUTPUTTYPE=%s" % os.environ.get("FSLOUTPUTTYPE", "NIFTI_GZ")
+        ] + wslargs
+    else:
+        # Command was not found in WSL with this path
+        return None
+
 def wslpath(patharg):
     """ 
     Convert a command line argument containing a Windows path to the equivalent WSL path (e.g. ``c:\\Users`` -> ``/mnt/c/Users``) 
-- 
GitLab