diff setup.py @ 69:cb1ed436642c

Always use version generated by `setup.py`. Better version generation.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 30 Aug 2014 08:35:26 -0700
parents e4a24512b814
children ecee3e8f35e5
line wrap: on
line diff
--- a/setup.py	Fri Aug 29 16:42:15 2014 -0700
+++ b/setup.py	Sat Aug 30 08:35:26 2014 -0700
@@ -6,7 +6,7 @@
 import sys
 import time
 import subprocess
-from setuptools import setup, find_packages
+from setuptools import setup, find_packages, Command
 from setuptools.command.test import test
 
 
@@ -34,49 +34,86 @@
         sys.exit(errno)
 
 
-# Figure out the version.
-# (this is loosely based on what Mercurial does)
-version = None
-try:
-    if os.path.isdir(os.path.join(os.path.dirname(__file__), '.hg')):
+class GenerateVersionCommand(Command):
+    description = 'generates a version file'
+    user_options = [
+            ('force=', 'f', 'force a specific version number')]
+
+    def initialize_options(self):
+        self.force = None
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        v = self.force or generate_version()
+        write_version(v)
+        print("Generated version %s" % v)
+        return 0
+
+
+def generate_version():
+    """ Generate a version file from the source control information.
+        (this is loosely based on what Mercurial does)"""
+    if not os.path.isdir(os.path.join(os.path.dirname(__file__), '.hg')):
+        raise Exception("Can't generate version number: this is not a "
+                        "Mercurial repository.")
+
+    try:
+        # Get the version we're currently on. Also see if we have local
+        # changes.
+        cmd = ['hg', 'id', '-i']
+        hgid, err = runcmd(cmd)
+        hgid = hgid.decode('utf8').strip()
+        has_local_changes = hgid.endswith('+')
+        hgid = hgid.rstrip('+')
+
+        # Get the tags on the current version.
         cmd = ['hg', 'log', '-r', '.', '--template', '{tags}\n']
         tags, err = runcmd(cmd)
         versions = [t for t in tags.decode('utf8').split() if t[0].isdigit()]
 
-        cmd = ['hg', 'id', '-i']
-        hgid, err = runcmd(cmd)
-        hgid = hgid.decode('utf8').strip()
-
         if versions:
-            # Use tag found at the current revision. Add dirty flag if any.
+            # Use the tag found at the current revision.
             version = versions[-1]
-            if hgid.endswith('+'):
-                version += '+'
         else:
-            # Use latest tag.
-            cmd = ['hg', 'parents', '--template', '{latesttag}+{latesttagdistance}-']
+            # Use the latest tag, but add info about how many revisions
+            # there have been since then.
+            cmd = ['hg', 'parents', '--template',
+                   '{latesttag}+{latesttagdistance}']
             version, err = runcmd(cmd)
-            version = version.decode('utf8') + hgid
+            tag, dist = version.decode('utf8').split('+')
+            if dist == '1':
+                # We're on the commit that created the tag in the first place.
+                # Let's just do as if we were on the tag.
+                version = tag
+            else:
+                version = '%s-%s.%s' % (tag, dist, hgid)
 
-        if version.endswith('+'):
-            version += time.strftime('%Y%m%d')
-except OSError:
-    # Mercurial isn't installed, or not in the PATH.
-    version = None
+        if has_local_changes:
+            version += time.strftime('+%Y%m%d')
+
+        return version
+    except OSError:
+        raise Exception("Can't generate version number: Mercurial isn't "
+                        "installed, or in the PATH.")
+    except Exception as ex:
+        raise Exception("Can't generate version number: %s" % ex)
 
 
-if version:
+def write_version(version):
+    if not version:
+        raise Exception("No version to write!")
+
     f = open("piecrust/__version__.py", "w")
     f.write('# this file is autogenerated by setup.py\n')
-    f.write('version = "%s"\n' % version)
+    f.write('APP_VERSION = "%s"\n' % version)
     f.close()
 
 
-try:
-    from piecrust import __version__
-    version = __version__.version
-except ImportError:
-    version = 'unknown'
+# Always generate an up to date version.
+version = generate_version()
+write_version(version)
 
 
 setup(name="piecrust",
@@ -119,7 +156,8 @@
             'pytest-mock==0.2.0'
             ],
         cmdclass={
-            'test': PyTest
+            'test': PyTest,
+            'version' : GenerateVersionCommand
             },
         classifiers=[
             'Development Status :: 3 - Alpha',