<commit_before>"""Interact with Backlogs on the command line."""

import os

import click

import backlog


@click.group(invoke_without_command=True)
@click.option(
    '--path',
    type=click.Path(),
    help='Specify the path to use for the backlog file.',
    default=os.path.join(os.path.expanduser('~'), '.backlog.json'),
)
@click.version_option(version=backlog.__version__)
@click.pass_context
def main(ctx, path: str) -> None:
    """Manage a Backlog."""
    ctx.obj = {
        'backlog': (
            backlog.Backlog.load(path)
            if os.path.isfile(path) else
            backlog.Backlog()
        ),
        'path': path,
    }
    if ctx.invoked_subcommand is None:
        ctx.invoke(show)


@main.command()
@click.option(
    '--note',
    type=str,
    help='Add a note.',
    default='',
)
@click.option(
    '--priority',
    type=int,
    help='Specify a priority level.',
    default=1,
)
@click.argument('title', type=str)
@click.pass_context
def add(ctx, title: str, note: str, priority: int) -> None:
    """Add an entry to the backlog."""
    ctx.obj['backlog'].entries.append(
        backlog.Backlog.Entry(
            note=note,
            priority=priority,
            title=title,
        ),
    )
    ctx.obj['backlog'].save(ctx.obj['path'])


@main.command()
@click.pass_context
def random(ctx) -> None:
    """Select a random entry from the backlog."""
    click.echo(ctx.obj['backlog'].random())


@main.command()
@click.option(
    '--ask/--dont-ask',
    help='Prompt before deleting.',
    default=True,
)
@click.argument('pattern', type=str)
@click.pass_context
def remove(ctx, pattern: str, ask: bool) -> None:
    """Remove entries from the backlog."""
    entries = list(ctx.obj['backlog'].search(pattern))
    click.echo(entries)
    if entries:
        if not ask or click.confirm(
                'delete {0} entries?'.format(len(entries)),
        ):
            backlog.Backlog(
                entries=list(ctx.obj['backlog'].search(pattern, invert=True)),
            ).save(ctx.obj['path'])


@main.command()
@click.option(
    '--pattern',
    type=str,
    help='Specify a search pattern for entry titles.',
    default='.*',
)
@click.pass_context
def show(ctx, pattern: str) -> None:
    """Show entries in the backlog."""
    entries = list(ctx.obj['backlog'].search(pattern))
    click.echo('total {}'.format(len(entries)))
    if entries:
        click.echo(backlog.Backlog(entries=entries))<commit_msg>Explicitly call str before invoking click.echo<commit_after>"""Interact with Backlogs on the command line."""

import os

import click

import backlog


@click.group(invoke_without_command=True)
@click.option(
    '--path',
    type=click.Path(),
    help='Specify the path to use for the backlog file.',
    default=os.path.join(os.path.expanduser('~'), '.backlog.json'),
)
@click.version_option(version=backlog.__version__)
@click.pass_context
def main(ctx, path: str) -> None:
    """Manage a Backlog."""
    ctx.obj = {
        'backlog': (
            backlog.Backlog.load(path)
            if os.path.isfile(path) else
            backlog.Backlog()
        ),
        'path': path,
    }
    if ctx.invoked_subcommand is None:
        ctx.invoke(show)


@main.command()
@click.option(
    '--note',
    type=str,
    help='Add a note.',
    default='',
)
@click.option(
    '--priority',
    type=int,
    help='Specify a priority level.',
    default=1,
)
@click.argument('title', type=str)
@click.pass_context
def add(ctx, title: str, note: str, priority: int) -> None:
    """Add an entry to the backlog."""
    ctx.obj['backlog'].entries.append(
        backlog.Backlog.Entry(
            note=note,
            priority=priority,
            title=title,
        ),
    )
    ctx.obj['backlog'].save(ctx.obj['path'])


@main.command()
@click.pass_context
def random(ctx) -> None:
    """Select a random entry from the backlog."""
    entry = ctx.obj['backlog'].random()
    if entry:
        click.echo(str(entry))


@main.command()
@click.option(
    '--ask/--dont-ask',
    help='Prompt before deleting.',
    default=True,
)
@click.argument('pattern', type=str)
@click.pass_context
def remove(ctx, pattern: str, ask: bool) -> None:
    """Remove entries from the backlog."""
    entries = list(ctx.obj['backlog'].search(pattern))
    click.echo(str(backlog.Backlog(entries=entries)))
    if entries:
        if not ask or click.confirm(
                'delete {0} entries?'.format(len(entries)),
        ):
            backlog.Backlog(
                entries=list(ctx.obj['backlog'].search(pattern, invert=True)),
            ).save(ctx.obj['path'])


@main.command()
@click.option(
    '--pattern',
    type=str,
    help='Specify a search pattern for entry titles.',
    default='.*',
)
@click.pass_context
def show(ctx, pattern: str) -> None:
    """Show entries in the backlog."""
    entries = list(ctx.obj['backlog'].search(pattern))
    click.echo(f'total {len(entries)}')
    if entries:
        click.echo(str(backlog.Backlog(entries=entries)))
{'fraction_non_alphanumeric': 0.16636887035934086, 'fraction_numerical': 0.0007941234862021044, 'mean_word_length': 2.8282674772036476, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7204740', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1620, 'n_words': 356}