Skip to content

Commit

Permalink
Prerelease version strings such as 1.0.0-rc1 were incorrectly retur…
Browse files Browse the repository at this point in the history
…ned 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
  • Loading branch information
Sylvain MARIE committed Feb 24, 2021
1 parent 71c731a commit cdb4805
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
50 changes: 48 additions & 2 deletions getversion/plugin_setuptools_scm.py
Expand Up @@ -27,9 +27,54 @@ def __str__(self):

try:
from setuptools_scm import get_version
from setuptools_scm.version import guess_next_dev_version
from setuptools_scm.utils import has_command
has_git_command = has_command('git')


def fixed_version_scheme(version):
"""
A fix for https://github.com/smarie/python-getversion/issues/10
until this is fixed in setuptools_scm or in pkg_resources
so that the dash is not removed when a pre-release version is present (e.g. 1.0.0-rc1)
"""
# This is the bugged string would be used by the default scheme (for reference)
# str(version.tag)

# modify the 'pre' part only if needed
do_hack = version.tag.is_prerelease
if do_hack:
# make a backup
_version_bak = version.tag._version

# get the various parts
parts = _version_bak._asdict()

# make sure we understand what we do by doing a simple copy
clone = type(_version_bak)(**parts)
assert clone == _version_bak, "Internal error with this version of `pkg_resources`, please report"

# now do a mod
parts['pre'] = ("-",) + parts['pre']
_version_mod = type(_version_bak)(**parts)

# and apply it
version.tag._version = _version_mod

# we can check that the string has been fixed correctly
# str(version.tag)

# create the version string as usual by applying setuptools_scm's default version scheme
# note that despite the name, this does not increment anything if the tag is exact (no local mod)
res = guess_next_dev_version(version)

# undo our hack if needed
if do_hack:
version.tag._version = _version_bak # noqa

return res


def scm_get_version_recursive_root(abs_path, initial_path):
"""
Recursively climbs the parent folders, searching for a git root
Expand All @@ -38,7 +83,7 @@ def scm_get_version_recursive_root(abs_path, initial_path):
:return:
"""
try:
return get_version(abs_path)
res = get_version(abs_path, version_scheme=fixed_version_scheme)
except LookupError as e:
parent_dir = dirname(abs_path)
if parent_dir == abs_path:
Expand All @@ -47,7 +92,8 @@ def scm_get_version_recursive_root(abs_path, initial_path):
else:
# recurse
return scm_get_version_recursive_root(parent_dir, initial_path=initial_path)

else:
return res

def get_version_using_setuptools_scm(module # type: ModuleType
):
Expand Down
40 changes: 40 additions & 0 deletions getversion/tests/test_issues.py
@@ -0,0 +1,40 @@
from os.path import join, pardir

from setuptools_scm import _do_parse, Configuration, format_version
from getversion.plugin_setuptools_scm import fixed_version_scheme

from pkg_resources import parse_version as pkg_parse_version


def test_issue_10():
# version with a prerelease
version_str = "1.0.0-rc1"

# Parse with pkg_resource and make sure that the issue is still there (see #10)
pkg_res_version = pkg_parse_version(version_str)
assert str(pkg_res_version) == '1.0.0rc1'

# use setuptools_scm to get a version object that we can modify to introduce the bug
config = Configuration(root=join(__file__, pardir, pardir, pardir))
s_version = _do_parse(config)
# --make sure that internals of `setuptools_scm` have not changed: the .tag object is a pkg_resource Version
assert isinstance(s_version.tag, type(pkg_res_version))
# --now lets modify the version object so as to inject the issue
s_version.tag = pkg_res_version

# make sure that setuptools_scm did not fix the issue yet
pb_ver = format_version(
s_version,
version_scheme=config.version_scheme,
local_scheme=config.local_scheme,
)
assert str(pb_ver) != version_str
assert str(pb_ver).startswith("1.0.0rc") # dash removed

# make sure that with our fixed version scheme (used in our plugin) it works
fixed_vers = format_version(
s_version,
version_scheme=fixed_version_scheme,
local_scheme=config.local_scheme,
)
assert str(fixed_vers).startswith("1.0.0-rc") # with the dash

0 comments on commit cdb4805

Please sign in to comment.