from __future__ import print_function """This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license. """ """ Version Lib Copyright (C) 2019 Maxim Tkachenko This library automatically generates version of package based on git. If 'git desc' is successful it will write version to __version__.py:git_version. If 'git desc' is fail it will read __version__.py:git_version. ATTENTION: do not include version_.py to git! It will affect git commit always! """ import json import os import sys from subprocess import STDOUT, CalledProcessError from subprocess import check_output as run VERSION_FILE = 'version_.py' LS_VERSION_FILE = 'ls-version_.py' VERSION_OVERRIDE = os.getenv('VERSION_OVERRIDE', '') BRANCH_OVERRIDE = os.getenv('BRANCH_OVERRIDE', '') def _write_py(info): # go to current dir to package __init__.py cwd = os.getcwd() d = os.path.dirname(__file__) d = d if d else '.' os.chdir(d) info_str = json.dumps(info) # write txt with open(VERSION_FILE, 'w') as f: os.chdir(cwd) # back current dir f.write( 'info = %s\n' % info_str + '\n# This file is automatically generated by version.py' '\n# Do not include it to git!\n' ) def _read_py(ls=False): # go to current dir to package __init__.py cwd = os.getcwd() d = os.path.dirname(__file__) d = d if d else '.' sys.path.append(d) os.chdir(d) # read version def import_version_module(file_path): try: return __import__(os.path.splitext(file_path)[0]) except ImportError: return None try: version_module = import_version_module(LS_VERSION_FILE if ls else VERSION_FILE) if not version_module and ls: version_module = import_version_module(VERSION_FILE) if version_module: return version_module.info else: return {} finally: os.chdir(cwd) # back to current dir # get commit info: message, date, hash, branch def get_git_commit_info(skip_os=True, ls=False): cwd = os.getcwd() d = os.path.dirname(__file__) d = d if d else '.' os.chdir(d) try: # take version from git try: desc = run('git describe --long --tags --always --dirty', stderr=STDOUT, shell=True).decode('utf-8') info = { 'message': run('git show -s --format=%s', stderr=STDOUT, shell=True).strip().decode('utf8'), 'commit': run('git show -s --format=%H', stderr=STDOUT, shell=True).strip().decode('utf8'), 'date': run('git log -1 --format="%cd" --date="format:%Y/%m/%d %H:%M:%S"', stderr=STDOUT, shell=True) .strip() .decode('utf8'), 'branch': BRANCH_OVERRIDE if BRANCH_OVERRIDE else run( "git branch --sort=committerdate -r --contains | grep -m 1 -v HEAD | cut -d'/' -f2-", stderr=STDOUT, shell=True, ) .strip() .decode('utf8'), } except CalledProcessError: os.chdir(cwd) return _read_py(ls=True) # create package version version = desc.lstrip('v').rstrip().replace('-', '+', 1).replace('-', '.') # take OS name if not skip_os: keys = ('ID=', 'VERSION_ID=', 'RELEASE=') with open('/etc/os-release') as f: os_version = ''.join( str(s).split('=', 1)[1].rstrip().strip('"').replace('.', '') for s in f if str(s).startswith(keys) ) version += '.' + os_version info['version'] = VERSION_OVERRIDE if VERSION_OVERRIDE else version _write_py(info) return info except Exception as e: raise e finally: os.chdir(cwd) # back current dir def get_git_version(skip_os=True): info = get_git_commit_info(skip_os) return info.get('version', '') # get only tag from git def get_short_version(): version = get_git_version() return version.split('+')[0] if __name__ == '__main__': # init version_.py file get_git_version()