From 031ee08407cfb7edd073fbbbaff2060ff3a3bd37 Mon Sep 17 00:00:00 2001 From: Maxim Martynov Date: Mon, 24 Oct 2022 16:23:59 +0300 Subject: [PATCH] Make version sanitization less strict --- CHANGELOG.rst | 9 +++++++++ setuptools_git_versioning.py | 17 ++++++++++++++++- tests/test_integration/test_substitution.py | 3 ++- tests/test_integration/test_tag.py | 2 ++ tests/test_integration/test_version_callback.py | 2 ++ tests/test_integration/test_version_file.py | 2 ++ 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b41d646..7380492 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,15 @@ Changelog 1.12 ---- +.. changelog:: + :version: 1.12.1 + + .. change:: + :tags: core, bug + + Make version sanitization less strict, allow to automatically convert some cases, e.g. + ``1.0.0+feature/abc`` to ``1.0.0+feature.abc`` + .. changelog:: :version: 1.12.0 :released: 13.10.2022 diff --git a/setuptools_git_versioning.py b/setuptools_git_versioning.py index 4610418..a5278bd 100644 --- a/setuptools_git_versioning.py +++ b/setuptools_git_versioning.py @@ -27,6 +27,9 @@ ENV_VARS_REGEXP = re.compile(r"\{env:(?P[^:}]+):?(?P[^}]+\}*)?\}", re.IGNORECASE | re.UNICODE) TIMESTAMP_REGEXP = re.compile(r"\{timestamp:?(?P[^:}]+)?\}", re.IGNORECASE | re.UNICODE) +# https://github.com/pypa/setuptools/blob/bc39d28bda2a1faee6680ae30e42526b9d775151/setuptools/command/dist_info.py#L108-L131 +UNSUPPORTED_SYMBOL_REGEXP = re.compile(r"[^\w\d]+", re.IGNORECASE | re.UNICODE) + LOG_FORMAT = "[%(asctime)s] %(levelname)+8s: %(message)s" # setuptools v60.2.0 changed default logging level to DEBUG: https://github.com/pypa/setuptools/pull/2974 # to avoid printing information messages to the same output as version number, @@ -447,7 +450,19 @@ def get_version_from_callback( def sanitize_version(version: str) -> str: log.log(INFO, "Before sanitization %r", version) - result = str(Version(version)) + public, sep, local = version.partition("+") + + # replace "feature/ABC-123" with "feature.ABC.123" + sanitized_public = UNSUPPORTED_SYMBOL_REGEXP.sub(".", public) + sanitized_local = UNSUPPORTED_SYMBOL_REGEXP.sub(".", local) + + sanitized_version = sanitized_public + sep + sanitized_local + sanitized_version = sanitized_version.rstrip(".") + + # replace "feature.ABC.123" with "feature.abc.123" + # drop leading "v" symbol + # other replacements according to PEP-440, like "-dev" -> ".dev" + result = str(Version(sanitized_version)) log.log(INFO, "Result %r", result) return result diff --git a/tests/test_integration/test_substitution.py b/tests/test_integration/test_substitution.py index 3be2614..b3e735f 100644 --- a/tests/test_integration/test_substitution.py +++ b/tests/test_integration/test_substitution.py @@ -135,6 +135,8 @@ def test_substitution_env(repo, dev_template, pipeline_id, suffix): "{tag}.post{ccount}+{}", lambda dt: (dt.strftime("%Y.%m.%dt%H.%M"),), ), + # unknown substitution + ("{tag}+git.{timestamp:%i}", "{tag}+git.i", lambda x: []), # pure string ("{tag}+git.{timestamp:abc}", "{tag}+git.abc", lambda x: []), ], @@ -167,7 +169,6 @@ def test_substitution_timestamp(repo, template, fmt, callback): "{tag}+a{env:MISSING_ENV:{}}}", "{tag}+a{timestamp:A:B}", "{tag}+a{timestamp:{%Y}", - "{tag}+a{timestamp:%i}", ], ) def test_substitution_wrong_format(repo, template): diff --git a/tests/test_integration/test_tag.py b/tests/test_integration/test_tag.py index a4a1f12..0521638 100644 --- a/tests/test_integration/test_tag.py +++ b/tests/test_integration/test_tag.py @@ -113,6 +113,8 @@ def test_tag_missing(repo, create_config, starting_version, version): ("1.2.3+local", "1.2.3+local"), ("1.2.3+local-abc", "1.2.3+local.abc"), ("1.2.3+local_abc", "1.2.3+local.abc"), + ("1.2.3+local/abc", "1.2.3+local.abc"), + ("1.2.3+local/abc/-", "1.2.3+local.abc"), ], ) def test_tag_sanitization(repo, create_config, tag, version): diff --git a/tests/test_integration/test_version_callback.py b/tests/test_integration/test_version_callback.py index b4dff83..769141b 100644 --- a/tests/test_integration/test_version_callback.py +++ b/tests/test_integration/test_version_callback.py @@ -157,6 +157,8 @@ def test_version_callback_missing(repo, create_version_py, create_config): ("1.2.3+local", "1.2.3+local"), ("1.2.3+local-abc", "1.2.3+local.abc"), ("1.2.3+local_abc", "1.2.3+local.abc"), + ("1.2.3+local/abc", "1.2.3+local.abc"), + ("1.2.3+local/abc/-", "1.2.3+local.abc"), ], ) def test_version_callback_sanitization(repo, version, real_version, create_config): diff --git a/tests/test_integration/test_version_file.py b/tests/test_integration/test_version_file.py index e4030b1..6fd91a6 100644 --- a/tests/test_integration/test_version_file.py +++ b/tests/test_integration/test_version_file.py @@ -122,6 +122,8 @@ def test_version_file_dirty(repo, create_config, add, template, subst): ("1.2.3+local", "1.2.3+local"), ("1.2.3+local-abc", "1.2.3+local.abc"), ("1.2.3+local_abc", "1.2.3+local.abc"), + ("1.2.3+local/abc", "1.2.3+local.abc"), + ("1.2.3+local/abc/-", "1.2.3+local.abc"), ], ) @pytest.mark.parametrize("count_commits_from_version_file", [True, False])