Coverage for src/pullapprove/results_migrations.py: 0%
20 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-12-15 16:43 -0600
« prev ^ index » next coverage.py v7.8.2, created at 2025-12-15 16:43 -0600
1"""
2Versioned migrations for PullRequestResults data.
4When the schema changes, add a new migration function and append it to ResultsMigrator.migrations.
5Old stored data will be migrated on-the-fly when loaded via from_dict().
6"""
8from __future__ import annotations
10from typing import Any
13def migrate_resview_results_scopes(data: dict[str, Any]) -> dict[str, Any]:
14 """
15 Migrate v1 -> v2:
16 - ReviewResult.scopes -> reviewed_for
17 - ReviewResult.state computed from review.state
18 """
19 if "review_results" in data:
20 for review_result in data["review_results"].values():
21 # Rename scopes -> reviewed_for
22 if "scopes" in review_result:
23 review_result["matched_scopes"] = review_result.pop("scopes")
25 return data
28class ResultsMigrator:
29 """
30 Handles versioned migrations for PullRequestResults data.
31 """
33 # Ordered list of migration functions.
34 # Index 0 = v1->v2, index 1 = v2->v3, etc.
35 migrations = [
36 migrate_resview_results_scopes,
37 ]
39 @classmethod
40 def current_version(cls) -> int:
41 """Current version is always 1 more than the number of migrations."""
42 return len(cls.migrations) + 1
44 @classmethod
45 def migrate(cls, data: dict[str, Any]) -> dict[str, Any]:
46 """
47 Apply all necessary migrations to bring data to current version.
49 Data without a version field is assumed to be v1.
50 """
51 version = data.get("version", 1)
53 # Apply migrations from current version to latest
54 for migration in cls.migrations[version - 1 :]:
55 data = migration(data)
57 data["version"] = cls.current_version()
58 return data