Skip to content

Commit 037097d

Browse files
committed
build: bump version to 1.2.7 and fix metrics storage
1 parent 6f69fbb commit 037097d

File tree

5 files changed

+47
-19
lines changed

5 files changed

+47
-19
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## [1.2.7] - 2025-03-05
4+
### 🛠️ Fixes
5+
- Fix JSON handling in metrics storage
6+
- Make statistics display more robust against malformed data
7+
- Add safety checks for repository and model usage data
8+
9+
10+
311
## [1.2.6] - 2025-03-05
412
### 🛠️ Fixes
513
- Connect Auto Release and Package Publishing workflows

commitloom/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .core.git import GitError, GitFile, GitOperations
66
from .services.ai_service import AIService, CommitSuggestion, TokenUsage
77

8-
__version__ = "1.2.6"
8+
__version__ = "1.2.7"
99
__author__ = "Petru Arakiss"
1010
__email__ = "petruarakiss@gmail.com"
1111

commitloom/cli/cli_handler.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -349,51 +349,56 @@ def stats_command(self) -> None:
349349

350350
# Display basic stats
351351
console.console.print("\n[bold cyan]Basic Statistics:[/bold cyan]")
352-
console.console.print(f" • Total commits generated: {stats['total_commits']:,}")
353-
console.console.print(f" • Total tokens used: {stats['total_tokens']:,}")
354-
console.console.print(f" • Total cost: €{stats['total_cost_in_eur']:.4f}")
355-
console.console.print(f" • Total files processed: {stats['total_files_processed']:,}")
352+
console.console.print(f" • Total commits generated: {stats.get('total_commits', 0):,}")
353+
console.console.print(f" • Total tokens used: {stats.get('total_tokens', 0):,}")
354+
console.console.print(f" • Total cost: €{stats.get('total_cost_in_eur', 0.0):.4f}")
355+
console.console.print(f" • Total files processed: {stats.get('total_files_processed', 0):,}")
356356

357357
# Display time saved if available
358358
if 'time_saved_formatted' in stats:
359359
console.console.print(f" • Total time saved: {stats['time_saved_formatted']}")
360360

361361
# Display activity period if available
362362
if 'first_used_at' in stats and stats['first_used_at'] and 'days_active' in stats:
363-
console.console.print(f" • Active since: {stats['first_used_at'].split('T')[0]}")
363+
first_used = stats['first_used_at']
364+
date_part = first_used.split('T')[0] if isinstance(first_used, str) and 'T' in first_used else first_used
365+
console.console.print(f" • Active since: {date_part}")
364366
console.console.print(f" • Days active: {stats['days_active']}")
365367

366368
if 'avg_commits_per_day' in stats:
367369
console.console.print(f" • Average commits per day: {stats['avg_commits_per_day']:.2f}")
368370
console.console.print(f" • Average cost per day: €{stats['avg_cost_per_day']:.4f}")
369371

370372
# Display repository stats if available
371-
if stats['repositories']:
373+
repositories = stats.get('repositories', {})
374+
if repositories and isinstance(repositories, dict):
372375
console.console.print("\n[bold cyan]Repository Activity:[/bold cyan]")
373-
console.console.print(f" • Most active repository: {stats['most_active_repository']}")
374-
console.console.print(f" • Repositories used: {len(stats['repositories'])}")
376+
if 'most_active_repository' in stats and stats['most_active_repository']:
377+
console.console.print(f" • Most active repository: {stats['most_active_repository']}")
378+
console.console.print(f" • Repositories used: {len(repositories)}")
375379

376380
# Display model usage if available
377-
if stats['model_usage']:
381+
model_usage = stats.get('model_usage', {})
382+
if model_usage and isinstance(model_usage, dict):
378383
console.console.print("\n[bold cyan]Model Usage:[/bold cyan]")
379-
for model, count in stats['model_usage'].items():
384+
for model, count in model_usage.items():
380385
console.console.print(f" • {model}: {count} commits")
381386

382387
# Display batch vs single commits
383388
console.console.print("\n[bold cyan]Processing Methods:[/bold cyan]")
384-
console.console.print(f" • Batch commits: {stats['batch_commits']}")
385-
console.console.print(f" • Single commits: {stats['single_commits']}")
389+
console.console.print(f" • Batch commits: {stats.get('batch_commits', 0)}")
390+
console.console.print(f" • Single commits: {stats.get('single_commits', 0)}")
386391

387392
# Get more detailed stats if commits exist
388-
if stats['total_commits'] > 0:
393+
if stats.get('total_commits', 0) > 0:
389394
model_stats = metrics_manager.get_model_usage_stats()
390395
if model_stats:
391396
console.console.print("\n[bold cyan]Detailed Model Stats:[/bold cyan]")
392397
for model, model_data in model_stats.items():
393398
console.console.print(f" • {model}:")
394-
console.console.print(f" - Total tokens: {model_data['tokens']:,}")
395-
console.console.print(f" - Total cost: €{model_data['cost']:.4f}")
396-
console.console.print(f" - Avg tokens per commit: {model_data['avg_tokens_per_commit']:.1f}")
399+
console.console.print(f" - Total tokens: {model_data.get('tokens', 0):,}")
400+
console.console.print(f" - Total cost: €{model_data.get('cost', 0.0):.4f}")
401+
console.console.print(f" - Avg tokens per commit: {model_data.get('avg_tokens_per_commit', 0.0):.1f}")
397402

398403
def run(
399404
self, auto_commit: bool = False, combine_commits: bool = False, debug: bool = False

commitloom/services/metrics.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ def _load_statistics(self) -> UsageStatistics:
8484
try:
8585
with open(self._stats_file) as f:
8686
data = json.load(f)
87+
# Ensure valid JSON structure
88+
if not isinstance(data, dict):
89+
logger.warning("Invalid statistics file format, creating new file")
90+
return UsageStatistics()
8791
stats = UsageStatistics(**data)
8892
return stats
8993
except (json.JSONDecodeError, FileNotFoundError, KeyError) as e:
@@ -93,8 +97,19 @@ def _load_statistics(self) -> UsageStatistics:
9397
def _save_statistics(self) -> None:
9498
"""Save usage statistics to file."""
9599
try:
100+
# Ensure valid data structure before saving
101+
stats_dict = asdict(self._statistics)
102+
103+
# Fix any potential problematic values
104+
if 'repositories' in stats_dict and not isinstance(stats_dict['repositories'], dict):
105+
stats_dict['repositories'] = {}
106+
107+
if 'model_usage' in stats_dict and not isinstance(stats_dict['model_usage'], dict):
108+
stats_dict['model_usage'] = {}
109+
96110
with open(self._stats_file, "w") as f:
97-
json.dump(asdict(self._statistics), f, indent=2)
111+
json.dump(stats_dict, f, indent=2)
112+
98113
except (OSError, TypeError) as e:
99114
logger.warning(f"Failed to save statistics: {str(e)}")
100115

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "commitloom"
3-
version = "1.2.6"
3+
version = "1.2.7"
44
description = "Weave perfect git commits with AI-powered intelligence"
55
authors = ["Petru Arakiss <petruarakiss@gmail.com>"]
66
readme = "README.md"

0 commit comments

Comments
 (0)