mirror of
https://github.com/drewcassidy/yaclog.git
synced 2024-09-01 14:58:58 +00:00
yaclog show
and yaclog format
commands
This commit is contained in:
parent
6e75e15526
commit
157f49839f
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,6 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file
|
All notable changes to this project will be documented in this file
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `yaclog` tool for manipulating changelogs from the command line
|
||||||
|
- `init` command to make a new changelog
|
||||||
|
- `format` command to reformat the changelog
|
||||||
|
- `show` command to show changes from the changelog
|
||||||
|
|
||||||
## 0.2.0 - 2021-04-19
|
## 0.2.0 - 2021-04-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@ -12,8 +22,7 @@ All notable changes to this project will be documented in this file
|
|||||||
- Updated package metadata
|
- Updated package metadata
|
||||||
- Rewrote parser to use a 2-step method that is more flexible.
|
- Rewrote parser to use a 2-step method that is more flexible.
|
||||||
- Parser can now handle code blocks.
|
- Parser can now handle code blocks.
|
||||||
- Parser can now handle setext-style headers and H2s not conforming to the
|
- Parser can now handle setext-style headers and H2s not conforming to the schema.
|
||||||
schema.
|
|
||||||
|
|
||||||
## 0.1.0 - 2021-04-16
|
## 0.1.0 - 2021-04-16
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ def _join_markdown(segments: List[str]) -> str:
|
|||||||
text: List[str] = []
|
text: List[str] = []
|
||||||
last_bullet = False
|
last_bullet = False
|
||||||
for segment in segments:
|
for segment in segments:
|
||||||
is_bullet = bullet_regex.match(segment) and '\n' not in segment
|
is_bullet = bullet_regex.match(segment)
|
||||||
|
|
||||||
if not is_bullet or not last_bullet:
|
if not is_bullet or not last_bullet:
|
||||||
text.append('')
|
text.append('')
|
||||||
@ -76,7 +76,7 @@ class VersionEntry:
|
|||||||
for section, entries in self.sections.items():
|
for section, entries in self.sections.items():
|
||||||
if section:
|
if section:
|
||||||
if md:
|
if md:
|
||||||
segments.append(f'## {section.title()}')
|
segments.append(f'### {section.title()}')
|
||||||
else:
|
else:
|
||||||
segments.append(f'{section.upper()}:')
|
segments.append(f'{section.upper()}:')
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ class VersionEntry:
|
|||||||
return ' '.join(segments)
|
return ' '.join(segments)
|
||||||
|
|
||||||
def text(self, md: bool = True) -> str:
|
def text(self, md: bool = True) -> str:
|
||||||
return self.body(md) + '\n\n' + self.header(md)
|
return self.header(md) + '\n\n' + self.body(md)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.header(False)
|
return self.header(False)
|
||||||
@ -115,9 +115,9 @@ class VersionEntry:
|
|||||||
|
|
||||||
class Changelog:
|
class Changelog:
|
||||||
def __init__(self, path: os.PathLike = None):
|
def __init__(self, path: os.PathLike = None):
|
||||||
self.path = path
|
self.path: os.PathLike = path
|
||||||
self.header = ''
|
self.header: str = ''
|
||||||
self.versions = []
|
self.versions: List[VersionEntry] = []
|
||||||
self.links = {}
|
self.links = {}
|
||||||
|
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
@ -256,7 +256,6 @@ class Changelog:
|
|||||||
|
|
||||||
# strip whitespace from header
|
# strip whitespace from header
|
||||||
self.header = _join_markdown(header_segments)
|
self.header = _join_markdown(header_segments)
|
||||||
self.links = self.links
|
|
||||||
|
|
||||||
def write(self, path: os.PathLike = None):
|
def write(self, path: os.PathLike = None):
|
||||||
if path is None:
|
if path is None:
|
||||||
@ -274,7 +273,10 @@ class Changelog:
|
|||||||
v_links[version.name] = version.link
|
v_links[version.name] = version.link
|
||||||
|
|
||||||
fp.write(version.text())
|
fp.write(version.text())
|
||||||
fp.write('\n\n')
|
fp.write('\n')
|
||||||
|
|
||||||
|
if version != self.versions[-1] or len(v_links) > 0:
|
||||||
|
fp.write('\n')
|
||||||
|
|
||||||
for link_id, link in v_links.items():
|
for link_id, link in v_links.items():
|
||||||
fp.write(f'[{link_id.lower()}]: {link}\n')
|
fp.write(f'[{link_id.lower()}]: {link}\n')
|
||||||
|
@ -20,33 +20,68 @@ import os.path
|
|||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@click.option('--path', envvar='YACLOG_PATH', default='CHANGELOG.md',
|
@click.option('--path', envvar='YACLOG_PATH', default='CHANGELOG.md', show_default=True,
|
||||||
type=click.Path(dir_okay=False, writable=True, readable=True))
|
type=click.Path(dir_okay=False, writable=True, readable=True),
|
||||||
|
help='Location for the changelog file')
|
||||||
@click.version_option()
|
@click.version_option()
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def cli(ctx, path):
|
def cli(ctx, path):
|
||||||
ctx.obj = path
|
"""Manipulate markdown changelog files"""
|
||||||
|
|
||||||
if not (ctx.invoked_subcommand == 'init' or os.path.exists(path)):
|
if not (ctx.invoked_subcommand == 'init' or os.path.exists(path)):
|
||||||
# if the path doesnt exist, then ask if we can create it
|
# if the path doesnt exist, then ask if we can create it
|
||||||
if click.confirm(f'Changelog file {path} does not exist. Would you like to create it?'):
|
if click.confirm(f'Changelog file {path} does not exist. Would you like to create it?', abort=True):
|
||||||
ctx.invoke('init')
|
ctx.invoke('init')
|
||||||
else:
|
|
||||||
return
|
ctx.obj = yaclog.read(path)
|
||||||
|
|
||||||
|
|
||||||
@cli.command('init')
|
@cli.command()
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def init(ctx):
|
def init(ctx):
|
||||||
|
"""Create a new changelog file"""
|
||||||
path = ctx.parent.params['path']
|
path = ctx.parent.params['path']
|
||||||
|
|
||||||
if os.path.exists(path) and not click.confirm(
|
if os.path.exists(path):
|
||||||
f'Changelog file {path} already exists. Would you like to overwrite it?'):
|
click.confirm(f'Changelog file {path} already exists. Would you like to overwrite it?', abort=True)
|
||||||
return
|
|
||||||
|
|
||||||
yaclog.Changelog(path).write()
|
yaclog.Changelog(path).write()
|
||||||
print(f'Created new changelog file at {path}')
|
print(f'Created new changelog file at {path}')
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command('format')
|
||||||
|
@click.pass_obj
|
||||||
|
def reformat(obj: yaclog.Changelog):
|
||||||
|
"""Reformat the changelog file"""
|
||||||
|
obj.write()
|
||||||
|
print(f'Reformatted changelog file at {obj.path}')
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command(short_help='Show changes from the changelog file')
|
||||||
|
@click.option('--all', '-a', 'all_versions', is_flag=True, help='show all versions')
|
||||||
|
@click.argument('versions', type=str, nargs=-1)
|
||||||
|
@click.pass_obj
|
||||||
|
def show(obj: yaclog.Changelog, all_versions, versions):
|
||||||
|
"""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
|
||||||
|
else:
|
||||||
|
v_list = [obj.versions[0]]
|
||||||
|
|
||||||
|
for v in v_list:
|
||||||
|
click.echo(v.text())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
cli()
|
cli()
|
||||||
|
Loading…
Reference in New Issue
Block a user