diff options
author | chrisjbillington <chrisjbillington@gmail.com> | 2020-05-11 14:45:43 -0400 |
---|---|---|
committer | chrisjbillington <chrisjbillington@gmail.com> | 2020-05-11 17:25:34 -0400 |
commit | e62d4aac4b2e9fa7c5c120f2f3b5108db21d52a2 (patch) | |
tree | b444580225dacd0a8789ffc8372d2362d8f5147e | |
parent | 6ad91d0085acc8091f2336faaf4710c1bae4cf18 (diff) | |
download | setuptools-scm-e62d4aac4b2e9fa7c5c120f2f3b5108db21d52a2.tar.gz |
Add release-branch-semver scheme
This is a scheme that assumes that the upcoming release for most
branches is a minor release, and that only for release branches
(those whose branch names parse as a version number according to current
configuration) is the upcoming version a patch release.
Better document the differences between the schemes in README.rst
-rw-r--r-- | README.rst | 17 | ||||
-rw-r--r-- | setup.py | 1 | ||||
-rw-r--r-- | src/setuptools_scm/version.py | 34 | ||||
-rw-r--r-- | testing/test_version.py | 43 |
4 files changed, 89 insertions, 6 deletions
@@ -477,9 +477,20 @@ Version number construction Available implementations: - :guess-next-dev: automatically guesses the next development version (default) - :post-release: generates post release versions (adds :code:`postN`) - :python-simplified-semver: basic semantic versioning similar to ``guess-next-dev`` + :guess-next-dev: Automatically guesses the next development version (default). + Guesses the upcoming release by incrementing the pre-release segment if present, + otherwise by incrementing the micro segment. Then appends :code:`.devN`. + :post-release: generates post release versions (adds :code:`.postN`) + :python-simplified-semver: Basic semantic versioning. Guesses the upcoming release + by incrementing the minor segment and setting the micro segment to zero if the + current branch contains the string ``'feature'``, otherwise by incrementing the + micro version. Then appends :code:`.devN`. Not compatible with pre-releases. + :release-branch-semver: Semantic versioning for projects with release branches. The + same as ``guess-next-dev`` (incrementing the pre-release or micro segment) if on + a release branch: a branch whose name (ignoring namespace) parses as a version + that matches the most recent tag up to the minor segment. Otherwise if on a + non-release branch, increments the minor segment and sets the micro segment to + zero, then appends :code:`.devN`. ``setuptools_scm.local_scheme`` Configures how the local part of a version is rendered given a @@ -89,6 +89,7 @@ arguments = dict( guess-next-dev = setuptools_scm.version:guess_next_dev_version post-release = setuptools_scm.version:postrelease_version python-simplified-semver = setuptools_scm.version:simplified_semver_version + release-branch-semver = setuptools_scm.version:release_branch_semver [setuptools_scm.local_scheme] node-and-date = setuptools_scm.version:get_local_node_and_date diff --git a/src/setuptools_scm/version.py b/src/setuptools_scm/version.py index aa4bd49..cc4d838 100644 --- a/src/setuptools_scm/version.py +++ b/src/setuptools_scm/version.py @@ -132,6 +132,7 @@ class ScmVersion(object): dirty=False, preformatted=False, branch=None, + config=None, **kw ): if kw: @@ -146,6 +147,7 @@ class ScmVersion(object): self.dirty = dirty self.preformatted = preformatted self.branch = branch + self.config = config @property def extra(self): @@ -193,7 +195,14 @@ def _parse_tag(tag, preformatted, config): def meta( - tag, distance=None, dirty=False, node=None, preformatted=False, config=None, **kw + tag, + distance=None, + dirty=False, + node=None, + preformatted=False, + branch=None, + config=None, + **kw ): if not config: warnings.warn( @@ -203,7 +212,9 @@ def meta( parsed_version = _parse_tag(tag, preformatted, config) trace("version", tag, "->", parsed_version) assert parsed_version is not None, "cant parse version %s" % tag - return ScmVersion(parsed_version, distance, node, dirty, preformatted, **kw) + return ScmVersion( + parsed_version, distance, node, dirty, preformatted, branch, config, **kw + ) def guess_next_version(tag_version): @@ -260,6 +271,25 @@ def simplified_semver_version(version): ) +def release_branch_semver(version): + if version.exact: + return version.format_with("{tag}") + if version.branch is not None: + # Does the branch name (stripped of namespace) parse as a version? + branch_ver = _parse_version_tag(version.branch.split("/")[-1], version.config) + if branch_ver is not None: + # Does the branch version up to the minor part match the tag? If not it + # might be like, an issue number or something and not a version number, so + # we only want to use it if it matches. + tag_ver_up_to_minor = str(version.tag).split(".")[:SEMVER_MINOR] + branch_ver_up_to_minor = branch_ver["version"].split(".")[:SEMVER_MINOR] + if branch_ver_up_to_minor == tag_ver_up_to_minor: + # We're in a release/maintenance branch, next is a patch/rc/beta bump: + return version.format_next_version(guess_next_version) + # We're in a development branch, next is a minor bump: + return version.format_next_version(guess_next_simple_semver, retain=SEMVER_MINOR) + + def _format_local_with_time(version, time_format): if version.exact or version.node is None: diff --git a/testing/test_version.py b/testing/test_version.py index 459d24b..3f2b10a 100644 --- a/testing/test_version.py +++ b/testing/test_version.py @@ -1,6 +1,11 @@ import pytest from setuptools_scm.config import Configuration -from setuptools_scm.version import meta, simplified_semver_version, tags_to_versions +from setuptools_scm.version import ( + meta, + simplified_semver_version, + release_branch_semver, + tags_to_versions, +) c = Configuration() @@ -44,6 +49,42 @@ def test_next_semver(version, expected_next): @pytest.mark.parametrize( + "version, expected_next", + [ + pytest.param(meta("1.0.0", config=c), "1.0.0", id="exact"), + pytest.param( + meta("1.0.0", distance=2, branch="master", config=c), + "1.1.0.dev2", + id="development_branch", + ), + pytest.param( + meta("1.0.0rc1", distance=2, branch="master", config=c), + "1.1.0.dev2", + id="development_branch_release_candidate", + ), + pytest.param( + meta("1.0.0", distance=2, branch="maintenance/1.0.x", config=c), + "1.0.1.dev2", + id="release_branch_legacy_version", + ), + pytest.param( + meta("1.0.0", distance=2, branch="release-1.0", config=c), + "1.0.1.dev2", + id="release_branch_with_prefix", + ), + pytest.param( + meta("1.0.0", distance=2, branch="bugfix/3434", config=c), + "1.1.0.dev2", + id="false_positive_release_branch", + ), + ], +) +def test_next_release_branch_semver(version, expected_next): + computed = release_branch_semver(version) + assert computed == expected_next + + +@pytest.mark.parametrize( "tag, expected", [ pytest.param("v1.0.0", "1.0.0"), |