Skip to content

Commit 30108ce

Browse files
committed
Merge branch 'use-git-archive-version'.
Support building from `git archive` tarball.
2 parents 7dc9628 + 227901c commit 30108ce

File tree

7 files changed

+104
-47
lines changed

7 files changed

+104
-47
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
/.travis* export-ignore
44
/conda-recipe/ export-ignore
55
/doc export-ignore
6-
/src/diffpy/version.tpl export-ignore
6+
gitarchive.cfg export-subst

doc/manual/source/conf.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@
5858
# The version info for the project you're documenting, acts as replacement for
5959
# |version| and |release|, also used in various other places throughout the
6060
# built documents.
61-
from libdiffpybuildutils import gitinfo
62-
ginfo = gitinfo()
61+
from libdiffpybuildutils import getversion
62+
gver = getversion()
6363
# The short X.Y version.
64-
vfmt = '%(major)i.%(minor)i' + ('.%(micro)i' if ginfo['micro'] else '')
65-
version = vfmt % ginfo
64+
vfmt = '%(major)i.%(minor)i' + ('.%(micro)i' if gver['micro'] else '')
65+
version = vfmt % gver
6666
# The full version, including alpha/beta/rc tags.
67-
release = ginfo['version']
67+
release = gver['version']
6868

6969
# The language for content autogenerated by Sphinx. Refer to documentation
7070
# for a list of supported languages.
@@ -73,7 +73,7 @@
7373
# There are two options for replacing |today|: either, you set today to some
7474
# non-false value, then it is used:
7575
#today = ''
76-
fulldate = ginfo['date']
76+
fulldate = gver['date']
7777
today_seconds = time.strptime(fulldate.split()[0], '%Y-%m-%d')
7878
today = time.strftime('%B %d, %Y', today_seconds)
7979
year = today.split()[-1]

site_scons/fallback_version.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python
2+
3+
'''
4+
Definition of FALLBACK_VERSION. Use it when git repository is
5+
not available for example, when building from git zip archive.
6+
7+
Update FALLBACK_VERSION when tagging a new release.
8+
'''
9+
10+
FALLBACK_VERSION = '1.3.3.post0'

site_scons/gitarchive.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[DEFAULT]
2+
commit = $Format:%H$
3+
date = $Format:%ai$
4+
refnames = $Format:%D$

