update version-number handling, pull release tags from darcs history

This commit is contained in:
Brian Warner 2007-05-03 20:14:07 -07:00
parent f4525f2af1
commit 3f6b660272
6 changed files with 184 additions and 20 deletions

View 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$

View 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

38
misc/get-version.py Normal file
View File

@ -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

117
misc/make-version.py Normal file
View File

@ -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)

View File

@ -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,

View 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