use API in command line tools

dev
Andrew Cassidy 3 years ago
parent 6734cd3b32
commit c43fc25eae

@ -4,8 +4,8 @@ import tempfile
import unittest
import yaclog
from yaclog.changelog import Changelog, VersionEntry
from tests.common import log, log_segments, log_text
from yaclog.changelog import VersionEntry
class TestParser(unittest.TestCase):

@ -8,8 +8,8 @@ import yaclog.changelog
from yaclog.cli.__main__ import cli
def check_result(runner, result, expected=0):
runner.assertEqual(result.exit_code, expected, f'output: {result.output}\ntraceback: {result.exc_info}')
def check_result(runner, result, success: bool = True):
runner.assertEqual((result.exit_code == 0), success, f'output: {result.output}\ntraceback: {result.exc_info}')
class TestCreation(unittest.TestCase):
@ -53,7 +53,7 @@ class TestCreation(unittest.TestCase):
with runner.isolated_filesystem():
result = runner.invoke(cli, ['show'])
check_result(self, result, 1)
check_result(self, result, False)
self.assertIn('does not exist', result.output)
@ -82,8 +82,7 @@ class TestTagging(unittest.TestCase):
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
result = runner.invoke(cli, ['tag', 'tag3', '0.8.0'])
check_result(self, result, 2)
self.assertIn('not found in changelog', result.output)
check_result(self, result, False)
def test_tag_deletion(self):
"""Test deleting tags from versions"""
@ -103,15 +102,12 @@ class TestTagging(unittest.TestCase):
in_log.write()
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.8.0'])
check_result(self, result, 2)
self.assertIn('not found in changelog', result.output)
check_result(self, result, False)
result = runner.invoke(cli, ['tag', '-d', 'tag3', '0.9.0'])
check_result(self, result, 2)
self.assertIn('not found in version', result.output)
check_result(self, result, False)
result = runner.invoke(cli, ['tag', '-d', 'tag1'])
self.assertNotIn('not found in version', result.output)
check_result(self, result)
out_log = yaclog.read(location)
@ -119,7 +115,6 @@ class TestTagging(unittest.TestCase):
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.9.0'])
self.assertNotIn('not found in version', result.output)
check_result(self, result)
out_log = yaclog.read(location)

