Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c8a025c
add a failing test for prerelease increment
davidhyman Feb 26, 2019
e53ec58
add precommit definition
davidhyman Feb 26, 2019
866a728
add precommit hooks file
davidhyman Feb 26, 2019
bb03fd1
move to semver library
davidhyman Feb 27, 2019
53b00bf
Merge branch 'precommit' into semver-lib
davidhyman Feb 27, 2019
fa9d69e
move semver requirement to requirements.txt
davidhyman Feb 27, 2019
a174d86
fix a couple of issues (conflicting versions check was wrong)
davidhyman Feb 28, 2019
6c9506d
support for detecting newsfiles added since last release
davidhyman Feb 28, 2019
dfa6c7d
add ability to extract the names of file triggers
davidhyman Feb 28, 2019
c01877e
allow multiple sources
davidhyman Feb 28, 2019
8d36de2
fix bug where git was returning files relative to project root
davidhyman Mar 5, 2019
2fafb2f
major: invert news trigger config to allow many-one
davidhyman Apr 2, 2019
1de6a56
provide a persist-from for previous release
davidhyman Apr 3, 2019
49f1f97
add functions for comparing semvers
davidhyman Apr 3, 2019
024b435
oops, fix test for trigger config
davidhyman Apr 4, 2019
f84d77f
add previous-release comparison logic
davidhyman Apr 4, 2019
be5c24e
tests and code for correctly incrementing, given a previous release
davidhyman Apr 4, 2019
ab8aec8
use the right param name in the cli
davidhyman Apr 4, 2019
d418cc8
log which previous release was detected
davidhyman Apr 8, 2019
9659842
Merge branch 'better-candidate-flow' into fiveai_stable
davidhyman Apr 8, 2019
f83e1d1
minimum patch increment for an existing version
davidhyman Apr 10, 2019
5168fb7
add support for yaml/yml
davidhyman Apr 11, 2019
548df68
better yaml
davidhyman Apr 11, 2019
dea8a58
don't perform replacement if line key isn't used
davidhyman May 2, 2019
a20b380
'ancestor' tag lookup is more accurate
davidhyman May 23, 2019
eb5764f
match the 'incr_from_release' to the vcs mode (previous or latest)
davidhyman May 24, 2019
e719d54
move update strings into main. print the right version to stdout.
davidhyman Jun 11, 2019
1b2d2a5
fix the tag replacement placeholder
davidhyman Aug 7, 2020
06fefd2
add tests and further improve the regex
davidhyman Aug 7, 2020
b515395
Merge pull request #1 from fiveai/bugfix/bad-placeholder
davidhyman Aug 7, 2020
770dc0e
sync with public master
davidhyman Apr 21, 2021
2d6cce1
Merge branch 'master' into stuff
davidhyman Nov 25, 2021
51a5a01
partial deps upgrade (no functional changes) to semver lib 3.x
davidhyman Apr 21, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/news/ancestor.major
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Reworked the DVCS persistence to load from previous tags either globally, or previous to the current commit.
The CLI `--persist-from` options were renamed to accommodate this.
1 change: 1 addition & 0 deletions docs/news/incr-flow.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adds better workflow for incrementing patches.
2 changes: 2 additions & 0 deletions docs/news/infinite.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Adds the ability to have "infinite" newsfiles. They no longer require cleaning up, if tags are used to indicate releases.
This requires a workflow where releases are tagged in git, so we can determine the "new news".
2 changes: 2 additions & 0 deletions docs/news/inv-conf.major
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Breaking change to the config spec: the trigger_patterns are specified as pattern:sigfig
in order to support multiple file patterns for each significant figure
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
toml
semver~=2.13
semver==3.0.0.dev2
six
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from setuptools import setup

from setuptools import find_packages
from setuptools import setup

repository_dir = os.path.dirname(__file__)

