diff --git a/dulwich/contrib/latest_git_tags.py b/dulwich/contrib/latest_git_tags.py new file mode 100644 index 00000000..b014e014 --- /dev/null +++ b/dulwich/contrib/latest_git_tags.py @@ -0,0 +1,59 @@ +""" +Alternate to `Versioneer `_ using +`Dulwich `_ to sort tags by time from +newest to oldest. + +Copy this file (``latest_git_tags.py``) into the package's top folder, import it +into ``__init__.py`` and then set :: + + from latest_git_tags import get_recent_tags + + __version__ = get_recent_tags()[0][0][1:] + # other dunder classes like __author__, etc. + +This example assumes the tags have a leading "v" like "v0.3", and that the +``.git`` folder is in the project folder that containts the package folder. +""" + +from dulwich.repo import Repo +import time +import datetime +import os + +# CONSTANTS +DIRNAME = os.path.abspath(os.path.dirname(__file__)) +PROJDIR = os.path.dirname(DIRNAME) + +def get_recent_tags(projdir=PROJDIR): + """ + Get list of recent tags in order from newest to oldest and their datetimes. + + :param projdir: path to ``.git`` + :returns: list of (tag, [datetime, commit, author]) sorted from new to old + """ + project = Repo(projdir) # dulwich repository object + refs = project.get_refs() # dictionary of refs and their SHA-1 values + tags = {} # empty dictionary to hold tags, commits and datetimes + # iterate over refs in repository + for key, value in refs.iteritems(): + obj = project.get_object(value) # dulwich object from SHA-1 + # check if object is tag + if obj.type_name != 'tag': + # skip ref if not a tag + continue + # strip the leading text from "refs/tag/" to get "tag name" + _, tag = key.rsplit('/', 1) + # check if tag object is commit, altho it should always be true + if obj.object[0].type_name == 'commit': + commit = project.get_object(obj.object[1]) # commit object + # get tag commit datetime, but dulwich returns seconds since + # beginning of epoch, so use Python time module to convert it to + # timetuple then convert to datetime + tags[tag] = [ + datetime.datetime(*time.gmtime(commit.commit_time)[:6]), + commit.id, + commit.author + ] + + # return list of tags sorted by their datetimes from newest to oldest + return sorted(tags.iteritems(), key=lambda tag: tag[1][0], reverse=True)