| | |
| | import os |
| | import subprocess |
| | import warnings |
| |
|
| | from packaging.version import parse |
| |
|
| |
|
| | def digit_version(version_str: str, length: int = 4): |
| | """Convert a version string into a tuple of integers. |
| | |
| | This method is usually used for comparing two versions. For pre-release |
| | versions: alpha < beta < rc. |
| | |
| | Args: |
| | version_str (str): The version string. |
| | length (int): The maximum number of version levels. Defaults to 4. |
| | |
| | Returns: |
| | tuple[int]: The version info in digits (integers). |
| | """ |
| | assert 'parrots' not in version_str |
| | version = parse(version_str) |
| | assert version.release, f'failed to parse version {version_str}' |
| | release = list(version.release) |
| | release = release[:length] |
| | if len(release) < length: |
| | release = release + [0] * (length - len(release)) |
| | if version.is_prerelease: |
| | mapping = {'a': -3, 'b': -2, 'rc': -1} |
| | val = -4 |
| | |
| | if version.pre: |
| | if version.pre[0] not in mapping: |
| | warnings.warn(f'unknown prerelease version {version.pre[0]}, ' |
| | 'version checking may go wrong') |
| | else: |
| | val = mapping[version.pre[0]] |
| | release.extend([val, version.pre[-1]]) |
| | else: |
| | release.extend([val, 0]) |
| |
|
| | elif version.is_postrelease: |
| | release.extend([1, version.post]) |
| | else: |
| | release.extend([0, 0]) |
| | return tuple(release) |
| |
|
| |
|
| | def _minimal_ext_cmd(cmd): |
| | |
| | env = {} |
| | for k in ['SYSTEMROOT', 'PATH', 'HOME']: |
| | v = os.environ.get(k) |
| | if v is not None: |
| | env[k] = v |
| | |
| | env['LANGUAGE'] = 'C' |
| | env['LANG'] = 'C' |
| | env['LC_ALL'] = 'C' |
| | out, err = subprocess.Popen( |
| | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
| | env=env).communicate() |
| | return out |
| |
|
| |
|
| | def get_git_hash(fallback='unknown', digits=None): |
| | """Get the git hash of the current repo. |
| | |
| | Args: |
| | fallback (str, optional): The fallback string when git hash is |
| | unavailable. Defaults to 'unknown'. |
| | digits (int, optional): kept digits of the hash. Defaults to None, |
| | meaning all digits are kept. |
| | |
| | Returns: |
| | str: Git commit hash. |
| | """ |
| |
|
| | if digits is not None and not isinstance(digits, int): |
| | raise TypeError('digits must be None or an integer') |
| |
|
| | try: |
| | out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD']) |
| | sha = out.strip().decode('ascii') |
| | if digits is not None: |
| | sha = sha[:digits] |
| | except OSError: |
| | sha = fallback |
| |
|
| | return sha |
| |
|