Expand Down
8 changes: 4 additions & 4 deletions src/auto_version/auto_version_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ def main(
if set_to:
_LOG.debug("setting version directly: %s", set_to)
# parse it - validation failure will raise a ValueError
new_version = semver.parse_version_info(set_to)
new_version = semver.Version.parse(set_to)
if not lock:
warnings.warn(
"After setting version manually, does it need locking for a CI flow, to avoid an extraneous increment?",
Expand All @@ -463,8 +463,8 @@ def main(
current_semver, last_release_semver, triggers, **overrides
)

release_string = semver.finalize_version(str(new_version))
release_version = semver.parse_version_info(release_string)
release_version = new_version.finalize_version()
release_string = str(release_version)
if release:
new_version = release_version
updates[Constants.RELEASE_FIELD] = config.RELEASED_VALUE
Expand All @@ -475,7 +475,7 @@ def main(
updates[Constants.VERSION_STRICT_FIELD] = release_string

# write out the individual parts of the version
updates.update(new_version._asdict())
updates.update(new_version.to_dict())

# only rewrite a field that the user has specified in the configuration
source_file_updates = {
Expand Down
4 changes: 3 additions & 1 deletion src/auto_version/replacement_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ def __call__(self, match):
"""
original = match.string
key = match.group(Constants.KEY_GROUP)
replacement = self.params[key] # if there's nothing in the lookup, raise KeyError
replacement = self.params[
key
] # if there's nothing in the lookup, raise KeyError
start, end = match.span(Constants.VALUE_GROUP)
if start < 0:
# when there's a match but zero-length for the value group, we insert it at the end
Expand Down
52 changes: 30 additions & 22 deletions src/auto_version/tests/test_autoversion.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import contextlib
import functools
import imp
import os
import re
import shlex
import subprocess
import textwrap
import unittest

import semver
Expand Down Expand Up @@ -115,8 +115,21 @@ def test_increment_existing_prerelease(self):
def test_end_to_end(self):
self.call(bump="major")
filepath = os.path.join(os.path.dirname(__file__), "example.py")
example = imp.load_source("example", filepath)
self.assertEqual(example.VERSION, "20.0.0-dev.1")
with open(filepath) as fh:
content = fh.read()
self.assertEqual(
content,
textwrap.dedent(
"""
LOCK = False
RELEASE = True
VERSION = "20.0.0-dev.1"
VERSION_AGAIN = "20.0.0-dev.1"
STRICT_VERSION = "20.0.0"
UNRELATED_STRING = "apple"
"""
).lstrip(),
)

def test_simple_config_bump(self):
old, new, updates = self.call(config_path="simple.toml", bump="minor")
Expand Down Expand Up @@ -164,9 +177,9 @@ def test_bump_patch(self):

class TestUtils(unittest.TestCase):
def test_is_release(self):
self.assertTrue(utils.is_release(semver.parse_version_info("1.2.3")))
self.assertFalse(utils.is_release(semver.parse_version_info("1.2.3-RC.1")))
self.assertFalse(utils.is_release(semver.parse_version_info("1.2.3+abc")))
self.assertTrue(utils.is_release(semver.Version.parse("1.2.3")))
self.assertFalse(utils.is_release(semver.Version.parse("1.2.3-RC.1")))
self.assertFalse(utils.is_release(semver.Version.parse("1.2.3+abc")))

def test_sigfig_max(self):
self.assertEqual("minor", utils.max_sigfig(["minor", "patch"]))
Expand All @@ -188,20 +201,19 @@ def test_semver_diff(self):
self.assertEqual(
"minor",
utils.semver_diff(
semver.parse_version_info("1.2.3"), semver.parse_version_info("1.3.5")
semver.Version.parse("1.2.3"), semver.Version.parse("1.3.5")
),
)
self.assertEqual(
"patch",
utils.semver_diff(
semver.parse_version_info("1.2.3"),
semver.parse_version_info("1.2.4-RC.1"),
semver.Version.parse("1.2.3"), semver.Version.parse("1.2.4-RC.1")
),
)
self.assertEqual(
None,
utils.semver_diff(
semver.parse_version_info("1.2.3"), semver.parse_version_info("1.2.3")
semver.Version.parse("1.2.3"), semver.Version.parse("1.2.3")
),
)

Expand All @@ -215,14 +227,10 @@ def setUpClass(cls):
auto_version_tool.load_config(os.path.join(test_dir, "example.toml"))

def check(self, previous, current, bumps, expect):
previous = semver.parse_version_info(previous) if previous else None
previous = semver.Version.parse(previous) if previous else None
self.assertEqual(
expect,
str(
utils.make_new_semver(
semver.parse_version_info(current), previous, bumps
)
),
str(utils.make_new_semver(semver.Version.parse(current), previous, bumps)),
)

def test_release_bump(self):
Expand Down Expand Up @@ -289,7 +297,7 @@ def test_from_ancestor_version(self):
{
"VERSION": bumped,
"VERSION_AGAIN": bumped,
"STRICT_VERSION": semver.finalize_version(bumped),
"STRICT_VERSION": str(semver.Version.parse(bumped).finalize_version()),
},
)

Expand All @@ -303,7 +311,7 @@ def test_from_ancestor_release(self):
{
"VERSION": bumped,
"VERSION_AGAIN": bumped,
"STRICT_VERSION": semver.finalize_version(bumped),
"STRICT_VERSION": str(semver.Version.parse(bumped).finalize_version()),
},
)

Expand All @@ -315,7 +323,7 @@ def test_from_latest_of_all_time(self):
{
"VERSION": bumped,
"VERSION_AGAIN": bumped,
"STRICT_VERSION": semver.finalize_version(bumped),
"STRICT_VERSION": str(semver.Version.parse(bumped).finalize_version()),
},
)

Expand All @@ -327,7 +335,7 @@ def test_from_latest_of_all_time_release(self):
{
"VERSION": bumped,
"VERSION_AGAIN": bumped,
"STRICT_VERSION": semver.finalize_version(bumped),
"STRICT_VERSION": str(semver.Version.parse(bumped).finalize_version()),
},
)

Expand All @@ -348,12 +356,12 @@ def test_to_tag(self):
{
"VERSION": bumped,
"VERSION_AGAIN": bumped,
"STRICT_VERSION": semver.finalize_version(bumped),
"STRICT_VERSION": str(semver.Version.parse(bumped).finalize_version()),
},
)
version = auto_version_tool.get_dvcs_repo_latest_version_semver()
self.assertEqual(
dict(version._asdict()),
dict(version.to_dict()),
dict(major=5, minor=0, patch=0, build=None, prerelease="dev.1"),
)

Expand Down
41 changes: 24 additions & 17 deletions src/auto_version/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def from_text_or_none(text):
"""
if text is not None:
try:
return semver.parse_version_info(text)
return semver.Version.parse(text)
except ValueError:
_LOG.debug("version string is not semver-compatible: %r", text)
pass
Expand Down Expand Up @@ -46,24 +46,28 @@ def get_semver_from_source(data):
# we didn't have enough components
pass

versions = [potential for potential in potentials if from_text_or_none(potential)]
release_versions = {semver.finalize_version(version) for version in versions}
actual_versions = []
for potential in potentials:
version = from_text_or_none(potential)
if version:
actual_versions.append(version)
release_versions = {version.finalize_version() for version in actual_versions}

if len(release_versions) > 1:
raise ValueError(
"conflicting versions within project: %s\nkeys were: %r"
% (release_versions, known)
)

if not versions:
if not actual_versions:
_LOG.debug("key pairs found: \n%r", known)
raise ValueError("could not find existing semver")

result = None
if versions:
result = versions[0]
if actual_versions:
result = actual_versions[0]
_LOG.info("latest version found in source: %r", result)
return semver.parse_version_info(result)
return result


def get_token_args(sig_fig):
Expand All @@ -84,7 +88,9 @@ def max_sigfig(sigfigs):

def min_sigfig(sigfigs):
"""Given a list of significant figures, return the smallest"""
for sig_fig in reversed(SemVerSigFig): # iterate sig figs in order of least significance
for sig_fig in reversed(
SemVerSigFig
): # iterate sig figs in order of least significance
if sig_fig in sigfigs:
return sig_fig

Expand Down Expand Up @@ -120,13 +126,15 @@ def make_new_semver(current_semver, last_release_semver, all_triggers, **overrid
:param overrides: explicit values for some or all of the sigfigs
:return:
"""
version_string = str(current_semver)
proposed_version = current_semver

# if the current version isn't a full release
if not is_release(current_semver) and last_release_semver:
# we check to see how important the changes are
# in the triggers, compared to the changes made between the current version and previous release
if sigfig_gt(max_sigfig(all_triggers), semver_diff(current_semver, last_release_semver)):
if sigfig_gt(
max_sigfig(all_triggers), semver_diff(current_semver, last_release_semver)
):
# here, the changes are more significant than the original RC bump, so we re-bump
pass
else:
Expand All @@ -142,23 +150,22 @@ def make_new_semver(current_semver, last_release_semver, all_triggers, **overrid

if bump_sigfig:
# perform an increment using the most-significant trigger
version_string = getattr(semver, "bump_" + bump_sigfig)(
str(current_semver), **get_token_args(bump_sigfig)
proposed_version = getattr(current_semver, "bump_" + bump_sigfig)(
**get_token_args(bump_sigfig)
)

if sigfig_gt(bump_sigfig, SemVerSigFig.prerelease):
# if we *didnt* increment sub-patch already, then we should do so
# this provides the "devmode template" as previously
# and ensures a simple 'bump' doesn't look like a full release
version_string = semver.bump_prerelease(
version_string, token=config.PRERELEASE_TOKEN
proposed_version = proposed_version.bump_prerelease(
token=config.PRERELEASE_TOKEN
)

# perform any explicit setting of sigfigs
version_info = semver.parse_version_info(version_string)
for k, v in overrides.items():
token_args = get_token_args(k)
prefix = list(token_args.values()).pop() + "." if token_args else ""
setattr(version_info, "_" + k, prefix + str(v))
setattr(proposed_version, "_" + k, prefix + str(v))

return version_info
return proposed_version