diff --git a/run.py b/run.py index 05610bd..0eac34d 100755 --- a/run.py +++ b/run.py @@ -667,10 +667,10 @@ def run(lang: str, testcase: tuple[str, ...], verbose: bool): if verbose: click.secho("===" * 3, fg="bright_black") - click.secho(f"[INPUT]", fg="cyan", bold=True) + click.secho("[INPUT]", fg="cyan", bold=True) with open(f_in_path, "r") as f: click.echo(f.read()) - click.secho(f"[ACTUAL]", fg="cyan", bold=True) + click.secho("[ACTUAL]", fg="cyan", bold=True) click.echo(stdout.strip() if stdout else "(empty)") click.secho("===" * 3, fg="bright_black") @@ -1018,6 +1018,62 @@ def find(filter_: str, completed: bool | None): click.echo(f" {status} {file_name}.{lang_name}") +@click.command(name="version") +def version(): + """Show version information.""" + click.echo(f"CodeObject version {__version__}") + + +@click.command(name="status") +def status(): + """Show storage statistics.""" + all_entries = StorageManager().list_entries() + + if not all_entries: + click.echo("No problems in storage.") + return + + stats: dict[str, dict[str, dict[str, int]]] = {} + for loc, lang, _, is_completed in all_entries: + if loc not in stats: + stats[loc] = {} + if lang not in stats[loc]: + stats[loc][lang] = {"total": 0, "completed": 0} + stats[loc][lang]["total"] += 1 + if is_completed: + stats[loc][lang]["completed"] += 1 + + total_problems = len(all_entries) + total_completed = sum(1 for _, _, _, c in all_entries if c) + + click.secho("Storage Status", fg="cyan", bold=True) + click.echo() + + for loc_name, langs in sorted(stats.items()): + loc_total = sum(c["total"] for c in langs.values()) + loc_completed = sum(c["completed"] for c in langs.values()) + loc_uncompleted = loc_total - loc_completed + click.secho(f"[{loc_name}]", fg="green", bold=True, nl=False) + click.secho(f" {loc_total}", fg="yellow", bold=False, nl=False) + click.secho(" (", fg="white", bold=False, nl=False) + click.secho(f"{loc_completed}", fg="green", bold=False, nl=False) + click.secho(" completed, ", fg="cyan", bold=False, nl=False) + click.secho(f"{loc_uncompleted}", fg="red", bold=False, nl=False) + click.secho(" not completed", fg="cyan", bold=False, nl=False) + click.secho(")", fg="white", bold=False) + for lang_name, counts in sorted(langs.items()): + click.echo( + f" {lang_name}: {counts['completed']}/{counts['total']}" + ) + click.echo() + + click.secho( + f"Total: {total_problems} (completed: {total_completed}, " + f"uncompleted: {total_problems - total_completed})", + fg="cyan", + ) + + @click.command(name="fetchprob") @click.argument("target", type=str, nargs=1, required=True) @click.option("--force", "-f", is_flag=True, help="Overwrite existing static files") @@ -1036,6 +1092,8 @@ cli.add_command(export) cli.add_command(state) cli.add_command(show) cli.add_command(find) +cli.add_command(version) +cli.add_command(status) cli.add_command(fetchprob) if __name__ == "__main__":