Skip to content

Commit e49fd5f

Browse files
committed
Extract version from .git_archival.txt
Repairs #25. The stgit version may now be extracted from the .git_archival.txt file. The version is still sought first from builtin_version.py, then `git describe`, but now if those fail, the .git_archival.txt file is parsed. At setup time, it is now required that a valid version be found with either `git describe` or in the .git_archival.txt file. At runtime, stg will still run even if none of the version sources succeed, in which case 'unknown-version' will be reported. N.B. the .git_archival.txt file is only valid/usable for archives from a tag. For an archive from a non-tagged commit/tree, no version information will be extracted from .git_archival.txt. So, in practice, this new .git_archival.txt version mechanism is specifically meant to support tagged releases. The stgit.version.write_builtin_version() capability is moved into setup.py since writing builtin_version.py is a setup-time only concern. The VersionUnavailable exception is modified to inherit Exception instead of StgException. This is done because VersionUnavailable is local to the stgit.version module. It is helpful to limit the dependencies of the stgit modules imported at setup time. Finally, the stgit.version.version variable is removed. Instead, stgit.version.get_version() is called explicitly at the few sites that need to reference stgit's version. It is perhaps a bit easier to reason about the version when importing stgit.version does not have side effects. Signed-off-by: Peter Grayson <[email protected]>
1 parent dc3acca commit e49fd5f

File tree

4 files changed

+49
-35
lines changed

4 files changed

+49
-35
lines changed

setup.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
import os
88
import sys
99

10-
from stgit import version
11-
from stgit import commands, completion
10+
from stgit import commands, completion, version
1211

1312

1413
def __version_to_list(version):
@@ -60,7 +59,17 @@ def __check_git_version():
6059
# ensure readable template files
6160
old_mask = os.umask(0o022)
6261

63-
version.write_builtin_version()
62+
try:
63+
ver = version.git_describe_version()
64+
except version.VersionUnavailable:
65+
ver = version.git_archival_version()
66+
with open('stgit/builtin_version.py', 'w') as f:
67+
print(
68+
'# This file is automatically generated. Do not edit.',
69+
'version = {ver!r}'.format(ver=ver),
70+
sep='\n',
71+
file=f,
72+
)
6473

6574
# generate the python command list
6675
with open('stgit/commands/cmdlist.py', 'w') as f:
@@ -72,7 +81,7 @@ def __check_git_version():
7281

7382
setup(
7483
name='stgit',
75-
version=version.version,
84+
version=ver,
7685
license='GPLv2',
7786
author='Catalin Marinas',
7887
author_email='[email protected]',

stgit/commands/mail.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def __build_extra_headers(msg, msg_id, ref_id = None):
427427
ref_id = '<%s>' % ref_id.strip(' \t\n<>')
428428
msg['In-Reply-To'] = ref_id
429429
msg['References'] = ref_id
430-
msg['User-Agent'] = 'StGit/%s' % version.version
430+
msg['User-Agent'] = 'StGit/%s' % version.get_version()
431431

432432
# update other address headers
433433
__update_header(msg, 'Reply-To')

stgit/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ def _main():
138138
print_help()
139139
sys.exit(utils.STGIT_SUCCESS)
140140
if cmd in ['-v', '--version', 'version']:
141-
from stgit.version import version
142-
print('Stacked GIT %s' % version)
141+
from stgit.version import get_version
142+
print('Stacked GIT %s' % get_version())
143143
os.system('git --version')
144144
print('Python version %s' % sys.version)
145145
sys.exit(utils.STGIT_SUCCESS)

stgit/version.py

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,62 +5,67 @@
55
import re
66
import sys
77

8-
from stgit import run, utils
9-
from stgit.exception import StgException
108
from stgit.run import Run, RunException
119

1210

13-
class VersionUnavailable(StgException):
11+
class VersionUnavailable(Exception):
1412
pass
1513

14+
1615
def git_describe_version():
17-
path = sys.path[0]
16+
root = sys.path[0]
1817
try:
19-
v = Run('git', 'describe', '--tags', '--abbrev=4'
20-
).cwd(path).output_one_line()
18+
v = Run(
19+
'git', 'describe', '--tags', '--abbrev=4'
20+
).cwd(root).output_one_line()
2121
except RunException as e:
2222
raise VersionUnavailable(str(e))
23-
if not re.match(r'^v[0-9]', v):
24-
raise VersionUnavailable('%s: bad version' % v)
23+
m = re.match(r'^v([0-9].*)', v)
24+
if m:
25+
v = m.group()
26+
else:
27+
raise VersionUnavailable('bad version: %s' % v)
2528
try:
26-
dirty = Run('git', 'diff-index', '--name-only', 'HEAD'
27-
).cwd(path).raw_output()
29+
dirty = Run(
30+
'git', 'diff-index', '--name-only', 'HEAD'
31+
).cwd(root).raw_output()
2832
except RunException as e:
2933
raise VersionUnavailable(str(e))
3034
if dirty:
3135
v += '-dirty'
32-
return utils.strip_prefix('v', v)
36+
return v
37+
38+
39+
def git_archival_version():
40+
tag_re = re.compile(r'(?<=\btag: )([^,]+)\b')
41+
archival_path = os.path.join(sys.path[0], '.git_archival.txt')
42+
with open(archival_path) as f:
43+
for line in f:
44+
if line.startswith('ref-names:'):
45+
tags = tag_re.findall(line)
46+
if tags:
47+
return tags[0]
48+
else:
49+
raise VersionUnavailable('no tags found in %s' % archival_path)
50+
3351

3452
def builtin_version():
3553
try:
36-
import stgit.builtin_version as bv
54+
import stgit.builtin_version
3755
except ImportError:
38-
raise VersionUnavailable()
56+
raise VersionUnavailable('could not import stgit.builtin_version')
3957
else:
40-
return bv.version
41-
42-
def _builtin_version_file(ext = 'py'):
43-
return os.path.join(sys.path[0], 'stgit', 'builtin_version.%s' % ext)
58+
return stgit.builtin_version.version
4459

45-
def write_builtin_version():
46-
try:
47-
v = git_describe_version()
48-
except VersionUnavailable:
49-
return
50-
with open(_builtin_version_file(), 'w') as f:
51-
f.write(
52-
'# This file was generated automatically. Do not edit by hand.\n'
53-
'version = %r\n' % v)
5460

5561
def get_version():
56-
for v in [builtin_version, git_describe_version]:
62+
for v in [builtin_version, git_describe_version, git_archival_version]:
5763
try:
5864
return v()
5965
except VersionUnavailable:
6066
pass
6167
return 'unknown-version'
6268

63-
version = get_version()
6469

6570
# minimum version requirements
6671
git_min_ver = '1.5.2'

0 commit comments

Comments
 (0)