Skip to content

Commit 0f21b73

Browse files
Make local version acquisition robust to the edge case of a git repository that doesn't include version tags.
1 parent f3c7bf3 commit 0f21b73

File tree

2 files changed

+90
-47
lines changed

2 files changed

+90
-47
lines changed

get_and_record_version.py

Lines changed: 89 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from __future__ import print_function
2+
import argparse
23
import logging
34
import os
45
import subprocess
@@ -19,54 +20,96 @@
1920
"""
2021

2122
def get_git_version():
22-
"""
23-
Try to get git version like '{tag}+{gitsha}', with the added suffix
24-
"+localmod" if the git repo has had any uncommitted modifications.
25-
The "+{gitsha}" suffix will be dropped if this is the tagged version.
26-
Code adapted from setuptools_git_version which has an MIT license.
27-
https://pypi.org/project/setuptools-git-version/
28-
Note: Only look for tags that start with "2." to avoid tags like "demo-v1.0.1".
29-
"""
30-
git_command = "git describe --tags --long --match '2.*' --dirty --always"
31-
fmt = '{tag}+{gitsha}{dirty}'
23+
"""
24+
Try to get git version like '{tag}+{gitsha}', with the added suffix
25+
"+localmod" if the git repo has had any uncommitted modifications.
26+
The "+{gitsha}" suffix will be dropped if this is the tagged version.
27+
Code adapted from setuptools_git_version which has an MIT license.
28+
https://pypi.org/project/setuptools-git-version/
29+
Note: Only look for tags that start with "2." to avoid tags like "demo-v1.0.1".
30+
"""
31+
git_command = "git describe --tags --long --match '2.*' --dirty --always"
32+
fmt = '{tag}+{gitsha}{dirty}'
3233

33-
git_version = subprocess.check_output(git_command, shell=True).decode('utf-8').strip()
34-
parts = git_version.split('-')
35-
# FYI, if it can't find a tag for whatever reason, len may be 1 or 2
36-
assert len(parts) in (3, 4)
37-
if len(parts) == 4:
38-
dirty = '+localmod'
39-
else:
40-
dirty = ''
41-
tag, count, sha = parts[:3]
42-
if count == '0' and not dirty:
43-
return tag
44-
return fmt.format(tag=tag, gitsha=sha.lstrip('g'), dirty=dirty)
34+
git_version = subprocess.check_output(git_command, shell=True).decode('utf-8').strip()
35+
parts = git_version.split('-')
36+
# FYI, if it can't find a tag for whatever reason, len may be 1 or 2
37+
assert len(parts) in (3, 4), (
38+
"Trouble parsing git version output. Got {}, expected 3 or 4 things "
39+
"separated by dashes. This has been caused by the repository having no "
40+
"available tags, which was solved by fetching from the main repo:\n"
41+
"`git remote add main https://github.com/switch-model/switch.git && "
42+
"git fetch --all`".format(git_version)
43+
)
44+
if len(parts) == 4:
45+
dirty = '+localmod'
46+
else:
47+
dirty = ''
48+
tag, count, sha = parts[:3]
49+
if count == '0' and not dirty:
50+
return tag
51+
return fmt.format(tag=tag, gitsha=sha.lstrip('g'), dirty=dirty)
4552

4653
def get_and_record_version(repo_path):
47-
"""
48-
Attempt to get an absolute version number that includes commits made since
49-
the last release. If that succeeds, record the absolute version and use it
50-
for the pip catalog. If that fails, fall back to something reasonable and
51-
vague for the pip catalog, using the data from base_version.py.
52-
"""
53-
pkg_dir = os.path.join(repo_path , 'switch_model', 'data' )
54-
try:
55-
__version__ = get_git_version()
56-
with open(os.path.join(pkg_dir, 'installed_version.txt'), 'w+') as f:
57-
f.write(__version__)
58-
except subprocess.CalledProcessError as e:
59-
logging.warning(
60-
"Could not call git as a subprocess to determine precise version."
61-
"Falling back to using the static version from version.py")
62-
logging.exception(e)
63-
module_dat = {}
64-
with open(os.path.join(pkg_dir, 'version.py')) as fp:
65-
exec(fp.read(), module_dat)
66-
__version__ = module_dat['__version__']
67-
return __version__
54+
"""
55+
Attempt to get an absolute version number that includes commits made since
56+
the last release. If that succeeds, record the absolute version and use it
57+
for the pip catalog. If that fails, fall back to something reasonable and
58+
vague for the pip catalog, using the data from base_version.py.
59+
"""
60+
pkg_dir = os.path.join(repo_path , 'switch_model' )
61+
data_dir = os.path.join(pkg_dir, 'data' )
62+
__version__ = None
63+
try:
64+
__version__ = get_git_version()
65+
with open(os.path.join(data_dir, 'installed_version.txt'), 'w+') as f:
66+
f.write(__version__)
67+
except subprocess.CalledProcessError as e:
68+
logging.warning(
69+
"Could not call git as a subprocess to determine precise version."
70+
"Falling back to using the static version from version.py")
71+
logging.exception(e)
72+
except AssertionError as e:
73+
logging.warning("Trouble parsing git output.")
74+
logging.exception(e)
75+
if __version__ is None:
76+
module_dat = {}
77+
with open(os.path.join(pkg_dir, 'version.py')) as fp:
78+
exec(fp.read(), module_dat)
79+
__version__ = module_dat['__version__']
80+
return __version__
81+
82+
def get_args():
83+
parser = argparse.ArgumentParser(
84+
description='Get a precise local version of this git repository',
85+
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
86+
parser.add_argument(
87+
'--verbose', '-v', dest='verbose', default=False,
88+
action='store_const', const=logging.WARNING,
89+
help='Show information about model preparation and solution')
90+
parser.add_argument(
91+
'--very-verbose', '-vv', dest='verbose', default=False,
92+
action='store_const', const=logging.INFO,
93+
help='Show more information about model preparation and solution')
94+
parser.add_argument(
95+
'--very-very-verbose', '-vvv', dest='verbose', default=False,
96+
action='store_const', const=logging.DEBUG,
97+
help='Show debugging-level information about model preparation and solution')
98+
parser.add_argument(
99+
'--quiet', '-q', dest='verbose', action='store_false',
100+
help="Don't show information about model preparation and solution "
101+
"(cancels --verbose setting)")
102+
103+
args = parser.parse_args()
104+
return args
105+
106+
def main():
107+
args = get_args()
108+
if args.verbose:
109+
logging.basicConfig(format='%(levelname)s:%(message)s', level=args.verbose)
110+
repo_path = os.path.dirname(os.path.realpath(__file__))
111+
__version__ = get_and_record_version(repo_path)
112+
print(__version__)
68113

69114
if __name__ == "__main__":
70-
repo_path = os.path.dirname(os.path.realpath(__file__))
71-
__version__ = get_and_record_version(repo_path)
72-
print(get_git_version())
115+
main()

switch_model/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
DATA_ROOT = os.path.join(os.path.dirname(__file__), 'data')
1515
with open(os.path.join(DATA_ROOT, 'installed_version.txt'), 'r') as f:
1616
__version__ = f.read().strip()
17-
except IOError:
17+
except (IOError, NameError):
1818
__version__ = base_version

0 commit comments

Comments
 (0)