Zygmunt here's a patch to support a "managed" version for your versiontools. I fear you are going to want it more integrated into your current classes, but as I looked at it - it seemed it would required me making more changes to the classes than I felt comfortable with (or have time to make). Would you merge this, or should we just try and do something like this some other day when we have more time to do it better?

-andy
>From 52aca22aab0081422b8b96325cdbaf5b49d730b9 Mon Sep 17 00:00:00 2001
From: Andy Doan <[email protected]>
Date: Wed, 30 Jan 2013 15:46:57 -0600
Subject: [PATCH] add support for "managed" versions

This code allows the __version__ value for a module to be automatically
determined by either a git/bzr repo or using egginfo
---
 versiontools/__init__.py |    4 +-
 versiontools/managed.py  |  107 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 versiontools/managed.py

diff --git a/versiontools/__init__.py b/versiontools/__init__.py
index 94bc4df..c4d52df 100644
--- a/versiontools/__init__.py
+++ b/versiontools/__init__.py
@@ -25,7 +25,9 @@ Define *single* and *useful* ``__version__`` of a project.
 .. note: Since version 1.1 we should conform to PEP 386
 """
 
-__version__ = (1, 10, 0, "dev", 0)
+import managed
+
+__version__ = managed.version(__file__, 'release-*')
 __all__ = ("VersionBase", "Version", "format_version", "handle_version")
 
 
diff --git a/versiontools/managed.py b/versiontools/managed.py
new file mode 100644
index 0000000..d0cf49a
--- /dev/null
+++ b/versiontools/managed.py
@@ -0,0 +1,107 @@
+# Copyright (C) 2010-2013 Linaro Limited
+#
+# Author: Andy Doan ([email protected])
+#
+# This file is part of versiontools.
+#
+# versiontools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# as published by the Free Software Foundation
+#
+# versiontools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with versiontools.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+import subprocess
+
+
+def _rev_parts(revstr):
+    """
+    converts something like "0.15" or "0.15.2" in a tuple of (maj, min, fix)
+    """
+    major = minor = fix = 0
+    revs = re.findall('\d+', revstr)
+    if len(revs) == 2:
+        major, minor = revs
+    else:
+        major, minor, fix = revs
+
+    return (int(major), int(minor), int(fix))
+
+def _bzr_version(dirname, tag_pattern):
+    output = subprocess.check_output(
+        ['/bin/sh', '-c', 'bzr tags -d %s | grep %s' % (dirname, tag_pattern)])
+    output = output.strip()
+    idx = output.rfind('\n') + 1
+    output = output[idx:]
+
+    # we now have string like: release-0.28         509
+    tag, revno = output.split()
+    major, minor, fix = _rev_parts(tag)
+
+    currev = subprocess.check_output(['bzr', 'revno'], cwd=dirname).strip()
+    newrevs = 0
+    devstr = 'final'
+
+    if currev != revno:
+        devstr = 'dev'
+        newrevs = int(currev) - int(revno)
+
+    return (major, minor, fix, devstr, newrevs)
+
+
+def _git_version(dirname, tag_pattern):
+    output = subprocess.check_output(
+        ['git', '--git-dir', dirname, 'describe', '--tags', '--match', tag_pattern])
+    output = output.strip()
+    # we now have something like:
+    #  release-0.28-4-g22d368f
+    #  release-0.28.1
+    # so strip off the release part and analyze
+    parts = output.split('-')[1:]
+    major, minor, fix = _rev_parts(parts[0])
+
+    devstr = 'final'
+    newrevs = 0
+
+    if len(parts) != 1:
+        devstr = 'dev'
+        newrevs = int(parts[1])
+
+    return (major, minor, fix, devstr, newrevs)
+
+def _pkg_version(dirname):
+    pkginfo = os.path.join(dirname, 'EGG-INFO/PKG-INFO')
+    with open(pkginfo, 'r') as f:
+        for line in f.readlines():
+            if line.startswith('Version:'):
+                major, minor, fix = _rev_parts(line.split()[1])
+                return (major, minor, fix, 'final', 0)
+
+    return (0, 0, 0, '?', 0)
+
+def version(version_file, tag_pattern='release-*'):
+    """
+    Tries to determine if this component is part of bzr, git, or an egg. Based on
+    that it will return the version it calculates.
+
+    See versiontools.__version__ for example usage
+    """
+    basedir = os.path.dirname(version_file)
+    bzrdir = os.path.join(basedir, '..', '.bzr')
+    gitdir = os.path.join(basedir, '..', '.git')
+    eggdir = os.path.join(basedir, '..')
+
+    if os.path.exists(bzrdir):
+        return _bzr_version(bzrdir, tag_pattern)
+    elif os.path.exists(gitdir):
+        return _git_version(gitdir, tag_pattern)
+    else:
+        return _pkg_version(eggdir)
+
-- 
1.7.9.5

_______________________________________________
linaro-validation mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/linaro-validation

Reply via email to