Improved `release` version handling

dev
Andrew Cassidy 3 years ago
parent 8394fbfd94
commit 7c638ad5fe

@ -6,8 +6,10 @@ All notable changes to this project will be documented in this file
### Changed ### Changed
- improved version header parsing - improved version header parsing to be more robust and handle multi-word version names.
- improved version number incrementing. It can now handle other text surrounding a pep440-compliant version number, which will not be modified - improved version number incrementing in `release`.
- can now handle other text surrounding a pep440-compliant version number, which will not be modified
- can now handle pre-releases correctly. The version to increment is the most recent version in the log with a valid pep440 version number in it. Release increment and prerelease increments can be mixed, allowing e.g: `yaclog release -mr` to create a release candidate with in incremented minor version number.
## 0.3.3 - 2021-04-27 ## 0.3.3 - 2021-04-27
@ -18,8 +20,7 @@ All notable changes to this project will be documented in this file
### Fixed ### Fixed
- Default links and dates in VersionEntry are now consistently `None` - Default links and dates in VersionEntry are now consistently `None`
- Changelog links dict now contains version links. - Changelog links dict now contains version links. Modified version links will overwrite those in the table when writing to a file
Modified version links will overwrite those in the table when writing to a file
- Changelog object no longer errors when creating without a path. - Changelog object no longer errors when creating without a path.
- `release` now resets lesser version values when incrementing - `release` now resets lesser version values when incrementing
- `release` now works with logs that have only unreleased changes - `release` now works with logs that have only unreleased changes

@ -138,7 +138,6 @@ class TestRelease(unittest.TestCase):
result = runner.invoke(cli, ['release', '--version', '1.0.0']) result = runner.invoke(cli, ['release', '--version', '1.0.0'])
check_result(self, result) check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '1.0.0') self.assertEqual(yaclog.read(location).versions[0].name, '1.0.0')
self.assertIn('Unreleased', result.output)
self.assertIn('1.0.0', result.output) self.assertIn('1.0.0', result.output)
runner.invoke(cli, ['entry', '-b', 'entry number 2']) runner.invoke(cli, ['entry', '-b', 'entry number 2'])
@ -146,7 +145,6 @@ class TestRelease(unittest.TestCase):
result = runner.invoke(cli, ['release', '-p']) result = runner.invoke(cli, ['release', '-p'])
check_result(self, result) check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '1.0.1') self.assertEqual(yaclog.read(location).versions[0].name, '1.0.1')
self.assertIn('Unreleased', result.output)
self.assertIn('1.0.1', result.output) self.assertIn('1.0.1', result.output)
runner.invoke(cli, ['entry', '-b', 'entry number 3']) runner.invoke(cli, ['entry', '-b', 'entry number 3'])
@ -154,7 +152,6 @@ class TestRelease(unittest.TestCase):
result = runner.invoke(cli, ['release', '-m']) result = runner.invoke(cli, ['release', '-m'])
check_result(self, result) check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '1.1.0') self.assertEqual(yaclog.read(location).versions[0].name, '1.1.0')
self.assertIn('Unreleased', result.output)
self.assertIn('1.1.0', result.output) self.assertIn('1.1.0', result.output)
runner.invoke(cli, ['entry', '-b', 'entry number 4']) runner.invoke(cli, ['entry', '-b', 'entry number 4'])
@ -162,9 +159,30 @@ class TestRelease(unittest.TestCase):
result = runner.invoke(cli, ['release', '-M']) result = runner.invoke(cli, ['release', '-M'])
check_result(self, result) check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '2.0.0') self.assertEqual(yaclog.read(location).versions[0].name, '2.0.0')
self.assertIn('Unreleased', result.output)
self.assertIn('2.0.0', result.output) self.assertIn('2.0.0', result.output)
runner.invoke(cli, ['entry', '-b', 'entry number 5'])
result = runner.invoke(cli, ['release', '-Ma'])
check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '3.0.0a1')
self.assertIn('3.0.0a1', result.output)
result = runner.invoke(cli, ['release', '-b'])
check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '3.0.0b1')
self.assertIn('3.0.0b1', result.output)
result = runner.invoke(cli, ['release', '-r'])
check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '3.0.0rc1')
self.assertIn('3.0.0rc1', result.output)
result = runner.invoke(cli, ['release', '-f'])
check_result(self, result)
self.assertEqual(yaclog.read(location).versions[0].name, '3.0.0')
self.assertIn('3.0.0', result.output)
def test_commit(self): def test_commit(self):
"""Test committing and tagging releases""" """Test committing and tagging releases"""
runner = CliRunner() runner = CliRunner()

