import sys import argparse from typing import List, Optional from redminelib.resources import Issue from .config import Config from .client import fetch_issues_by_time_entries from .formatter import format_compact, format_table def parse_date_range(date_arg: str) -> tuple[str, str]: if "--" not in date_arg: raise ValueError("Date range must be in format YYYY-MM-DD--YYYY-MM-DD") parts = date_arg.split("--", 1) if len(parts) != 2: raise ValueError("Invalid date range format") return parts[0].strip(), parts[1].strip() def main(argv: Optional[List[str]] = None) -> int: parser = argparse.ArgumentParser( prog="redmine-reporter", description="Generate Redmine issue report based on your time entries." ) parser.add_argument( "--date", default=Config.get_default_date_range(), # help="Date range in format YYYY-MM-DD--YYYY-MM-DD (default: %(default)s)" help="Date range in format YYYY-MM-DD--YYYY-MM-DD (default from .env or %(default)s)" ) parser.add_argument( "--compact", action="store_true", help="Use compact plain-text output instead of table" ) args = parser.parse_args(argv) try: Config.validate() except ValueError as e: print(f"❌ Configuration error: {e}", file=sys.stderr) return 1 try: from_date, to_date = parse_date_range(args.date) except ValueError as e: print(f"❌ Date error: {e}", file=sys.stderr) return 1 try: issues = fetch_issues_by_time_entries(from_date, to_date) except Exception as e: print(f"❌ Redmine API error: {e}", file=sys.stderr) return 1 if issues is None: print("ℹ️ No time entries found in the given period.", file=sys.stderr) return 0 print(f"✅ Total issues: {len(issues)} [{args.date}]") try: if args.compact: output = format_compact(issues) else: output = format_table(issues) print(output) except Exception as e: print(f"❌ Formatting error: {e}", file=sys.stderr) return 1 return 0 if __name__ == "__main__": sys.exit(main())