From 7747d8a3280321c1ec2312aa9f09d9e37299c4b5 Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Mon, 3 May 2021 20:50:04 -0700 Subject: [PATCH] `show` command now uses color --- CHANGELOG.md | 4 +++ yaclog/changelog.py | 49 +++++++++++++++++++++++++---------- yaclog/cli/__main__.py | 58 +++++++++++++++++++++++++----------------- 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47368fa..02b0652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ All notable changes to this project will be documented in this file - `entry` with multiple `-b` options no longer add sub bullet points, instead adding each bullet as its own line. +### Added + +- Terminal output has color to distinguish version names/headers, sections, and git information + ## 0.3.3 - 2021-04-27 ### Added diff --git a/yaclog/changelog.py b/yaclog/changelog.py index fb20574..56082d6 100644 --- a/yaclog/changelog.py +++ b/yaclog/changelog.py @@ -21,6 +21,8 @@ import os import re from typing import List, Optional, Dict +import click # only for styling + import yaclog.markdown as markdown import yaclog.version @@ -114,11 +116,12 @@ class VersionEntry: self.sections[section].append(contents) - def body(self, md: bool = True) -> str: + def body(self, md: bool = True, color: bool = False) -> str: """ Get the version's body as a string - :param md: Whether or not to use markdown syntax in headings + :param md: Format headings as markdown + :param color: Add color codes to the string for display in a terminal :return: The formatted version body, without the version header """ @@ -127,27 +130,38 @@ class VersionEntry: for section, entries in self.sections.items(): if section: if md: - segments.append(f'### {section.title()}') + prefix = '### ' + title = section.title() else: - segments.append(f'{section.upper()}:') + prefix = '' + title = section.upper() + + if color: + prefix = click.style(prefix, fg='bright_black') + title = click.style(title, fg='cyan', bold=True) + + segments.append(prefix + title) if len(entries) > 0: segments += entries return markdown.join(segments) - def header(self, md: bool = True) -> str: + def header(self, md: bool = True, color: bool = False) -> str: """ Get the version's header as a string - :param md: Whether or not to use markdown syntax in headings + :param md: Format headings as markdown + :param color: Add color codes to the string for display in a terminal :return: The formatted version header """ - segments = [] - if md: - segments.append('##') + prefix = '## ' + else: + prefix = '' + + segments = [] if self.link and md: segments.append(f'[{self.name}]') @@ -162,18 +176,25 @@ class VersionEntry: segments += [f'[{t.upper()}]' for t in self.tags] - return ' '.join(segments) + title = ' '.join(segments) + + if color: + prefix = click.style(prefix, fg='bright_black') + title = click.style(title, fg='blue', bold=True) + + return prefix + title - def text(self, md: bool = True) -> str: + def text(self, md: bool = True, color: bool = False) -> str: """ Get the version's contents as a string - :param md: Whether or not to use markdown syntax in headings + :param md: Format headings as markdown + :param color: Add color codes to the string for display in a terminal :return: The formatted version header and body """ - contents = self.header(md) - body = self.body(md) + contents = self.header(md, color) + body = self.body(md, color) if body: contents += '\n\n' + body return contents diff --git a/yaclog/cli/__main__.py b/yaclog/cli/__main__.py index bf8d6dc..d82ba1b 100644 --- a/yaclog/cli/__main__.py +++ b/yaclog/cli/__main__.py @@ -87,7 +87,7 @@ def show(obj: Changelog, all_versions, markdown, str_func, version_names): except ValueError as v: raise click.ClickException(v) - kwargs = {'md': markdown} + kwargs = {'md': markdown, 'color': True} for v in versions: text = str_func(v, kwargs) @@ -122,17 +122,14 @@ 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() @cli.command(short_help='Add entries to the changelog.') -@click.option('--bullet', '-b', 'bullets', multiple=True, type=str, - help='Bullet points to add. ' - 'When multiple bullet points are provided, additional points are added as sub-points.') -@click.option('--paragraph', '-p', 'paragraphs', multiple=True, type=str, - help='Paragraphs to add') +@click.option('--bullet', '-b', 'bullets', multiple=True, type=str, help='Add a bullet point.') +@click.option('--paragraph', '-p', 'paragraphs', multiple=True, type=str, help='Add a paragraph') @click.argument('section_name', metavar='SECTION', type=str, default='', required=False) @click.argument('version_name', metavar='VERSION', type=str, default=None, required=False) @click.pass_obj @@ -161,6 +158,13 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name): version.add_entry('- ' + b, section_name) obj.write() + count = len(paragraphs) + len(bullets) + message = f"Created {count} {['entry', 'entries'][min(count - 1, 1)]}" + if section_name: + message += f" in section {click.style(section_name, fg='yellow')}" + if version.name.lower() != 'unreleased': + message += f" in version {click.style(version.name, fg='blue')}" + print(message) @cli.command(short_help='Release versions.') @@ -179,6 +183,9 @@ def entry(obj: Changelog, bullets, paragraphs, section_name, version_name): def release(obj: Changelog, version_name, rel_seg, pre_seg, commit): """Release versions in the changelog and increment their version numbers""" + if not (rel_seg or pre_seg or version_name or commit): + rel_seg = 2 # default to incrementing patch number I guess + cur_version = obj.current_version() old_name = cur_version.name @@ -197,47 +204,50 @@ def release(obj: Changelog, version_name, rel_seg, pre_seg, commit): if new_name != old_name: if yaclog.version.is_release(old_name): - click.confirm(f'Rename release version "{cur_version.name}" to "{new_name}"?', abort=True) + click.confirm( + f"Rename release version {click.style(old_name, fg='blue')} " + f"to {click.style(new_name, fg='blue')}?", + abort=True) cur_version.name = new_name cur_version.date = datetime.datetime.utcnow().date() obj.write() - print(f'Renamed version "{old_name}" to "{cur_version.name}".') + print(f"Renamed {click.style(old_name, fg='blue')} to {click.style(new_name, fg='blue')}") if commit: repo = git.Repo(os.curdir) if repo.bare: - raise click.BadOptionUsage('commit', f'Directory {os.path.abspath(os.curdir)} is not a git repo.') + raise click.BadOptionUsage('commit', f'Directory {os.path.abspath(os.curdir)} is not a git repo') repo.index.add(obj.path) - version_type = '' if yaclog.version.is_release(cur_version.name) else 'non-release ' tracked = len(repo.index.diff(repo.head.commit)) - tracked_warning = 'Create tag' untracked = len(repo.index.diff(None)) - untracked_warning = '' - untracked_plural = 's' if untracked > 1 else '' - if untracked > 0: - untracked_warning = click.style( - f' You have {untracked} untracked file{untracked_plural} that will not be included.', - fg='red', bold=True) - if tracked > 0: - tracked_warning = 'Commit and create tag' + message = [['Commit and create tag', 'Create tag'][min(tracked, 1)], 'for'] + + if not cur_version.released: + message.append('non-release') + + message.append(f"version {click.style(new_name, fg='blue')}?") + + if untracked > 0: + message.append(click.style( + f"You have {untracked} untracked file{'s'[:untracked]} that will not be included!", + fg='red', bold=True)) - click.confirm(f'{tracked_warning} for {version_type}version {cur_version.name}?{untracked_warning}', - abort=True) + click.confirm(' '.join(message), abort=True) if tracked > 0: commit = repo.index.commit(f'Version {cur_version.name}\n\n{cur_version.body()}') - print(f'Created commit {repo.head.commit.hexsha[0:7]}') + print(f"Created commit {click.style(repo.head.commit.hexsha[0:7], fg='green')}") else: commit = repo.head.commit repo_tag = repo.create_tag(cur_version.name, ref=commit, message=cur_version.body(False)) - print(f'Created tag "{repo_tag.name}".') + print(f"Created tag {click.style(repo_tag.name, fg='green')}.") if __name__ == '__main__':