@ -182,6 +182,10 @@ class VersionEntry:
def released(self): def released(self):
return yaclog.version.is_release(self.name) return yaclog.version.is_release(self.name)
@property
def version(self):
return yaclog.version.extract_version(self.name)[0]
def __str__(self) -> str: def __str__(self) -> str:
return self.header(False) return self.header(False)

@ -186,21 +186,26 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name):
@click.option('-a', '--alpha', 'pre_seg', flag_value='a', default=None, help='Increment alpha version number.') @click.option('-a', '--alpha', 'pre_seg', flag_value='a', default=None, help='Increment alpha version number.')
@click.option('-b', '--beta', 'pre_seg', flag_value='b', help='Increment beta version number.') @click.option('-b', '--beta', 'pre_seg', flag_value='b', help='Increment beta version number.')
@click.option('-r', '--rc', 'pre_seg', flag_value='rc', help='Increment release candidate version number.') @click.option('-r', '--rc', 'pre_seg', flag_value='rc', help='Increment release candidate version number.')
@click.option('-c', '--commit', is_flag=True, help='Create a git commit tagged with the new version number.') @click.option('-f', '--full', 'pre_seg', flag_value='', help='Clear the prerelease value creating a full release.')
@click.option('-c', '--commit', is_flag=True,
help='Create a git commit tagged with the new version number. '
'If there are no changes to commit, the current commit will be tagged instead.')
@click.pass_obj @click.pass_obj
def release(obj: Changelog, version_name, rel_seg, pre_seg, commit): def release(obj: Changelog, version_name, rel_seg, pre_seg, commit):
"""Release versions in the changelog and increment their version numbers""" """Release versions in the changelog and increment their version numbers"""
try:
version = obj.current_version(released=True).name
except ValueError:
version = '0.0.0'
cur_version = obj.current_version() cur_version = obj.current_version()
new_name = version
old_name = cur_version.name old_name = cur_version.name
if version_name: if version_name:
new_name = version_name new_name = version_name
else:
for v in obj.versions:
if v.version is not None:
new_name = v.name
break
else:
new_name = '0.0.0'
if rel_seg is not None or pre_seg is not None: if rel_seg is not None or pre_seg is not None:
new_name = yaclog.version.increment_version(new_name, rel_seg, pre_seg) new_name = yaclog.version.increment_version(new_name, rel_seg, pre_seg)

@ -41,7 +41,7 @@ def increment_version(version_str: str, rel_seg: int = None, pre_seg: str = None
:param version_str: The input string to manipulate :param version_str: The input string to manipulate
:param rel_seg: Which segment of the "release" value to increment, if any :param rel_seg: Which segment of the "release" value to increment, if any
:param pre_seg: Which kind of prerelease to use, if any :param pre_seg: Which kind of prerelease to use, if any. An empty string clears the prerelease field.
:return: The original string with the version number incremented :return: The original string with the version number incremented
""" """
v, *span = extract_version(version_str) v, *span = extract_version(version_str)
@ -56,12 +56,15 @@ def increment_version(version_str: str, rel_seg: int = None, pre_seg: str = None
if len(release) <= rel_seg: if len(release) <= rel_seg:
release += (0,) * (1 + rel_seg - len(release)) release += (0,) * (1 + rel_seg - len(release))
release = release[0:rel_seg] + (release[rel_seg] + 1,) + (0,) * (len(release) - rel_seg - 1) release = release[0:rel_seg] + (release[rel_seg] + 1,) + (0,) * (len(release) - rel_seg - 1)
pre = None
if pre_seg is not None: if pre_seg is not None:
if pre and pre[0] == pre_seg: if pre_seg == '': # full release, clear prerelease field
pre = None
elif pre and pre[0] == pre_seg: # increment current prerelease type
pre = (pre_seg, pre[1] + 1) pre = (pre_seg, pre[1] + 1)
else: else:
pre = (pre_seg, 1) pre = (pre_seg, 1) # set prerelease field
new_v = join_version(epoch, release, pre, post, dev, local) new_v = join_version(epoch, release, pre, post, dev, local)
return version_str[0:span[0]] + new_v + version_str[span[1]:] return version_str[0:span[0]] + new_v + version_str[span[1]:]

Loading…
Cancel
Save