From f7bf82cb0256db68e04653055980940c8a2814af Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Sun, 27 May 2018 18:11:08 +0100
Subject: [PATCH] RF,ENH: Simplified management of $FSLDIR. Added $FSLDEVDIR.
 runfsl function gives $FSLDEVDIR precedence, and also allows a global
 override.

---
 fsl/utils/platform.py | 41 ++++++++++++++++++++++++++++++++++-------
 fsl/utils/run.py      | 16 ++++++++++++++--
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/fsl/utils/platform.py b/fsl/utils/platform.py
index 63c1d697c..cd2764ef9 100644
--- a/fsl/utils/platform.py
+++ b/fsl/utils/platform.py
@@ -88,7 +88,6 @@ def isWidgetAlive(widget):
 
     import wx
 
-
     if platform.wxFlavour == platform.WX_PHOENIX:
         excType = RuntimeError
     elif platform.wxFlavour == platform.WX_PYTHON:
@@ -116,6 +115,7 @@ class Platform(notifier.Notifier):
        os
        frozen
        fsldir
+       fsldevdir
        haveGui
        canHaveGui
        inSSHSession
@@ -146,8 +146,9 @@ class Platform(notifier.Notifier):
         self.__glRenderer   = None
         self.__glIsSoftware = None
         self.__fslVersion   = None
-        self.__fsldir       = None
-        self.fsldir         = os.environ.get('FSLDIR', None)
+
+        # initialise fsldir - see fsldir.setter
+        self.fsldir = self.fsldir
 
         # Determine if a display is available. We do
         # this once at init (instead of on-demand in
@@ -284,7 +285,13 @@ class Platform(notifier.Notifier):
                   any registered listeners are notified via the
                   :class:`.Notifier` interface.
         """
-        return self.__fsldir
+        return os.environ.get('FSLDIR', None)
+
+
+    @property
+    def fsldevdir(self):
+        """The FSL development directory location. """
+        return os.environ.get('FSLDEVDIR', None)
 
 
     @fsldir.setter
@@ -301,9 +308,9 @@ class Platform(notifier.Notifier):
         elif not op.exists(value): value = None
         elif not op.isdir(value):  value = None
 
-        self.__fsldir = value
-
-        if value is not None:
+        if value is None:
+            os.environ.pop('FSLDIR', None)
+        else:
             os.environ['FSLDIR'] = value
 
             # Set the FSL version field if we can
@@ -316,6 +323,26 @@ class Platform(notifier.Notifier):
         self.notify(value=value)
 
 
+    @fsldevdir.setter
+    def fsldevdir(self, value):
+        """Changes the value of the :attr:`fsldevdir` property, and notifies
+        any registered listeners.
+        """
+
+        if value is not None:
+            value = value.strip()
+
+        if   value is None:        pass
+        elif value == '':          value = None
+        elif not op.exists(value): value = None
+        elif not op.isdir(value):  value = None
+
+        if value is None:
+            os.environ.pop('FSLDEVDIR', None)
+        else:
+            os.environ['FSLDEVDIR'] = value
+
+
     @property
     def fslVersion(self):
         """Returns the FSL version as a string, e.g. ``'5.0.9'``. Returns
diff --git a/fsl/utils/run.py b/fsl/utils/run.py
index 7ea69adf2..ee4de6621 100644
--- a/fsl/utils/run.py
+++ b/fsl/utils/run.py
@@ -40,6 +40,10 @@ execute them.
 """
 
 
+FSL_PREFIX = None
+"""Global override for the FSL executable location used by :func:`runfsl`. """
+
+
 class FSLNotPresent(Exception):
     """Error raised by the :func:`runfsl` function when ``$FSLDIR`` cannot
     be found.
@@ -239,11 +243,19 @@ def runfsl(*args, **kwargs):
     ``$FSLDIR/bin/`` to the command before passing it to :func:`run`.
     """
 
-    if fslplatform.fsldir is None:
+    prefix = None
+
+    if FSL_PREFIX is not None:
+        prefix = FSL_PREFIX
+    elif fslplatform.fsldevdir is not None:
+        prefix = op.join(fslplatform.fsldevdir, 'bin')
+    elif fslplatform.fsldir is not None:
+        prefix = op.join(fslplatform.fsldir, 'bin')
+    else:
         raise FSLNotPresent('$FSLDIR is not set - FSL cannot be found!')
 
     args    = _prepareArgs(args)
-    args[0] = op.join(fslplatform.fsldir, 'bin', args[0])
+    args[0] = op.join(prefix, args[0])
 
     return run(*args, **kwargs)
 
-- 
GitLab