@ -298,17 +298,18 @@ class Changelog:
self.versions.insert(index, version := VersionEntry(*args, **kwargs))
return version
def current_version(self, released: Optional[bool] = None,
new_version_name: str = 'Unreleased') -> Optional[VersionEntry]:
def current_version(self, released: Optional[bool] = None, new_version: bool = False,
new_version_name: str = 'Unreleased') -> VersionEntry:
"""
Get the current version entry from the changelog
:param released: if the returned version should be a released version,
an unreleased version, or ``None`` to return the most recent
:param new_version_name: if unreleased versions are allowed, the name of
the version to create if there are no matches
:return: The current version matching the criteria, or None if only
release versions are allowed and none are found.
:param new_version: if a new version should be created if none exist.
:param new_version_name: The name of the version to create if there
are no matches and ``new_version`` is True.
:return: The current version matching the criteria,
or None if ``new_version`` is disabled and none are found.
"""
# return the first version that matches `released`
@ -317,10 +318,13 @@ class Changelog:
return version
# fallback if none are found
if released:
return None
else:
if new_version:
return self.add_version(name=new_version_name)
else:
if released is not None:
raise ValueError(f'Changelog has no current version matching released={released}')
else:
raise ValueError('Changelog has no current version')
def get_version(self, name: Optional[str] = None) -> VersionEntry:
"""
@ -333,7 +337,7 @@ class Changelog:
for version in self.versions:
if version.name == name or name is None:
return version
raise IndexError()
raise KeyError(f'Version {name} not found in changelog')
def __getitem__(self, item: str) -> VersionEntry:
return self.get_version(item)

@ -14,14 +14,14 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import click
import os.path
import datetime
import os.path
import click
import git
import yaclog.version
import yaclog.changelog
from yaclog import Changelog
from yaclog.changelog import Changelog
@click.group()
@ -61,35 +61,44 @@ def reformat(obj: Changelog):
@cli.command(short_help='Show changes from the changelog file')
@click.option('--all', '-a', 'all_versions', is_flag=True, help='Show the entire changelog.')
@click.argument('versions', type=str, nargs=-1)
@click.option('--markdown/--txt', '-m/-t', default=False, help='Display as markdown or plain text.')
@click.option('--full', '-f', 'str_func', flag_value=lambda v, k: v.text(**k), default=True,
help='Show version header and body.')
@click.option('--name', '-n', 'str_func', flag_value=lambda v, k: v.name, help='Show only the version name')
@click.option('--body', '-b', 'str_func', flag_value=lambda v, k: v.body(**k), help='Show only the version body.')
@click.option('--header', '-h', 'str_func', flag_value=lambda v, k: v.header(**k), help='Show only the version header.')
@click.argument('version_names', metavar='VERSIONS', type=str, nargs=-1)
@click.pass_obj
def show(obj: Changelog, all_versions, versions):
def show(obj: Changelog, all_versions, markdown, str_func, version_names):
"""Show the changes for VERSIONS.
VERSIONS is a list of versions to print. If not given, the most recent version is used.
"""
if all_versions:
with open(obj.path, 'r') as fp:
click.echo_via_pager(fp.read())
else:
if len(versions):
v_list = []
for v_name in versions:
matches = [v for v in obj.versions if v.name == v_name]
if len(matches) == 0:
raise click.BadArgumentUsage(f'Version "{v_name}" not found in changelog.')
v_list += matches
try:
if all_versions:
versions = obj.versions
elif len(version_names) == 0:
versions = [obj.current_version()]
else:
v_list = [obj.versions[0]]
versions = [obj.get_version(name) for name in version_names]
except KeyError as k:
raise click.BadArgumentUsage(k)
except ValueError as v:
raise click.ClickException(v)
kwargs = {'md': markdown}
for v in v_list:
click.echo(v.text(False))
for v in versions:
text = str_func(v, kwargs)
click.echo(text)
click.echo('\n')
@cli.command(short_help='Modify version tags')
@click.option('--add/--delete', '-a/-d', default=True, is_flag=True, help='Add or delete tags')
@click.argument('tag_name', metavar='tag', type=str)
@click.argument('version_name', metavar='version', type=str, required=False)
@click.argument('version_name', metavar='VERSION', type=str, required=False)
@click.pass_obj
def tag(obj: Changelog, add, tag_name: str, version_name: str):
"""Modify TAG on VERSION.
@ -97,13 +106,15 @@ def tag(obj: Changelog, add, tag_name: str, version_name: str):
VERSION is the name of a version to add tags to. If not given, the most recent version is used.
"""
tag_name = tag_name.upper()
if version_name:
matches = [v for v in obj.versions if v.name == version_name]
if len(matches) == 0:
raise click.BadArgumentUsage(f'Version "{version_name}" not found in changelog.')
version = matches[0]
else:
version = obj.versions[0]
try:
if version_name:
version = obj.get_version(version_name)
else:
version = obj.current_version()
except KeyError as k:
raise click.BadArgumentUsage(k)
except ValueError as v:
raise click.ClickException(v)
if add:
version.tags.append(tag_name)
@ -111,7 +122,7 @@ def tag(obj: Changelog, add, tag_name: str, version_name: str):
try:
version.tags.remove(tag_name)
except ValueError:
raise click.BadArgumentUsage(f'Tag "{tag_name}" not found in version "{version.name}".')
raise click.BadArgumentUsage(f'Tag {tag_name} not found in version {version.name}.')
obj.write()
@ -135,24 +146,19 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name):
"""
section_name = section_name.title()
if version_name:
matches = [v for v in obj.versions if v.name == version_name]
if len(matches) == 0:
raise click.BadArgumentUsage(f'Version "{version_name}" not found in changelog.')
version = matches[0]
else:
matches = [v for v in obj.versions if v.name.lower() == 'unreleased']
if len(matches) == 0:
version = yaclog.changelog.VersionEntry()
obj.versions.insert(0, version)
try:
if version_name:
version = obj.get_version(version_name)
else:
version = matches[0]
version = obj.current_version(released=False, new_version=True)
except KeyError as k:
raise click.BadArgumentUsage(k)
if section_name not in version.sections.keys():
version.sections[section_name] = []
section = version.sections[section_name]
section += paragraphs
for p in paragraphs:
version.add_entry(p, section_name)
sub_bullet = False
bullet_str = ''
@ -166,7 +172,8 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name):
bullet_str += bullet
sub_bullet = True
section.append(bullet_str)
version.add_entry(bullet_str, section_name)
obj.write()

Loading…
Cancel
Save