From cb62961be00d1b1c8549f4a7e20759dfcee0b1c4 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Thu, 4 Dec 2025 10:45:36 -0800 Subject: [PATCH] Remove colors from log capture, and reset log every run --- aocsync.py | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/aocsync.py b/aocsync.py index 0ef7156..0f70dee 100755 --- a/aocsync.py +++ b/aocsync.py @@ -359,6 +359,27 @@ class GitManager: class CargoAOCRunner: """Runs cargo-aoc benchmarks and parses results""" + @staticmethod + def _strip_ansi_codes(text: str) -> str: + """Remove ANSI escape codes from text""" + import re + if not text: + return text + # Remove ANSI escape sequences - comprehensive pattern + # This pattern matches all ANSI escape codes including: + # - ESC[...m (SGR/color codes) + # - ESC[...K (EL codes) + # - ESC[...H (cursor positioning) + # - ESC[38;5;...m (256-color codes) + # - ESC[0m, ESC[1m, etc. + ansi_escape = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]') + # Also catch standalone ESC sequences + ansi_escape2 = re.compile(r'\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') + # Remove all ANSI codes + text = ansi_escape.sub('', text) + text = ansi_escape2.sub('', text) + return text + @staticmethod def find_implemented_days(work_dir: Path) -> List[int]: """Find which days are implemented in the directory @@ -533,6 +554,10 @@ class CargoAOCRunner: # Write to log file if provided if log_file: timestamp = datetime.now().isoformat() + # Strip ANSI codes from output before writing + stdout_clean = CargoAOCRunner._strip_ansi_codes(result.stdout or "") + stderr_clean = CargoAOCRunner._strip_ansi_codes(result.stderr or "") + with open(log_file, 'a', encoding='utf-8') as f: f.write(f"\n{'='*80}\n") f.write(f"[{timestamp}] {user} - Year {year} - Day {day}\n") @@ -540,13 +565,13 @@ class CargoAOCRunner: f.write(f"Working Directory: {work_dir}\n") f.write(f"Return Code: {result.returncode}\n") f.write(f"{'='*80}\n") - if result.stdout: + if result.stdout: # Check original, write cleaned version f.write("STDOUT:\n") - f.write(result.stdout) + f.write(stdout_clean) f.write("\n") - if result.stderr: + if result.stderr: # Check original, write cleaned version f.write("STDERR:\n") - f.write(result.stderr) + f.write(stderr_clean) f.write("\n") f.write(f"{'='*80}\n\n") @@ -558,9 +583,13 @@ class CargoAOCRunner: if not result.stdout.strip() and not result.stderr.strip(): logger.warning(f"No output from cargo aoc for {user} year {year} day {day}") + # Strip ANSI codes before parsing (for cleaner parsing) + stdout_clean = CargoAOCRunner._strip_ansi_codes(result.stdout or "") + stderr_clean = CargoAOCRunner._strip_ansi_codes(result.stderr or "") + # Parse output for runtime information day_results = CargoAOCRunner._parse_runtime_output( - result.stdout, result.stderr, day, year, user, git_rev, repo_url + stdout_clean, stderr_clean, day, year, user, git_rev, repo_url ) if day_results: logger.info(f"Parsed {len(day_results)} runtime result(s) for {user} year {year} day {day}") @@ -1852,6 +1881,15 @@ class AOCSync: """Sync all repositories""" logger.info("Starting sync of all repositories...") + # Clear log file at start of sync + log_file = Path(self.config.output_dir) / 'cargo-aoc.log' + log_file.parent.mkdir(parents=True, exist_ok=True) + # Clear the log file and write a header + with open(log_file, 'w', encoding='utf-8') as f: + f.write(f"{'#'*80}\n") + f.write(f"# Sync started at {datetime.now().isoformat()}\n") + f.write(f"{'#'*80}\n\n") + for repo_config in self.config.repositories: user_name = repo_config['name'] try: