def _parse_version_str()

in automation/tinc/main/tinctest/case.py [0:0]


    def _parse_version_str(self, filler):
        """
        Possible regex:
        4.2.x, 4.2.x.x, 4.2, 4.x, x, 4.2.1.3, 4.2.1.3A, 4.2.1.3B, etc
        It is the user's responsibility to pass a string like this to
        __TINCProductVersion__.
        """
        # filler should just be 'x' or 'digits'
        filler_pattern = r"""^(x|\d+)$"""
        if not re.match(filler_pattern, filler):
            raise TINCInvalidProductVersionException("Invalid filler specified. Should be 'x' or 'digits'")
        # '' or 'x' or None means a complete wild card match. 

        if not self.version_str or self.version_str == 'x' or self.version_str == 'X':
            self.version.extend(['x'] * 4)
            return

        if self.version_str.lower() == 'main':
            self.version.extend(self._main_version.split('.'))
            return

        _version_str_pattern = r"""^(?P<majors>((x|\d+)\.){1,3}) # Matches upto first three parts of a four part version x. , x.x. , x.x.x.
                                   (?P<minor>x|\d+) # Matches the final part of a four part version
                                   (?P<hotfix>([a-z]+\d*)*)$ # Matches the hotfix part of the version string"""

        matches = re.match(_version_str_pattern, self.version_str, flags = re.I | re.X)
        
        if not matches:
            raise TINCInvalidProductVersionException("Given version string %s is invalid." %self.version_str)

        majors = matches.group('majors')
        minor = matches.group('minor')
        hotfix = matches.group('hotfix')
       
        #majors now have to be of the form x. , x.x. or x.x.x.
        #filter it to remove the last part which will be None
        major_parts = [x.strip() for x in filter(None, majors.split('.'))]

        if len(major_parts) > 3 or len(major_parts) < 1:
            raise TINCInvalidProductVersionException("Given version string %s is invalid." %self.version_str)

        # minor should not be none
        if not minor:
            raise TINCInvalidProductVersionException("Given version string %s is invalid." %self.version_str)

        self.version.extend([x.lower() for x in major_parts])
        self.version.append(minor.lower())

        #hotfix should be given only if the whole version is given
        # For eg: 4.2MS1 will be invalid, 4.2.3.5MS1 , 4.2.2.4MS1 is valid,
        # 4.2.xMS1 will also be invalid, 4.2.x.xMS1 will also be invalid
        if (len(self.version) < 4 and hotfix) or ('x' in self.version and hotfix):
            raise TINCInvalidProductVersionException("Given version string %s is invalid." %self.version_str + \
                                                     "Hotfix can be provided only with four part versions.")

        if hotfix:
            self.hotfix = hotfix.strip()
        
        # If version does not have four parts , fill the list with 'filler' to make it a four part version
        if len(self.version) < 4:
            self.version.extend([filler.lower()] * (4 - len(self.version)))

        # Strip all version components
        self.version = [x.strip() for x in self.version]