'Determines the semver version bump based on commit messages in \'git log\'.
Uses \'conventional-changelog\' format to search for features and breaking
changes.
Args:
curr_version [CommitTag]: Latest \'version-X.Y.Z\' tag/commit hash pair
calcluated by semver sort.
commit_hashes [String list]: List of ordered commit hashes.
commit_msgs [String list]: List of ordered, full commit messages.
Returns:
[VersionBump]: Next semantic version tag to be used, along with what type
of version bump it was.'

def bump_semver(self, curr_version, commit_hashes, commit_msgs):

    commits_iter = iter([CommitMessage(hash, msg) for (hash, msg) in zip(commit_hashes, commit_msgs)])
    commit = next(commits_iter, None)
    head_commit_hash = commit.hash
    feat_matcher = re.compile('feat\\(.*\\)*')
    bc_matcher = re.compile('BREAKING    CHANGE')
    feature = False
    breaking_change = False
    first_dash_idx = curr_version.tag.index('-')
    if (first_dash_idx == (-1)):
        raise GitTagMissingException("No    version    tags    of    the    form    'version-X.Y.Z'.")
    (major, minor, patch) = curr_version.tag[(first_dash_idx + 1):].split('.')
    while ((commit is not None) and (commit.hash != curr_version.hash)):
        msg_lines = commit.msg.split('\n')
        if any([bc_matcher.match(m.strip()) for m in msg_lines]):
            breaking_change = True
            break
        if any([feat_matcher.match(m.strip()) for m in msg_lines]):
            feature = True
        commit = next(commits_iter, None)
    if (breaking_change == True):
        return VersionBump((('version-' + str((int(major) + 1))) + '.0.0'), head_commit_hash, major=True)
    elif (feature == True):
        return VersionBump((((('version-' + major) + '.') + str((int(minor) + 1))) + '.0'), head_commit_hash, minor=True)
    else:
        return VersionBump(((((('version-' + major) + '.') + minor) + '.') + str((int(patch) + 1))), head_commit_hash, patch=True)