site_scons/libdiffpybuildutils.py

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,38 @@
44
'''
55

66
import os
7+
import re
78

89
MYDIR = os.path.dirname(os.path.abspath(__file__))
910

11+
GIT_MISSING_ERROR_MSG = """
12+
Cannot determine libdiffpy version. Compile from a git repository
13+
or use a source archive from
14+
15+
https://github.com/diffpy/libdiffpy/releases
16+
"""
17+
18+
1019
def gitinfo():
1120
'Extract dictionary of version data from git records.'
12-
import re
1321
from subprocess import Popen, PIPE
1422
global _cached_gitinfo
15-
if _cached_gitinfo is not None: return _cached_gitinfo
16-
rv = _cached_gitinfo = {}
23+
if _cached_gitinfo is not None:
24+
return _cached_gitinfo
1725
nullfile = open(os.devnull, 'w')
1826
kw = dict(stdout=PIPE, stderr=nullfile, cwd=MYDIR)
1927
proc = Popen(['git', 'describe', '--match=v[[:digit:]]*'], **kw)
2028
desc = proc.stdout.read()
21-
if proc.wait(): return gitinfo()
29+
if proc.wait():
30+
_cached_gitinfo = {}
31+
return gitinfo()
2232
proc = Popen(['git', 'log', '-1', '--format=%H %ai'], **kw)
2333
glog = proc.stdout.read()
2434
words = desc.strip().split('-')
2535
vtag = words[0].lstrip('v')
2636
vnum = int((words[1:2] or ['0'])[0])
37+
rv = {}
2738
rv['commit'], rv['date'] = glog.strip().split(None, 1)
28-
mx = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?((?:[ab]|rc)\d*)?', vtag)
29-
rv['major'] = int(mx.group(1))
30-
rv['minor'] = int(mx.group(2))
31-
rv['micro'] = int(mx.group(3) or 0)
32-
rv['prerelease'] = mx.group(4)
3339
rv['patchnumber'] = vnum
3440
rv['version'] = vtag
3541
if vnum:
@@ -38,3 +44,50 @@ def gitinfo():
3844
return gitinfo()
3945

4046
_cached_gitinfo = None
47+
48+
49+
def getversion():
50+
"""Extract version from gitinfo and/or gitarchive.cfg file.
51+
52+
Process gitinfo first and make sure it matches FALLBACK_VERSION
53+
in gitarchive.cfg. Use expanded data from gitarchive.cfg when
54+
these sources are from git archive bundle.
55+
"""
56+
from ConfigParser import RawConfigParser
57+
from fallback_version import FALLBACK_VERSION
58+
gitarchivecfgfile = os.path.join(MYDIR, 'gitarchive.cfg')
59+
assert os.path.isfile(gitarchivecfgfile)
60+
cp = RawConfigParser()
61+
cp.read(gitarchivecfgfile)
62+
ga = cp.defaults()
63+
gi = gitinfo()
64+
rv = {}
65+
if gi:
66+
afb = FALLBACK_VERSION
67+
gfb = gi['version'].split('.post')[0] + '.post0'
68+
emsg = "Inconsistent FALLBACK_VERSION {!r}. Git tag suggests {!r}."
69+
assert gfb == afb, emgs.format(afb, gfb)
70+
rv.update(gi)
71+
else:
72+
# Not a git repository. Require that gitarchive.cfg is expanded.
73+
assert '$Format:' not in ga['commit'], GIT_MISSING_ERROR_MSG
74+
rv['commit'] = ga['commit']
75+
rv['date'] = ga['date']
76+
# First assume we have an undetermined post-release. Keep version
77+
# suffix as ".post0", but set patchnumber to ensure we are post
78+
# FALLBACK_VERSION.
79+
rv['version'] = FALLBACK_VERSION
80+
rv['patchnumber'] = 1
81+
# If we are at version tag turn this to regular release.
82+
mx = re.search(r'\btag: v(\d[^,]*)', ga['refnames'])
83+
if mx:
84+
rv['version'] = mx.group(1)
85+
rv['patchnumber'] = 0
86+
# rv['version'] is resolved, let's parse its subfields.
87+
vbase = rv['version'].split('.post')[0]
88+
mx = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?((?:[ab]|rc)\d*)?', vbase)
89+
rv['major'] = int(mx.group(1))
90+
rv['minor'] = int(mx.group(2))
91+
rv['micro'] = int(mx.group(3) or 0)
92+
rv['prerelease'] = mx.group(4)
93+
return rv

src/SConscript.sdist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def add_version_and_compress(target, source, env):
1111
fpout = gzip.GzipFile(target[0].path + '.gz', 'w', mtime=0)
1212
tfout = tarfile.open(fileobj=fpout, mode='w')
1313
# copy archive members up to version.cpp
14-
tiiter = iter(tfin)
14+
tiiter = (t for t in tfin if not t.name.endswith('/version.tpl'))
1515
for ti in tiiter:
1616
tfout.addfile(ti, tfin.extractfile(ti))
1717
if ti.name.endswith('diffpy/version.cpp'):

src/diffpy/SConscript.version

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,28 @@ def parsemajorminor(hcode):
1616

1717
def build_VersionCode(target, source, env):
1818
tplcode = source[0].get_contents()
19-
numversion = ginfo['major']
20-
numversion = 1000 * numversion + ginfo['minor']
21-
numversion = 1000 * numversion + ginfo['micro']
22-
numversion = 1000 * numversion + ginfo['patchnumber']
19+
numversion = gver['major']
20+
numversion = 1000 * numversion + gver['minor']
21+
numversion = 1000 * numversion + gver['micro']
22+
numversion = 1000 * numversion + gver['patchnumber']
2323
# verify that formulas in version.tpl work as advertised
2424
emsg = "Inconsistent value of DIFFPY_VERSION = %i" % numversion
25-
assert numversion // 1000000000 == ginfo['major'], emsg
26-
assert numversion // 1000000 % 1000 == ginfo['minor'], emsg
27-
assert numversion // 1000 % 1000 == ginfo['micro'], emsg
28-
assert numversion % 500 == ginfo['patchnumber'], emsg
25+
assert numversion // 1000000000 == gver['major'], emsg
26+
assert numversion // 1000000 % 1000 == gver['minor'], emsg
27+
assert numversion // 1000 % 1000 == gver['micro'], emsg
28+
assert numversion % 500 == gver['patchnumber'], emsg
2929
libversion = str(numversion) + "LL"
30-
if ginfo['prerelease']:
30+
if gver['prerelease']:
3131
libversion = "(-500 + %s)" % libversion
3232
flds = {
3333
'DIFFPY_VERSION' : libversion,
34-
'DIFFPY_VERSION_MAJOR' : ginfo['major'],
35-
'DIFFPY_VERSION_MINOR' : ginfo['minor'],
36-
'DIFFPY_VERSION_MICRO' : ginfo['micro'],
37-
'DIFFPY_VERSION_PATCH' : ginfo['patchnumber'],
38-
'DIFFPY_VERSION_STR' : ginfo['version'],
39-
'DIFFPY_VERSION_DATE' : ginfo['date'],
40-
'DIFFPY_GIT_SHA' : ginfo['commit'],
34+
'DIFFPY_VERSION_MAJOR' : gver['major'],
35+
'DIFFPY_VERSION_MINOR' : gver['minor'],
36+
'DIFFPY_VERSION_MICRO' : gver['micro'],
37+
'DIFFPY_VERSION_PATCH' : gver['patchnumber'],
38+
'DIFFPY_VERSION_STR' : gver['version'],
39+
'DIFFPY_VERSION_DATE' : gver['date'],
40+
'DIFFPY_GIT_SHA' : gver['commit'],
4141
}
4242
versiontemplate = string.Template(tplcode)
4343
versioncode = versiontemplate.safe_substitute(flds)
@@ -65,26 +65,16 @@ env.Append(BUILDERS={'BuildFeaturesCode' :
6565

6666
vhpp = File('version.hpp')
6767

68-
MY_GIT_MISSING_ERROR_MSG = """
69-
Cannot determine libdiffpy version. Compile from a git repository
70-
or use a source archive from
71-
72-
https://github.com/diffpy/libdiffpy/releases
73-
"""
74-
7568
# If version.hpp exists do not use git
7669
if os.path.isfile(str(vhpp.srcnode())):
7770
majorminor = parsemajorminor(vhpp.srcnode().get_contents())
7871
else:
79-
from libdiffpybuildutils import gitinfo
72+
from libdiffpybuildutils import getversion
8073
vtpl = File('version.tpl')
81-
ginfo = gitinfo()
82-
if not ginfo:
83-
print MY_GIT_MISSING_ERROR_MSG
84-
Exit(1)
74+
gver = getversion()
8575
vhpp, = env.BuildVersionCode(['version.hpp'], vtpl)
86-
env.Depends(vhpp, env.Value(ginfo['version'] + ginfo['commit']))
87-
majorminor = (ginfo['major'], ginfo['minor'])
76+
env.Depends(vhpp, env.Value(gver['version'] + gver['commit']))
77+
majorminor = (gver['major'], gver['minor'])
8878

8979
fhpp, = env.BuildFeaturesCode(['features.tpl'])
9080
env.Depends(fhpp, env.Value(env['has_objcryst']))

0 commit comments

Comments
 (0)