Skip to content

Commit cdb4805

Browse files
author
Sylvain MARIE
committed
Prerelease version strings such as 1.0.0-rc1 were incorrectly returned as 1.0.0rc1 (without dash) because of an issue with setuptools_scm due to pkg_resources removing the dash of prerelease versions. Fixes #10
1 parent 71c731a commit cdb4805

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

getversion/plugin_setuptools_scm.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,54 @@ def __str__(self):
2727

2828
try:
2929
from setuptools_scm import get_version
30+
from setuptools_scm.version import guess_next_dev_version
3031
from setuptools_scm.utils import has_command
3132
has_git_command = has_command('git')
3233

34+
35+
def fixed_version_scheme(version):
36+
"""
37+
A fix for https://github.com/smarie/python-getversion/issues/10
38+
until this is fixed in setuptools_scm or in pkg_resources
39+
so that the dash is not removed when a pre-release version is present (e.g. 1.0.0-rc1)
40+
"""
41+
# This is the bugged string would be used by the default scheme (for reference)
42+
# str(version.tag)
43+
44+
# modify the 'pre' part only if needed
45+
do_hack = version.tag.is_prerelease
46+
if do_hack:
47+
# make a backup
48+
_version_bak = version.tag._version
49+
50+
# get the various parts
51+
parts = _version_bak._asdict()
52+
53+
# make sure we understand what we do by doing a simple copy
54+
clone = type(_version_bak)(**parts)
55+
assert clone == _version_bak, "Internal error with this version of `pkg_resources`, please report"
56+
57+
# now do a mod
58+
parts['pre'] = ("-",) + parts['pre']
59+
_version_mod = type(_version_bak)(**parts)
60+
61+
# and apply it
62+
version.tag._version = _version_mod
63+
64+
# we can check that the string has been fixed correctly
65+
# str(version.tag)
66+
67+
# create the version string as usual by applying setuptools_scm's default version scheme
68+
# note that despite the name, this does not increment anything if the tag is exact (no local mod)
69+
res = guess_next_dev_version(version)
70+
71+
# undo our hack if needed
72+
if do_hack:
73+
version.tag._version = _version_bak # noqa
74+
75+
return res
76+
77+
3378
def scm_get_version_recursive_root(abs_path, initial_path):
3479
"""
3580
Recursively climbs the parent folders, searching for a git root
@@ -38,7 +83,7 @@ def scm_get_version_recursive_root(abs_path, initial_path):
3883
:return:
3984
"""
4085
try:
41-
return get_version(abs_path)
86+
res = get_version(abs_path, version_scheme=fixed_version_scheme)
4287
except LookupError as e:
4388
parent_dir = dirname(abs_path)
4489
if parent_dir == abs_path:
@@ -47,7 +92,8 @@ def scm_get_version_recursive_root(abs_path, initial_path):
4792
else:
4893
# recurse
4994
return scm_get_version_recursive_root(parent_dir, initial_path=initial_path)
50-
95+
else:
96+
return res
5197

5298
def get_version_using_setuptools_scm(module # type: ModuleType
5399
):

getversion/tests/test_issues.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from os.path import join, pardir
2+
3+
from setuptools_scm import _do_parse, Configuration, format_version
4+
from getversion.plugin_setuptools_scm import fixed_version_scheme
5+
6+
from pkg_resources import parse_version as pkg_parse_version
7+
8+
9+
def test_issue_10():
10+
# version with a prerelease
11+
version_str = "1.0.0-rc1"
12+
13+
# Parse with pkg_resource and make sure that the issue is still there (see #10)
14+
pkg_res_version = pkg_parse_version(version_str)
15+
assert str(pkg_res_version) == '1.0.0rc1'
16+
17+
# use setuptools_scm to get a version object that we can modify to introduce the bug
18+
config = Configuration(root=join(__file__, pardir, pardir, pardir))
19+
s_version = _do_parse(config)
20+
# --make sure that internals of `setuptools_scm` have not changed: the .tag object is a pkg_resource Version
21+
assert isinstance(s_version.tag, type(pkg_res_version))
22+
# --now lets modify the version object so as to inject the issue
23+
s_version.tag = pkg_res_version
24+
25+
# make sure that setuptools_scm did not fix the issue yet
26+
pb_ver = format_version(
27+
s_version,
28+
version_scheme=config.version_scheme,
29+
local_scheme=config.local_scheme,
30+
)
31+
assert str(pb_ver) != version_str
32+
assert str(pb_ver).startswith("1.0.0rc") # dash removed
33+
34+
# make sure that with our fixed version scheme (used in our plugin) it works
35+
fixed_vers = format_version(
36+
s_version,
37+
version_scheme=fixed_version_scheme,
38+
local_scheme=config.local_scheme,
39+
)
40+
assert str(fixed_vers).startswith("1.0.0-rc") # with the dash

0 commit comments

Comments
 (0)