Skip to content

Commit ee0b58b

Browse files
Store precise version number, and append suffixes as-needed to ensure exact version of code can be known: release[+gitsha]+localmod
[+gitsha] will be ignored if this is exactly a release. +localmod will be dropped if there are no uncommitted modifications to the code.
1 parent 8294ca3 commit ee0b58b

File tree

5 files changed

+97
-11
lines changed

5 files changed

+97
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ venv
88
build*/
99
dist*/
1010
autodoc*
11+
switch_model/installed_version.py

get_and_record_version.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import print_function
2+
import logging
3+
import os
4+
import subprocess
5+
6+
"""
7+
Define a precise package version that includes any git digests for any commits
8+
made subsequently to a package release.
9+
10+
Example:
11+
1) Some commits have been made subsequent to an official release (possibly on
12+
a branch), plus some uncommitted modifications. The version would be:
13+
v1.0.4+{gitsha}+localmod
14+
2) Same scenario, but no uncommitted modifications: v1.0.4+{gitsha}
15+
3) No commits since the last official release: v1.0.4
16+
17+
These functions are encoded into a separate file from setup.py to support
18+
including precise versions in docker tags.
19+
"""
20+
21+
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}'
32+
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)
45+
46+
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__
68+
69+
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())

setup.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
import os
1616
from setuptools import setup, find_packages
1717

18-
# Get the version number. Strategy #3 from https://packaging.python.org/single_source_version/
19-
version_path = os.path.join(os.path.dirname(__file__), 'switch_model', 'version.py')
20-
version = {}
21-
with open(version_path) as f:
22-
exec(f.read(), version)
23-
__version__ = version['__version__']
18+
from get_and_record_version import get_and_record_version
19+
20+
repo_path = os.path.dirname(os.path.realpath(__file__))
21+
__version__ = get_and_record_version(repo_path)
2422

2523
def read(*rnames):
2624
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
@@ -55,6 +53,9 @@ def read(*rnames):
5553
'Topic :: Software Development :: Libraries :: Python Modules'
5654
],
5755
packages=find_packages(include=['switch_model', 'switch_model.*']),
56+
package_data = {
57+
'switch_model': ['data/*']
58+
},
5859
keywords=[
5960
'renewable', 'power', 'energy', 'electricity',
6061
'production cost', 'capacity expansion',

switch_model/data/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""This directory contains any necessary package data or default configuration
2+
files.
3+
"""

switch_model/version.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
# Copyright (c) 2015-2019 The Switch Authors. All rights reserved.
22
# Licensed under the Apache License, Version 2.0, which is in the LICENSE file.
33
"""
4-
This file should only include the version. Do not import any packages or
5-
modules here because this file needs to be executed before Switch is
6-
installed and executed in environments that don't have any dependencies
7-
installed.
4+
This file should only include the version. Do not import anything in here that
5+
is not part of a minimal python distribution because this file needs to be
6+
executed before Switch is installed and executed in environments that don't
7+
have any dependencies installed.
88
"""
9-
__version__='2.0.4'
9+
import os
10+
11+
base_version = '2.0.4'
12+
13+
try:
14+
DATA_ROOT = os.path.join(os.path.dirname(__file__), 'data')
15+
with open(os.path.join(DATA_ROOT, 'installed_version.txt'), 'r') as f:
16+
__version__ = f.read().strip()
17+
except IOError:
18+
__version__ = base_version

0 commit comments

Comments
 (0)