def detect_version_str(self): """ Detect which version by scanning the README for the latest release """ cmd_path = run_matlab_cmd("which('{}')".format(self.test_func)) pkg_root = op.join(op.dirname(cmd_path), '..') readmes = [f for f in os.listdir(pkg_root) if 'readme' in f.lower()] if not readmes: raise ArcanaVersionNotDetectableError( "Did not find a README in STI package root ({})".format( pkg_root)) elif len(readmes) > 1: raise ArcanaVersionNotDetectableError( "Found multiple READMEs in STI package root ({})".format( pkg_root)) readme_path = op.join(pkg_root, readmes[0]) with open(readme_path, 'rb') as f: contents = f.read() # Cut out citations text as there can be non-decodable characters in # there contents = contents.split(b'TERMS OF USE')[0] if PY3: contents = contents.decode('utf-8') # Get dummy version so we can use its 'regex' property dummy_version_obj = self.version_cls(self, 1) versions = dummy_version_obj.regex.findall(contents) latest_version = sorted(versions)[-1] return latest_version
def parse(cls, version_str): regex = r'R?(\d+)(a|b)' match = re.search(regex, version_str, re.IGNORECASE) if match is None: raise ArcanaVersionNotDetectableError( "Could not parse Matlab version string {} as {}. Regex ({})" " did not match any sub-string".format(version_str, cls.__name__, regex)) return (int(match.group(1)), match.group(2).lower()), None, None, None
def parse_help_text(self, help_text): """ Detect which SPM version we are using from the copyright year """ match = re.search( r'Copyright \(C\) [\d\-\, ]*(?<!\d)(\d+) Wellcome Trust Centre', help_text) if match is None: raise ArcanaVersionNotDetectableError( "Could not parse year of copyright from spm_authors in order " "to determine the version of {}".format(self)) copyright_year = match.group(1) if copyright_year == '2010': version = 8 elif copyright_year == '2012': version = 12 else: raise ArcanaVersionNotDetectableError( "Do not know the version of SPM corresponding to the year of " "copyright of {}".format(copyright_year)) return version
def detect_version_str(self): """ Try to detect version of package from command help text. Bit of a long shot as they are typically included """ try: help_text = run_matlab_cmd("help('{}')".format(self.test_func)) except IOError as e: if str(e).startswith('No command "matlab"'): raise ArcanaVersionNotDetectableError( "Could not detect version of MatlabRequirement '{}' as " "matlab was not found in the environment (or was not " "loaded)".format(self.name)) if not help_text: raise ArcanaRequirementNotFoundError( "Did not find test function '{}' for {}".format( self.test_func, self)) return self.parse_help_text(help_text)
def detect_version_str(self): """ C3D doesn't print out the version so we need to interrogate the install directory to extract it """ c3d_bin_path = op.dirname(self.locate_command()) if platform.system() == 'Linux': libname = os.listdir(op.join(c3d_bin_path, '..', 'lib'))[0] version_str = libname.split('-')[-1] elif platform.system() == 'Darwin': info_list_path = op.join(c3d_bin_path, '..', 'Info.plist') info_etree = xml.etree.ElementTree.parse(info_list_path) elem_bodies = [e.text for e in info_etree.iter()] version_str = elem_bodies[ elem_bodies.index('CFBundleShortVersionString') + 1] else: raise ArcanaVersionNotDetectableError( "Can't detect c3d version on Windows") return version_str
def detect_version_str(self): test_cmd_loc = self.locate_command() if self.version_switch is None: raise ArcanaVersionNotDetectableError( "Could not detect version of {} as version information is not " "provided by underlying command".format(self)) try: process = sp.Popen((test_cmd_loc, self._version_switch), stdout=sp.PIPE, stderr=sp.PIPE) version_str, stderr = process.communicate() if not version_str: version_str = stderr except sp.CalledProcessError as e: raise ArcanaUsageError( "Problem calling test command ({}) with version switch '{}' " "for {}:\n{}".format(test_cmd_loc, self._version_switch, self, e)) if PY3: version_str = version_str.decode('utf-8') return version_str
def detect_version_str(self): raise ArcanaVersionNotDetectableError( "Can't automatically detect version of STIR as it isn't saved in " "the build process")
def parse(self, version): """ Splits a typical version string (e.g. <MAJOR>.<MINOR>.<MICRO>) into a tuple that can be sorted properly. Ignores all leading and trailing characters by using a regex search (instead of match) so as to pick the version string out of a block of text. Parameters ---------- version : str | int | float | tuple(int) The string containing the version numbers, or alternatively an integer, float (number after decimal is interpreted as minor ver), or tuple|list containing the version sequence. Returns ------- sequence : tuple(int | str) A tuple containing the main sequence of the version, e.g. <MAJOR>.<MINOR>.<MICRO> prerelease : 2-tuple(str, int) | None A 2-tuple containing the type of prerelease ('a' - alpha, 'b' - beta, or 'rc' - release-canditate) and the number of the prerelease post : int |None The number of the post version dev : int | None The number of the development version """ # Check to see if version is not a string but rather another type # that can be interpreted as a version if isinstance(version, int): return (version, ), None, None, None elif isinstance(version, (tuple, list)): return tuple(int(i) for i in version), None, None, None elif isinstance(version, float): major = math.floor(version) minor = version - major return (major, minor), None, None, None match = self.regex.search(version) if match is None: raise ArcanaVersionNotDetectableError( "Could not parse version string {} as {}. Regex ({}) did not " "match any sub-string".format(version, type(self).__name__, self.regex.pattern)) sequence = [] prerelease = None dev = None post = None for part in match.group(1).split(self.delimeter): if part.startswith('dev'): dev = int(part[len('dev'):]) elif part.startswith('post'): post = int(part[len('post'):]) else: # Split on non-numeric parts of the version string so that we # can detect prerelease sub_parts = re.split(r'([^\d]+)', part) if sub_parts[0]: try: seq_part = int(sub_parts[0]) except ValueError: seq_part = sub_parts[0] sequence.append(seq_part) if len(sub_parts) > 1: stage = sub_parts[1] try: pr_ver = int(sub_parts[2]) except ValueError: raise ArcanaVersionNotDetectableError( "Could not parse version string {} as {}. " "Did not recognise pre-release version {}".format( version, type(self).__name__, sub_parts[2])) stage = stage.strip('-_').lower() if not stage: # No prerelease info, assume a dev version assert dev is None dev = pr_ver continue if 'alpha'.startswith(stage): stage = 'a' elif 'beta'.startswith(stage): stage = 'b' elif stage == 'rc' or stage == 'release-canditate': stage = 'rc' else: raise ArcanaVersionNotDetectableError( "Could not parse version string {} as {}. " "Did not recognise pre-release stage {}".format( version, type(self).__name__, stage)) prerelease = (stage, pr_ver) return tuple(sequence), prerelease, post, dev