diff --git a/codewiki/src/be/dependency_analyzer/analysis/analysis_service.py b/codewiki/src/be/dependency_analyzer/analysis/analysis_service.py index 2d8eb11d..ed07fc69 100644 --- a/codewiki/src/be/dependency_analyzer/analysis/analysis_service.py +++ b/codewiki/src/be/dependency_analyzer/analysis/analysis_service.py @@ -252,18 +252,6 @@ def _analyze_structure( def _read_readme_file(self, repo_dir: str) -> Optional[str]: """Find and read the README file from the repository root.""" - # possible_readme_names = ["README.md", "README", "readme.md", "README.txt"] - # for name in possible_readme_names: - # readme_path = Path(repo_dir) / name - # if readme_path.exists(): - # try: - # logger.debug(f"Found README file at {readme_path}") - # return readme_path.read_text(encoding="utf-8") - # except Exception as e: - # logger.warning(f"Could not read README file at {readme_path}: {e}") - # return None - # logger.debug("No README file found in repository root.") - # return None base = Path(repo_dir) possible_readme_names = ["README.md", "README", "readme.md", "README.txt"] for name in possible_readme_names: @@ -396,3 +384,4 @@ def analyze_repository_structure_only( github_url, include_patterns, exclude_patterns ) return result, None + diff --git a/codewiki/src/be/flamingo_guidelines.py b/codewiki/src/be/flamingo_guidelines.py index 8014a8c5..155e874d 100644 --- a/codewiki/src/be/flamingo_guidelines.py +++ b/codewiki/src/be/flamingo_guidelines.py @@ -13,8 +13,11 @@ prompt = f"{get_custom_instructions_section()}{get_guidelines_section()}Your actual prompt here..." """ import os +import logging from pathlib import Path +logger = logging.getLogger(__name__) + GUIDELINES_ENV_VAR = "FLAMINGO_MARKDOWN_GUIDELINES_PATH" CUSTOM_INSTRUCTIONS_ENV_VAR = "CUSTOM_REPO_INSTRUCTIONS" VALIDATION_RULES_ENV_VAR = "VALIDATION_RULES_PATH" @@ -34,20 +37,20 @@ def load_flamingo_guidelines() -> str: guidelines_path = os.environ.get(GUIDELINES_ENV_VAR) if not guidelines_path: - print(f"[CodeWiki] {GUIDELINES_ENV_VAR} not set - continuing without Flamingo guidelines") + logger.info(f"{GUIDELINES_ENV_VAR} not set - continuing without Flamingo guidelines") return "" try: path = Path(guidelines_path) if not path.exists(): - print(f"[CodeWiki] Guidelines file not found: {guidelines_path}") + logger.warning(f"Guidelines file not found: {guidelines_path}") return "" content = path.read_text(encoding='utf-8') - print(f"[CodeWiki] Loaded Flamingo markdown guidelines ({len(content)} chars)") + logger.info(f"Loaded Flamingo markdown guidelines ({len(content)} chars)") return content except Exception as e: - print(f"[CodeWiki] Failed to load guidelines: {e}") + logger.error(f"Failed to load guidelines: {e}") return "" @@ -75,12 +78,12 @@ def sanitize_problematic_patterns(text: str) -> str: """ import re - print(f"[DEBUG] sanitize_problematic_patterns called - input length: {len(text)}") + logger.debug(f"sanitize_problematic_patterns called - input length: {len(text)}") # Count braces before sanitization open_count_before = text.count('{') close_count_before = text.count('}') - print(f"[DEBUG] BEFORE: {{ count={open_count_before}, }} count={close_count_before}") + logger.debug(f" BEFORE: {{ count={open_count_before}, }} count={close_count_before}") # 1. GitHub Actions syntax: ${{...}} → ${...} # Use iterative approach for robustness with nested braces @@ -104,8 +107,8 @@ def sanitize_problematic_patterns(text: str) -> str: # Count braces after sanitization open_count_after = text.count('{') close_count_after = text.count('}') - print(f"[DEBUG] AFTER: {{ count={open_count_after}, }} count={close_count_after}") - print(f"[DEBUG] Sample (first 200 chars): {text[:200]}") + logger.debug(f" AFTER: {{ count={open_count_after}, }} count={close_count_after}") + logger.debug(f" Sample (first 200 chars): {text[:200]}") return text @@ -146,7 +149,7 @@ def sanitize_and_escape_format_braces(text: str) -> str: """ import re - print(f"[DEBUG] sanitize_and_escape_format_braces called - input length: {len(text)}") + logger.debug(f"sanitize_and_escape_format_braces called - input length: {len(text)}") # STEP 1: SANITIZATION (if not already done) # This ensures problematic patterns are normalized before we escape braces @@ -164,7 +167,7 @@ def preserve_numeric(match): # Replace all {digit} patterns with markers text = re.sub(r'\{(\d+)\}', preserve_numeric, text) - print(f"[DEBUG] Preserved {len(numeric_placeholders)} numeric placeholders: {list(numeric_placeholders.values())}") + logger.debug(f" Preserved {len(numeric_placeholders)} numeric placeholders: {list(numeric_placeholders.values())}") # STEP 3: ESCAPE ALL REMAINING BRACES # Now escape ALL braces (non-numeric content like {Decision}, {Component}) @@ -180,8 +183,8 @@ def preserve_numeric(match): # Count braces after escaping open_count_after = result.count('{') close_count_after = result.count('}') - print(f"[DEBUG] AFTER ESCAPING: {{ count={open_count_after}, }} count={close_count_after}") - print(f"[DEBUG] Sample (first 200 chars): {result[:200]}") + logger.debug(f" AFTER ESCAPING: {{ count={open_count_after}, }} count={close_count_after}") + logger.debug(f" Sample (first 200 chars): {result[:200]}") return result @@ -259,16 +262,16 @@ def load_custom_instructions() -> str: custom_instructions = os.environ.get(CUSTOM_INSTRUCTIONS_ENV_VAR, "") if not custom_instructions: - print(f"[CodeWiki] {CUSTOM_INSTRUCTIONS_ENV_VAR} not set - continuing without custom instructions") + logger.info(f"{CUSTOM_INSTRUCTIONS_ENV_VAR} not set - continuing without custom instructions") return "" - print(f"[CodeWiki] Loaded custom repo instructions ({len(custom_instructions)} chars)") + logger.info(f"Loaded custom repo instructions ({len(custom_instructions)} chars)") # CRITICAL: Sanitize on input - this is the ONLY place text sanitization should happen # Shell scripts pass raw text, and we handle all sanitization here in Python # This prevents double-sanitization and ensures consistent behavior sanitized = sanitize_problematic_patterns(custom_instructions) - print(f"[CodeWiki] Sanitized custom instructions ({len(sanitized)} chars after sanitization)") + logger.info(f"Sanitized custom instructions ({len(sanitized)} chars after sanitization)") return sanitized @@ -291,20 +294,20 @@ def load_validation_rules() -> str: rules_path = os.environ.get(VALIDATION_RULES_ENV_VAR) if not rules_path: - print(f"[CodeWiki] {VALIDATION_RULES_ENV_VAR} not set - continuing without validation rules injection") + logger.info(f"{VALIDATION_RULES_ENV_VAR} not set - continuing without validation rules injection") return "" try: path = Path(rules_path) if not path.exists(): - print(f"[CodeWiki] Validation rules file not found: {rules_path}") + logger.warning(f"Validation rules file not found: {rules_path}") return "" content = path.read_text(encoding='utf-8') - print(f"[CodeWiki] Loaded markdown validation rules ({len(content)} chars)") + logger.info(f"Loaded markdown validation rules ({len(content)} chars)") return content except Exception as e: - print(f"[CodeWiki] Failed to load validation rules: {e}") + logger.error(f"Failed to load validation rules: {e}") return "" diff --git a/codewiki/src/fe/background_worker.py b/codewiki/src/fe/background_worker.py index 007ef88c..a9fe7729 100644 --- a/codewiki/src/fe/background_worker.py +++ b/codewiki/src/fe/background_worker.py @@ -9,6 +9,7 @@ import threading import subprocess import asyncio +import logging from datetime import datetime from pathlib import Path from queue import Queue @@ -23,6 +24,8 @@ from .config import WebAppConfig from codewiki.src.utils import file_manager +logger = logging.getLogger(__name__) + class BackgroundWorker: """Background worker for processing documentation generation jobs.""" @@ -41,7 +44,7 @@ def start(self): self.running = True thread = threading.Thread(target=self._worker_loop, daemon=True) thread.start() - print("Background worker started") + logger.info("Background worker started") def stop(self): """Stop the background worker.""" @@ -84,9 +87,9 @@ def load_job_statuses(self): progress=job_data.get('progress', ''), docs_path=job_data.get('docs_path') ) - print(f"Loaded {len([j for j in self.job_status.values() if j.status == 'completed'])} completed jobs from disk") + logger.info(f"Loaded {len([j for j in self.job_status.values() if j.status == 'completed'])} completed jobs from disk") except Exception as e: - print(f"Error loading job statuses: {e}") + logger.error(f"Error loading job statuses: {e}") def _reconstruct_jobs_from_cache(self): """Reconstruct job statuses from cache entries for backward compatibility.""" @@ -114,14 +117,14 @@ def _reconstruct_jobs_from_cache(self): ) reconstructed_count += 1 except Exception as e: - print(f"Failed to reconstruct job for {cache_entry.repo_url}: {e}") + logger.error(f"Failed to reconstruct job for {cache_entry.repo_url}: {e}") if reconstructed_count > 0: - print(f"Reconstructed {reconstructed_count} job statuses from cache") + logger.info(f"Reconstructed {reconstructed_count} job statuses from cache") self.save_job_statuses() except Exception as e: - print(f"Error reconstructing jobs from cache: {e}") + logger.error(f"Error reconstructing jobs from cache: {e}") def save_job_statuses(self): """Save job statuses to disk.""" @@ -145,7 +148,7 @@ def save_job_statuses(self): file_manager.save_json(data, self.jobs_file) except Exception as e: - print(f"Error saving job statuses: {e}") + logger.error(f"Error saving job statuses: {e}") def _worker_loop(self): """Main worker loop.""" @@ -157,7 +160,7 @@ def _worker_loop(self): else: time.sleep(1) except Exception as e: - print(f"Worker error: {e}") + logger.error(f"Worker error: {e}") time.sleep(1) def _process_job(self, job_id: str): @@ -187,7 +190,7 @@ def _process_job(self, job_id: str): # Save job status to disk self.save_job_statuses() - print(f"Job {job_id}: Using cached documentation") + logger.info(f"Job {job_id}: Using cached documentation") return # Clone repository @@ -236,7 +239,7 @@ def _process_job(self, job_id: str): # Save job status to disk self.save_job_statuses() - print(f"Job {job_id}: Documentation generated successfully") + logger.info(f"Job {job_id}: Documentation generated successfully") except Exception as e: # Update job status with error @@ -245,7 +248,7 @@ def _process_job(self, job_id: str): job.error_message = str(e) job.progress = f"Failed: {str(e)}" - print(f"Job {job_id}: Failed with error: {e}") + logger.error(f"Job {job_id}: Failed with error: {e}") finally: # Cleanup temporary repository @@ -253,4 +256,4 @@ def _process_job(self, job_id: str): try: subprocess.run(['rm', '-rf', temp_repo_dir], check=True) except Exception as e: - print(f"Failed to cleanup temp directory: {e}") \ No newline at end of file + logger.error(f"Failed to cleanup temp directory: {e}")