# Helper functions for main conf.py Sphinx build configuration import datetime import re import subprocess def get_current_branch(): """Return the current branch we are on or the branch that the detached head is pointed to""" current_branch = subprocess.check_output( ['git', 'rev-parse', '--abbrev-ref', "HEAD"] ).decode("utf-8").strip() if current_branch == 'HEAD': # This means we are operating in a detached head state, will need to # parse out the branch that the commit is from. # Decode "bytes" type to UTF-8 sting to avoid Python 3 error: # "TypeError: a bytes-like object is required, not 'str'"" # https://docs.python.org/3/library/stdtypes.html#bytes.decode branches = subprocess.check_output(['git', 'branch']).decode('utf-8').split('\n') for branch in branches: # Git marks the current branch, or in this case the branch # we are currently detached from with an asterisk if '*' in branch: # Split on the remote/branch separator, grab the # last entry in the list and then strip off the trailing # parentheis detached_from_branch = branch.split('/')[-1].replace(')', '') return detached_from_branch else: # The assumption is that we are on a branch at this point. Return that. return current_branch def get_current_stable_version(): """Return the current X.Y stable version number from the latest git tag""" def get_latest_tag(): """"Helper function: Return the latest git tag""" git_tag_output = subprocess.check_output( ['git', 'tag', '--list', "v*"] ).decode("utf-8").strip() git_tag_list = re.sub('[A-Za-z]', '', git_tag_output).split('\n') git_tag_list.sort(key=lambda s: [int(u) for u in s.split('.')]) # The latest tag is the last in the list git_tag_latest = git_tag_list[-1] return git_tag_latest latest_tag = get_latest_tag() # Return 'X.Y' from 'X.Y.Z' return latest_tag[:-2] def get_next_stable_version(): """Return the next stable version""" current_version = get_current_stable_version() # Break apart 'x.y' value, increment y and then concatenate into 'x.y' again next_version = "{}.{}".format( int(current_version[:1]), int(current_version[-2:]) + 1 ) return next_version def get_current_commit_hash(): """Return commit hash string""" commit_hash = subprocess.check_output(['git', 'log', '--pretty=format:%h', 'HEAD', '-n1']).decode("utf-8") return commit_hash def get_release_string(release_type, release_string_detail, version): """Return a release string representing the type of build. Verbose for dev builds and with sparse version info for release builds""" if release_type == "dev": # Used in dev builds DATE = datetime.date.today() TODAY = DATE.strftime('%Y%m%d') # The detailed release string is too long for the rsyslog.com 'better' # theme and perhaps too long for other themes as well, so we set the # level to 'simple' by default (to be explicit) and # allow overriding by command-line if desired. if release_string_detail == "simple": # 'rsyslog' prefix is already set via 'project' variable in conf.py # HASH # 'docs' string suffix is already ... release_string = "{}".format( get_current_commit_hash() ) elif release_string_detail == "detailed": # The verbose variation of the release string. This was previously # the default when using the 'classic' theme, but proves to be # too long when viewed using alternate themes. If requested # via command-line override this format is used. release_string = "{}-{}-{}-{}".format( get_next_stable_version(), get_current_branch(), TODAY, get_current_commit_hash() ) else: # This means that someone set a value that we do not # have a format defined for. Return an error string instead # to help make it clear what happened. release_string = "invalid value for release_string_detail" else: release_string = "{}".format(version) return release_string