"""Modulo `countings` — funzioni per il conteggio SLOC e metadati per file. Questo file contiene funzioni wrapper che incapsulano l'uso di `pygount` o implementazioni di fallback per ottenere i conteggi richiesti dal requisito "Counting" descritto in `doc/Sviluppo.md`. Per ora fornisce uno skeleton minimale con API chiaramente documentata. """ from pathlib import Path from typing import Dict, Any try: from pygount import analysis _HAS_PYGOUNT = True except Exception: _HAS_PYGOUNT = False def analyze_file_counts(path: Path) -> Dict[str, Any]: """Analizza un singolo file e ritorna un dizionario con i conteggi. Restituisce almeno le chiavi: - physical_lines - code_lines - comment_lines - blank_lines - language Nota: la funzione usa `pygount` se disponibile; altrimenti ritorna valori di fallback (zeros/unknown). """ result: Dict[str, Any] = { "file": str(path), "physical_lines": 0, "code_lines": 0, "comment_lines": 0, "blank_lines": 0, "language": "unknown", } if not path.exists(): raise FileNotFoundError(f"File non trovato: {path}") if _HAS_PYGOUNT: # Use pygount's SourceAnalysis API (pygount >= 1.0) try: stats = analysis.SourceAnalysis.from_file(str(path), "analysis") result.update({ "physical_lines": stats.line_count, "code_lines": stats.code_count, "comment_lines": stats.documentation_count, "blank_lines": stats.empty_count, "language": stats.language, }) except Exception: # In caso di problemi con pygount, manteniamo i fallback pass else: # Fallback molto semplice: leggi file e conta righe with path.open("r", errors="ignore") as fh: lines = fh.readlines() result["physical_lines"] = len(lines) # Semplice approssimazione: righe vuote vs non vuote blanks = sum(1 for l in lines if l.strip() == "") result["blank_lines"] = blanks result["code_lines"] = len(lines) - blanks return result def analyze_paths(paths): """Analizza più paths (file) e ritorna una lista di risultati. `paths` può essere un iterabile di `Path` o stringhe; la funzione normalizza e invoca `analyze_file_counts` per ciascuno. """ results = [] for p in paths: path = Path(p) try: results.append(analyze_file_counts(path)) except Exception as e: results.append({"file": str(path), "error": str(e)}) return results