]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
update version-number handling, pull release tags from darcs history
authorBrian Warner <warner@lothar.com>
Fri, 4 May 2007 03:14:07 +0000 (20:14 -0700)
committerBrian Warner <warner@lothar.com>
Fri, 4 May 2007 03:14:07 +0000 (20:14 -0700)
.darcs-boringfile
GNUmakefile
misc/get-version.py [new file with mode: 0644]
misc/make-version.py [new file with mode: 0644]
setup.py
src/allmydata/__init__.py

index 39fd8d2ccda92bb7b051ab3916d7f94b26fdae20..bc032565f62ee50d676728a52b799be71e3d992a 100644 (file)
@@ -56,3 +56,6 @@
 ^src/Crypto/build($|/)
 ^_test_memory($|/)
 
+# version.py is generated at build time, and never checked in
+^src/allmydata/version\.py$
+
index b72bc4b0668f13ed744cb3c141b49ec0d0f220e4..9f15ce0bc598029f81af8d08a6842da75b849edb 100644 (file)
@@ -56,6 +56,7 @@ PP=PYTHONPATH=$(PYTHONPATH)
 
 .PHONY: build
 build: build-zfec build-Crypto build-foolscap
+       $(PYTHON) misc/make-version.py
        $(PP) $(PYTHON) ./setup.py $(EXTRA_SETUP_ARGS) install --prefix="." --root="$(INSTDIR)" --install-lib="lib" --install-scripts="bin"
 
 build-zfec:
@@ -178,13 +179,11 @@ clean: clean-zfec clean-Crypto clean-foolscap
 
 # DEBIAN PACKAGING
 
-VER=$(shell python -c "import os,re;print re.search(\"verstr=['\\\"](.*?)['\\\"]\", open(os.path.join('src', 'allmydata', '__init__.py')).readline()).group(1)")
-DEBSTRING=$(VER)-T`date +%s`
+VER=$(shell $(PYTHON) misc/get-version.py)
 DEBCOMMENTS="'make deb' build"
 
-show:
+show-version:
        @echo $(VER)
-       @echo $(DEBSTRING)
 
 .PHONY: setup-dapper setup-sid setup-edgy setup-feisty
 .PHONY: deb-dapper deb-sid deb-edgy deb-feisty
@@ -242,7 +241,7 @@ deb-feisty: setup-feisty
        echo "The newly built .deb packages are in the parent directory from here."
 
 increment-deb-version:
-       debchange --newversion $(DEBSTRING) $(DEBCOMMENTS)
+       debchange --newversion $(VER) $(DEBCOMMENTS)
 deb-dapper-head: setup-dapper increment-deb-version
        fakeroot debian/rules binary
 deb-sid-head: setup-sid increment-deb-version
