feat(v1.2.0): retry API, dernier commit, tri, coloration, export JSON

- client.py: _get_with_retry (max 2 retries, backoff lineaire), get_latest_commit
- collector.py: champ last_commit_date dans RepoData
- display.py: colonne "Dernier commit", _sort_repos (name/issues/release/activity),
  _colorize_milestone_due (rouge/jaune/vert selon echeance)
- cli.py: options --sort/-s et --format/-f (table/json)
- exporter.py: nouveau module, repos_to_dicts + export_json
- 88 tests (35 nouveaux), ruff clean

fixes #8, fixes #7, fixes #10, fixes #9, fixes #6

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sylvain
2026-03-12 03:58:45 +01:00
parent 19f300ccdb
commit 4c66fbe98d
10 changed files with 639 additions and 10 deletions

View File

@@ -130,6 +130,54 @@ class TestCollectAll:
assert result[0].is_mirror is True
class TestCollectAllLastCommit:
"""Test last_commit_date field in RepoData."""
def test_repo_data_has_last_commit_date(self):
"""RepoData includes last_commit_date field."""
repo = RepoData(
name="test",
full_name="admin/test",
description="",
open_issues=0,
is_fork=False,
is_archived=False,
is_mirror=False,
latest_release=None,
milestones=[],
last_commit_date="2026-03-10T14:30:00Z",
)
assert repo.last_commit_date == "2026-03-10T14:30:00Z"
def test_collect_all_calls_get_latest_commit(self):
"""collect_all calls get_latest_commit and fills last_commit_date."""
client = MagicMock()
client.get_repos.return_value = [_make_repo()]
client.get_latest_release.return_value = None
client.get_milestones.return_value = []
client.get_latest_commit.return_value = {
"sha": "abc123",
"created": "2026-03-10T14:30:00Z",
}
result = collect_all(client)
client.get_latest_commit.assert_called_once_with("admin", "my-repo")
assert result[0].last_commit_date == "2026-03-10T14:30:00Z"
def test_collect_all_no_commits(self):
"""Repo without commits gets last_commit_date=None."""
client = MagicMock()
client.get_repos.return_value = [_make_repo()]
client.get_latest_release.return_value = None
client.get_milestones.return_value = []
client.get_latest_commit.return_value = None
result = collect_all(client)
assert result[0].last_commit_date is None
class TestCollectAllFiltering:
"""Test collect_all filtering (include/exclude)."""