mirror of
https://github.com/drewcassidy/yaclog.git
synced 2024-09-01 14:58:58 +00:00
use API in command line tools
This commit is contained in:
parent
6734cd3b32
commit
c43fc25eae
@ -4,8 +4,8 @@ import tempfile
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import yaclog
|
import yaclog
|
||||||
from yaclog.changelog import Changelog, VersionEntry
|
|
||||||
from tests.common import log, log_segments, log_text
|
from tests.common import log, log_segments, log_text
|
||||||
|
from yaclog.changelog import VersionEntry
|
||||||
|
|
||||||
|
|
||||||
class TestParser(unittest.TestCase):
|
class TestParser(unittest.TestCase):
|
||||||
|
@ -8,8 +8,8 @@ import yaclog.changelog
|
|||||||
from yaclog.cli.__main__ import cli
|
from yaclog.cli.__main__ import cli
|
||||||
|
|
||||||
|
|
||||||
def check_result(runner, result, expected=0):
|
def check_result(runner, result, success: bool = True):
|
||||||
runner.assertEqual(result.exit_code, expected, f'output: {result.output}\ntraceback: {result.exc_info}')
|
runner.assertEqual((result.exit_code == 0), success, f'output: {result.output}\ntraceback: {result.exc_info}')
|
||||||
|
|
||||||
|
|
||||||
class TestCreation(unittest.TestCase):
|
class TestCreation(unittest.TestCase):
|
||||||
@ -53,7 +53,7 @@ class TestCreation(unittest.TestCase):
|
|||||||
|
|
||||||
with runner.isolated_filesystem():
|
with runner.isolated_filesystem():
|
||||||
result = runner.invoke(cli, ['show'])
|
result = runner.invoke(cli, ['show'])
|
||||||
check_result(self, result, 1)
|
check_result(self, result, False)
|
||||||
self.assertIn('does not exist', result.output)
|
self.assertIn('does not exist', result.output)
|
||||||
|
|
||||||
|
|
||||||
@ -82,8 +82,7 @@ class TestTagging(unittest.TestCase):
|
|||||||
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
|
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
|
||||||
|
|
||||||
result = runner.invoke(cli, ['tag', 'tag3', '0.8.0'])
|
result = runner.invoke(cli, ['tag', 'tag3', '0.8.0'])
|
||||||
check_result(self, result, 2)
|
check_result(self, result, False)
|
||||||
self.assertIn('not found in changelog', result.output)
|
|
||||||
|
|
||||||
def test_tag_deletion(self):
|
def test_tag_deletion(self):
|
||||||
"""Test deleting tags from versions"""
|
"""Test deleting tags from versions"""
|
||||||
@ -103,15 +102,12 @@ class TestTagging(unittest.TestCase):
|
|||||||
in_log.write()
|
in_log.write()
|
||||||
|
|
||||||
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.8.0'])
|
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.8.0'])
|
||||||
check_result(self, result, 2)
|
check_result(self, result, False)
|
||||||
self.assertIn('not found in changelog', result.output)
|
|
||||||
|
|
||||||
result = runner.invoke(cli, ['tag', '-d', 'tag3', '0.9.0'])
|
result = runner.invoke(cli, ['tag', '-d', 'tag3', '0.9.0'])
|
||||||
check_result(self, result, 2)
|
check_result(self, result, False)
|
||||||
self.assertIn('not found in version', result.output)
|
|
||||||
|
|
||||||
result = runner.invoke(cli, ['tag', '-d', 'tag1'])
|
result = runner.invoke(cli, ['tag', '-d', 'tag1'])
|
||||||
self.assertNotIn('not found in version', result.output)
|
|
||||||
check_result(self, result)
|
check_result(self, result)
|
||||||
|
|
||||||
out_log = yaclog.read(location)
|
out_log = yaclog.read(location)
|
||||||
@ -119,7 +115,6 @@ class TestTagging(unittest.TestCase):
|
|||||||
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
|
self.assertEqual(out_log.versions[1].tags, ['TAG2'])
|
||||||
|
|
||||||
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.9.0'])
|
result = runner.invoke(cli, ['tag', '-d', 'tag2', '0.9.0'])
|
||||||
self.assertNotIn('not found in version', result.output)
|
|
||||||
check_result(self, result)
|
check_result(self, result)
|
||||||
|
|
||||||
out_log = yaclog.read(location)
|
out_log = yaclog.read(location)
|
||||||
|
@ -298,17 +298,18 @@ class Changelog:
|
|||||||
self.versions.insert(index, version := VersionEntry(*args, **kwargs))
|
self.versions.insert(index, version := VersionEntry(*args, **kwargs))
|
||||||
return version
|
return version
|
||||||
|
|
||||||
def current_version(self, released: Optional[bool] = None,
|
def current_version(self, released: Optional[bool] = None, new_version: bool = False,
|
||||||
new_version_name: str = 'Unreleased') -> Optional[VersionEntry]:
|
new_version_name: str = 'Unreleased') -> VersionEntry:
|
||||||
"""
|
"""
|
||||||
Get the current version entry from the changelog
|
Get the current version entry from the changelog
|
||||||
|
|
||||||
:param released: if the returned version should be a released version,
|
:param released: if the returned version should be a released version,
|
||||||
an unreleased version, or ``None`` to return the most recent
|
an unreleased version, or ``None`` to return the most recent
|
||||||
:param new_version_name: if unreleased versions are allowed, the name of
|
:param new_version: if a new version should be created if none exist.
|
||||||
the version to create if there are no matches
|
:param new_version_name: The name of the version to create if there
|
||||||
:return: The current version matching the criteria, or None if only
|
are no matches and ``new_version`` is True.
|
||||||
release versions are allowed and none are found.
|
: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`
|
# return the first version that matches `released`
|
||||||
@ -317,10 +318,13 @@ class Changelog:
|
|||||||
return version
|
return version
|
||||||
|
|
||||||
# fallback if none are found
|
# fallback if none are found
|
||||||
if released:
|
if new_version:
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return self.add_version(name=new_version_name)
|
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:
|
def get_version(self, name: Optional[str] = None) -> VersionEntry:
|
||||||
"""
|
"""
|
||||||
@ -333,7 +337,7 @@ class Changelog:
|
|||||||
for version in self.versions:
|
for version in self.versions:
|
||||||
if version.name == name or name is None:
|
if version.name == name or name is None:
|
||||||
return version
|
return version
|
||||||
raise IndexError()
|
raise KeyError(f'Version {name} not found in changelog')
|
||||||
|
|
||||||
def __getitem__(self, item: str) -> VersionEntry:
|
def __getitem__(self, item: str) -> VersionEntry:
|
||||||
return self.get_version(item)
|
return self.get_version(item)
|
||||||
|
@ -14,14 +14,14 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import click
|
|
||||||
import os.path
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import click
|
||||||
import git
|
import git
|
||||||
|
|
||||||
import yaclog.version
|
import yaclog.version
|
||||||
import yaclog.changelog
|
from yaclog.changelog import Changelog
|
||||||
from yaclog import Changelog
|
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@ -61,35 +61,44 @@ def reformat(obj: Changelog):
|
|||||||
|
|
||||||
@cli.command(short_help='Show changes from the changelog file')
|
@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.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
|
@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.
|
"""Show the changes for VERSIONS.
|
||||||
|
|
||||||
VERSIONS is a list of versions to print. If not given, the most recent version is used.
|
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
|
|
||||||
else:
|
|
||||||
v_list = [obj.versions[0]]
|
|
||||||
|
|
||||||
for v in v_list:
|
try:
|
||||||
click.echo(v.text(False))
|
if all_versions:
|
||||||
|
versions = obj.versions
|
||||||
|
elif len(version_names) == 0:
|
||||||
|
versions = [obj.current_version()]
|
||||||
|
else:
|
||||||
|
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 versions:
|
||||||
|
text = str_func(v, kwargs)
|
||||||
|
click.echo(text)
|
||||||
|
click.echo('\n')
|
||||||
|
|
||||||
|
|
||||||
@cli.command(short_help='Modify version tags')
|
@cli.command(short_help='Modify version tags')
|
||||||
@click.option('--add/--delete', '-a/-d', default=True, is_flag=True, help='Add or delete 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('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
|
@click.pass_obj
|
||||||
def tag(obj: Changelog, add, tag_name: str, version_name: str):
|
def tag(obj: Changelog, add, tag_name: str, version_name: str):
|
||||||
"""Modify TAG on VERSION.
|
"""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.
|
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()
|
tag_name = tag_name.upper()
|
||||||
|
try:
|
||||||
if version_name:
|
if version_name:
|
||||||
matches = [v for v in obj.versions if v.name == version_name]
|
version = obj.get_version(version_name)
|
||||||
if len(matches) == 0:
|
|
||||||
raise click.BadArgumentUsage(f'Version "{version_name}" not found in changelog.')
|
|
||||||
version = matches[0]
|
|
||||||
else:
|
else:
|
||||||
version = obj.versions[0]
|
version = obj.current_version()
|
||||||
|
except KeyError as k:
|
||||||
|
raise click.BadArgumentUsage(k)
|
||||||
|
except ValueError as v:
|
||||||
|
raise click.ClickException(v)
|
||||||
|
|
||||||
if add:
|
if add:
|
||||||
version.tags.append(tag_name)
|
version.tags.append(tag_name)
|
||||||
@ -111,7 +122,7 @@ def tag(obj: Changelog, add, tag_name: str, version_name: str):
|
|||||||
try:
|
try:
|
||||||
version.tags.remove(tag_name)
|
version.tags.remove(tag_name)
|
||||||
except ValueError:
|
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()
|
obj.write()
|
||||||
|
|
||||||
@ -135,24 +146,19 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
section_name = section_name.title()
|
section_name = section_name.title()
|
||||||
|
try:
|
||||||
if version_name:
|
if version_name:
|
||||||
matches = [v for v in obj.versions if v.name == version_name]
|
version = obj.get_version(version_name)
|
||||||
if len(matches) == 0:
|
|
||||||
raise click.BadArgumentUsage(f'Version "{version_name}" not found in changelog.')
|
|
||||||
version = matches[0]
|
|
||||||
else:
|
else:
|
||||||
matches = [v for v in obj.versions if v.name.lower() == 'unreleased']
|
version = obj.current_version(released=False, new_version=True)
|
||||||
if len(matches) == 0:
|
except KeyError as k:
|
||||||
version = yaclog.changelog.VersionEntry()
|
raise click.BadArgumentUsage(k)
|
||||||
obj.versions.insert(0, version)
|
|
||||||
else:
|
|
||||||
version = matches[0]
|
|
||||||
|
|
||||||
if section_name not in version.sections.keys():
|
if section_name not in version.sections.keys():
|
||||||
version.sections[section_name] = []
|
version.sections[section_name] = []
|
||||||
|
|
||||||
section = version.sections[section_name]
|
for p in paragraphs:
|
||||||
section += paragraphs
|
version.add_entry(p, section_name)
|
||||||
|
|
||||||
sub_bullet = False
|
sub_bullet = False
|
||||||
bullet_str = ''
|
bullet_str = ''
|
||||||
@ -166,7 +172,8 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name):
|
|||||||
|
|
||||||
bullet_str += bullet
|
bullet_str += bullet
|
||||||
sub_bullet = True
|
sub_bullet = True
|
||||||
section.append(bullet_str)
|
|
||||||
|
version.add_entry(bullet_str, section_name)
|
||||||
|
|
||||||
obj.write()
|
obj.write()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user