diff --git a/misc/get-version.py b/misc/get-version.py
new file mode 100644 (file)
index 0000000..9281a9d
--- /dev/null
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+
+"""Determine the version number of the current tree.
+
+This should be run *after* make-version.py . It will emit a single line of
+text to stdout, either of the form '0.2.0' if this is a release tree (i.e. no
+patches have been added since the last release tag), or '0.2.0-34' (if 34
+patches have been added since the last release tag). If the tree does not
+have a well-formed version number, this will emit 'unknown'.
+
+The version string thus calculated should exactly match the version string
+determined by setup.py (when it creates eggs and source tarballs) and also
+the version available in the code image when you do:
+
+ from allmydata import __version__
+
+"""
+
+import os.path, re
+
+def get_version():
+    VERSIONFILE = "src/allmydata/version.py"
+    verstr = "unknown"
+    if os.path.exists(VERSIONFILE):
+        VSRE = re.compile("^verstr = ['\"]([^'\"]*)['\"]", re.M)
+        verstrline = open(VERSIONFILE, "rt").read()
+        mo = VSRE.search(verstrline)
+        if mo:
+            verstr = mo.group(1)
+        else:
+            raise RuntimeError("if version.py exists, it must be well-formed")
+
+    return verstr
+
+if __name__ == '__main__':
+    verstr = get_version()
+    print verstr
+
diff --git a/misc/make-version.py b/misc/make-version.py
new file mode 100644 (file)
index 0000000..466240e
--- /dev/null
@@ -0,0 +1,117 @@
+#! /usr/bin/python
+
+"""
+Create src/allmydata/version.py, based upon the latest darcs release tag.
+
+If your source tree is coming from darcs (i.e. there exists a _darcs
+directory), this tool will determine the most recent release tag, count the
+patches that have been applied since then, and compute a version number to be
+written into version.py . This version number will be available by doing:
+
+ from allmydata import __version__
+
+Source trees that do not come from darcs (release tarballs, nightly tarballs)
+do not have a _darcs directory. Instead, they should have a version.py that
+was generated before the tarball was produced. In this case, this script will
+quietly exit without modifying the existing version.py .
+
+FYI, src/allmydata/__init__.py will attempt to import version.py and use the
+version number therein. If it cannot, it will announce a version of
+'UNKNOWN'. This should only happen if someone manages to get hold of a
+non-_darcs/ source tree.
+
+'release tags' are tags in the tahoe source tree that match the following
+regexp:
+
+ ^allmydata-tahoe-\d+\.\d+\.\d+\w*$
+
+This excludes zfec tags (which start with 'zfec '). It also excludes
+'developer convenience tags', which look like 'hoping to fix bug -warner'.
+(the original goal was to use release tags that lacked the 'allmydata-tahoe-'
+prefix, but it turns out to be more efficient to keep it in, because I can't
+get 'darcs changes --from-tag=' to accept real regexps).
+
+"""
+
+import os, sys, commands, re
+import xml.dom.minidom
+
+def get_text(nodelist):
+    rc = ""
+    for node in nodelist:
+        if node.nodeType == node.TEXT_NODE:
+            rc = rc + node.data
+    return rc
+
+VERSION_BODY = '''
+from util.version import Version
+
+# This is the version of this tree, as created by misc/make-version.py from
+# the Darcs patch information: the main version number is taken from the most
+# recent release tag. If some patches have been added since the last release,
+# this will have a -NN "build number" suffix. Please see
+# allmydata.util.version for a description of what the different fields mean.
+
+verstr = "%s"
+__version__ = Version(verstr)
+'''
+
+def write_version_py(verstr):
+    f = open("src/allmydata/version.py", "wt")
+    f.write(VERSION_BODY % (verstr,))
+    f.close()
+
+def update():
+    if not os.path.exists("_darcs") or not os.path.isdir("_darcs"):
+        if os.path.exists("src/allmydata/version.py"):
+            print "no _darcs/ and version.py exists, leaving it alone"
+            return 0
+        print "no _darcs/ but no version.py either: how did you get this tree?"
+        return 0
+    cmd = "darcs changes --from-tag=^allmydata-tahoe --xml-output"
+    (rc, output) = commands.getstatusoutput(cmd)
+    if rc != 0:
+        print "unable to run 'darcs changes':"
+        print output
+        print "so I'm leaving version.py alone"
+        return 0
+
+    try:
+        doc = xml.dom.minidom.parseString(output)
+    except xml.parsers.expat.ExpatError:
+        print "unable to parse darcs XML output:"
+        print output
+        raise
+    changelog = doc.getElementsByTagName("changelog")[0]
+    patches = changelog.getElementsByTagName("patch")
+    count = 0
+    version_re = re.compile("^TAG allmydata-tahoe-(\d+\.\d+\.\d+\w*)$")
+    for patch in patches:
+        name = get_text(patch.getElementsByTagName("name")[0].childNodes)
+        m = version_re.match(name)
+        if m:
+            last_tag = m.group(1)
+            last_tag = last_tag.encode("ascii")
+            break
+        count += 1
+    else:
+        print "unable to find a matching tag"
+        print output
+        print "so I'm leaving version.py alone"
+        return 0
+
+    if count:
+        # this is an interim version
+        verstr = "%s-%d" % (last_tag, count)
+    else:
+        # this is a release
+        verstr = last_tag
+
+    write_version_py(verstr)
+    print "wrote '%s' into src/allmydata/version.py" % (verstr,)
+    return 0
+
+if __name__ == '__main__':
+    rc = update()
+    sys.exit(rc)
+
index f2ab1913f11da176e1f1659b5a27f7ffbc994e16..15eda54e5d3e6ac8447635373444c1aab518e858 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -23,6 +23,7 @@
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 # more details.
 
+import re, os.path
 from distutils.core import Extension, setup
 
 trove_classifiers=[
@@ -56,11 +57,18 @@ trove_classifiers=[
     "Topic :: System :: Archiving", 
     ]
 
-import re
-VSRE=re.compile("verstr=['\"]([^'\"]*)['\"]")
-verstrline=open("src/allmydata/__init__.py").readline()
-mo = VSRE.search(verstrline)
-verstr = mo.group(1)
+
+VERSIONFILE = "src/allmydata/version.py"
+verstr = "unknown"
+if os.path.exists(VERSIONFILE):
+    VSRE = re.compile("^verstr = ['\"]([^'\"]*)['\"]", re.M)
+    verstrline = open(VERSIONFILE, "rt").read()
+    mo = VSRE.search(verstrline)
+    if mo:
+        verstr = mo.group(1)
+    else:
+        print "unable to find version in version.py"
+        raise RuntimeError("if version.py exists, it must be well-formed")
 
 setup(name='allmydata-tahoe',
       version=verstr,
index 415dff459bdc74af25127a82199a5aa846a58e6d..0ad8d29399ee947a463afa01d8061a21bc5b625d 100644 (file)
@@ -1,5 +1,3 @@
-verstr="0.2.0-0-UNSTABLE"
-# The line is placed above so that it can be easily read by build scripts.
 
 """
 Decentralized storage grid.
@@ -9,13 +7,14 @@ maintainer web site: U{http://allmydata.com/}
 community web site: U{http://allmydata.org/}
 """
 
-from util.version import Version
+__version__ = "unknown"
+try:
+    from allmydata.version import __version__
+except ImportError:
+    # we're running in a tree that hasn't run misc/make-version.py, so we
+    # don't know what our version is. This should not happen very often.
+    pass
 
-# For an explanation of what the parts of the version string mean,
-# please see pyutil.version.
-__version__ = Version(verstr)
-
-# Please put a URL or other note here which shows where to get the branch of
-# development from which this version grew.
-__sources__ = ["http://allmydata.org/source/tahoe",]
+hush_pyflakes = __version__
+del hush_pyflakes