Repository: nipy/nipype

Issue:
Make sure the new FreeSurfer dev version scheme plays nice



Discussion:

Resolving patch:
diff --git a/nipype/interfaces/freesurfer/base.py b/nipype/interfaces/freesurfer/base.py
--- a/nipype/interfaces/freesurfer/base.py
+++ b/nipype/interfaces/freesurfer/base.py
@@ -17,9 +17,9 @@
 from __future__ import print_function, division, unicode_literals, absolute_import
 from builtins import open, object, str
 
-
 import os
 
+from ... import LooseVersion
 from ...utils.filemanip import fname_presuffix
 from ..base import (CommandLine, Directory,
                     CommandLineInputSpec, isdefined,
@@ -27,6 +27,7 @@
 
 __docformat__ = 'restructuredtext'
 
+
 class Info(object):
     """ Freesurfer subject directory and version information.
 
@@ -65,6 +66,41 @@ def version():
         fid.close()
         return version
 
+    @classmethod
+    def looseversion(cls):
+        """ Return a comparable version object
+
+        If no version found, use LooseVersion('0.0.0')
+        """
+        ver = cls.version()
+        if ver is None:
+            return LooseVersion('0.0.0')
+
+        vinfo = ver.rstrip().split('-')
+        try:
+            int(vinfo[-1], 16)
+        except ValueError:
+            githash = ''
+        else:
+            githash = '.' + vinfo[-1]
+
+        # As of FreeSurfer v6.0.0, the final component is a githash
+        if githash:
+            if vinfo[3] == 'dev':
+                # This will need updating when v6.0.1 comes out
+                vstr = '6.0.0-dev' + githash
+            elif vinfo[5][0] == 'v':
+                vstr = vinfo[5][1:]
+            else:
+                raise RuntimeError('Unknown version string: ' + ver)
+        # Retain pre-6.0.0 heuristics
+        elif 'dev' in ver:
+            vstr = vinfo[-1] + '-dev'
+        else:
+            vstr = ver.rstrip().split('-v')[-1]
+
+        return LooseVersion(vstr)
+
     @classmethod
     def subjectsdir(cls):
         """Check the global SUBJECTS_DIR
@@ -154,12 +190,9 @@ def _gen_fname(self, basename, fname=None, cwd=None, suffix='_fs',
 
     @property
     def version(self):
-        ver = Info.version()
-        if ver:
-            if 'dev' in ver:
-                return ver.rstrip().split('-')[-1] + '.dev'
-            else:
-                return ver.rstrip().split('-v')[-1]
+        ver = Info.looseversion()
+        if ver > LooseVersion("0.0.0"):
+            return ver.vstring
 
 
 class FSSurfaceCommand(FSCommand):
diff --git a/nipype/interfaces/freesurfer/preprocess.py b/nipype/interfaces/freesurfer/preprocess.py
--- a/nipype/interfaces/freesurfer/preprocess.py
+++ b/nipype/interfaces/freesurfer/preprocess.py
@@ -36,13 +36,9 @@
 __docformat__ = 'restructuredtext'
 iflogger = logging.getLogger('interface')
 
-FSVersion = "0"
-_ver = Info.version()
-if _ver:
-    if 'dev' in _ver:
-        FSVersion = _ver.rstrip().split('-')[-1] + '.dev'
-    else:
-        FSVersion = _ver.rstrip().split('-v')[-1]
+# Keeping this to avoid breaking external programs that depend on it, but
+# this should not be used internally
+FSVersion = Info.looseversion()
 
 
 class ParseDICOMDirInputSpec(FSTraitedSpec):
@@ -724,7 +720,7 @@ class ReconAll(CommandLine):
                         'mri/brainmask.auto.mgz',
                         'mri/brainmask.mgz'], []),
         ]
-    if LooseVersion(FSVersion) < LooseVersion("6.0.0"):
+    if Info.looseversion() < LooseVersion("6.0.0"):
         _autorecon2_steps = [
             ('gcareg', ['mri/transforms/talairach.lta'], []),
             ('canorm', ['mri/norm.mgz'], []),
@@ -1072,7 +1068,7 @@ class BBRegister(FSCommand):
     """
 
     _cmd = 'bbregister'
-    if FSVersion and LooseVersion(FSVersion) < LooseVersion("6.0.0"):
+    if LooseVersion('0.0.0') < Info.looseversion() < LooseVersion("6.0.0"):
         input_spec = BBRegisterInputSpec
     else:
         input_spec = BBRegisterInputSpec6


Test patch:
diff --git a/nipype/interfaces/freesurfer/tests/test_preprocess.py b/nipype/interfaces/freesurfer/tests/test_preprocess.py
--- a/nipype/interfaces/freesurfer/tests/test_preprocess.py
+++ b/nipype/interfaces/freesurfer/tests/test_preprocess.py
@@ -7,7 +7,7 @@
 from nipype.testing.fixtures import create_files_in_directory
 
 from nipype.interfaces import freesurfer
-from nipype.interfaces.freesurfer.preprocess import FSVersion
+from nipype.interfaces.freesurfer import Info
 from nipype import LooseVersion
 
 
@@ -138,7 +138,7 @@ def test_bbregister(create_files_in_directory):
     bbr.inputs.contrast_type = 't2'
 
     # Check that 'init' is mandatory in FS < 6, but not in 6+
-    if LooseVersion(FSVersion) < LooseVersion("6.0.0"):
+    if Info.looseversion() < LooseVersion("6.0.0"):
         with pytest.raises(ValueError):
             bbr.cmdline
     else: