diff --git a/django/__init__.py b/django/__init__.py index 20ca23496c4..85cf02c9a4d 100644 --- a/django/__init__.py +++ b/django/__init__.py @@ -1,5 +1,11 @@ +import datetime +import os +import subprocess + + VERSION = (1, 5, 0, 'alpha', 0) + def get_version(version=None): """Derives a PEP386-compliant version number from VERSION.""" if version is None: @@ -17,14 +23,31 @@ def get_version(version=None): sub = '' if version[3] == 'alpha' and version[4] == 0: - # At the toplevel, this would cause an import loop. - from django.utils.version import get_svn_revision - svn_revision = get_svn_revision()[4:] - if svn_revision != 'unknown': - sub = '.dev%s' % svn_revision + git_changeset = get_git_changeset() + if git_changeset: + sub = '.dev%s' % git_changeset elif version[3] != 'final': mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'} sub = mapping[version[3]] + str(version[4]) return main + sub + + +def get_git_changeset(): + """Returns a numeric identifier of the latest git changeset. + + The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format. + This value isn't guaranteed to be unique but collisions are very unlikely, + so it's sufficient for generating the development version numbers. + """ + repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + git_show = subprocess.Popen('git show --pretty=format:%ct --quiet HEAD', + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=True, cwd=repo_dir, universal_newlines=True) + timestamp = git_show.communicate()[0].partition('\n')[0] + try: + timestamp = datetime.datetime.utcfromtimestamp(int(timestamp)) + except ValueError: + return None + return timestamp.strftime('%Y%m%d%H%M%S') diff --git a/django/utils/version.py b/django/utils/version.py deleted file mode 100644 index cb8623b1036..00000000000 --- a/django/utils/version.py +++ /dev/null @@ -1,41 +0,0 @@ -import django -import re - -def get_svn_revision(path=None): - """ - Returns the SVN revision in the form SVN-XXXX, - where XXXX is the revision number. - - Returns SVN-unknown if anything goes wrong, such as an unexpected - format of internal SVN files. - - If path is provided, it should be a directory whose SVN info you want to - inspect. If it's not provided, this will use the root django/ package - directory. - """ - rev = None - if path is None: - path = django.__path__[0] - entries_path = '%s/.svn/entries' % path - - try: - entries = open(entries_path, 'r').read() - except IOError: - pass - else: - # Versions >= 7 of the entries file are flat text. The first line is - # the version number. The next set of digits after 'dir' is the revision. - if re.match('(\d+)', entries): - rev_match = re.search('\d+\s+dir\s+(\d+)', entries) - if rev_match: - rev = rev_match.groups()[0] - # Older XML versions of the file specify revision as an attribute of - # the first entries node. - else: - from xml.dom import minidom - dom = minidom.parse(entries_path) - rev = dom.getElementsByTagName('entry')[0].getAttribute('revision') - - if rev: - return u'SVN-%s' % rev - return u'SVN-unknown' diff --git a/tests/regressiontests/version/tests.py b/tests/regressiontests/version/tests.py index 1a67483c1f0..9b849ee4ba2 100644 --- a/tests/regressiontests/version/tests.py +++ b/tests/regressiontests/version/tests.py @@ -8,7 +8,7 @@ class VersionTests(TestCase): def test_development(self): ver_tuple = (1, 4, 0, 'alpha', 0) # This will return a different result when it's run within or outside - # of a SVN checkout: 1.4.devNNNNN or 1.4. + # of a git clone: 1.4.devYYYYMMDDHHMMSS or 1.4. ver_string = get_version(ver_tuple) self.assertRegexpMatches(ver_string, r'1\.4(\.dev\d+)?')