diff --git a/grouped_run_statistics/src/grouped_run_statistics/cli.py b/grouped_run_statistics/src/grouped_run_statistics/cli.py new file mode 100644 index 0000000..27e404a --- /dev/null +++ b/grouped_run_statistics/src/grouped_run_statistics/cli.py @@ -0,0 +1,60 @@ +import argparse +import json +from pathlib import Path +from collections import defaultdict +from grouped_run_statistics.core import group_runs + + +def main(): + """CLI entrypoint for grouping run statistics based on pinned status.""" + parser = argparse.ArgumentParser(description="Group run data by pinned/unpinned status and generate aggregated statistics.") + parser.add_argument( + "--input", + type=str, + required=True, + help="Pfad zur Eingabedatei mit Run-Daten im JSON-Format." + ) + parser.add_argument( + "--output", + type=str, + required=True, + help="Pfad zur Ausgabedatei mit den gruppierten Statistikdaten im JSON-Format." + ) + + args = parser.parse_args() + + input_path = Path(args.input) + output_path = Path(args.output) + + if not input_path.exists(): + raise FileNotFoundError(f"Input file not found: {input_path}") + + with input_path.open("r", encoding="utf-8") as f: + try: + run_data = json.load(f) + except json.JSONDecodeError as e: + raise ValueError(f"Invalid JSON input: {e}") from e + + if not isinstance(run_data, list): + raise ValueError("Input JSON must be a list of run records.") + + # Validate minimal fields for data integrity + for idx, record in enumerate(run_data): + if not isinstance(record, dict): + raise ValueError(f"Run record at index {idx} is not a dictionary.") + required_keys = {"id", "pinned", "status"} + if not required_keys.issubset(record.keys()): + missing = required_keys - set(record.keys()) + raise ValueError(f"Run record {idx} missing required fields: {missing}") + + grouped_stats = group_runs(run_data) + + # Ensure output directory exists + output_path.parent.mkdir(parents=True, exist_ok=True) + + with output_path.open("w", encoding="utf-8") as f: + json.dump(grouped_stats, f, indent=2) + + +if __name__ == "__main__": + main()