pintest-cli 0.2.5__tar.gz → 0.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/PKG-INFO +1 -1
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/cloud_mapping_db.py +16 -7
- pintest_cli-0.2.6/pintest/push_cache.py +61 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/PKG-INFO +1 -1
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/SOURCES.txt +1 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/setup.py +1 -1
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/README.md +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/__init__.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/build_mapping_iterative.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/cli.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/config.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/coverage_mapper.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/git_diff_parser.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/post_commit_hook.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/pre_commit_hook.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/range_set.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/test_mapping_db_v2.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest/update_mapping.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/dependency_links.txt +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/entry_points.txt +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/requires.txt +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/pintest_cli.egg-info/top_level.txt +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/setup.cfg +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/tests/__init__.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/tests/test_git_diff_parser.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/tests/test_new_feature.py +0 -0
- {pintest_cli-0.2.5 → pintest_cli-0.2.6}/tests/test_range_set.py +0 -0
|
@@ -108,6 +108,7 @@ class CloudMappingDB:
|
|
|
108
108
|
True on success, False on failure
|
|
109
109
|
"""
|
|
110
110
|
from .coverage_mapper import CoverageMapper # existing module
|
|
111
|
+
from .push_cache import PushCache
|
|
111
112
|
|
|
112
113
|
if not coverage_file.exists():
|
|
113
114
|
if verbose:
|
|
@@ -137,19 +138,26 @@ class CloudMappingDB:
|
|
|
137
138
|
test_file_ranges[key] = RangeSet()
|
|
138
139
|
test_file_ranges[key].add_range(line_num, line_num)
|
|
139
140
|
|
|
141
|
+
cache_db_path = coverage_file.parent / ".pintest_push_cache.db"
|
|
142
|
+
push_cache = PushCache(cache_db_path)
|
|
143
|
+
cached_state = push_cache.get_cached_state(self._branch)
|
|
144
|
+
|
|
140
145
|
mappings = []
|
|
141
146
|
for (test_name, file_path), rs in test_file_ranges.items():
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
compact_ranges = rs.to_compact_string()
|
|
148
|
+
key = (test_name, file_path)
|
|
149
|
+
if key not in cached_state or cached_state[key] != compact_ranges:
|
|
150
|
+
mappings.append({
|
|
151
|
+
"test_name": test_name,
|
|
152
|
+
"file_path": file_path,
|
|
153
|
+
"ranges": compact_ranges,
|
|
154
|
+
})
|
|
147
155
|
|
|
148
156
|
if not mappings:
|
|
149
|
-
print("ℹ️
|
|
157
|
+
print("ℹ️ All coverage mappings are up-to-date with Pintest Cloud (0 deltas)")
|
|
150
158
|
return True
|
|
151
159
|
|
|
152
|
-
print(f"☁️ Pushing {len(mappings)} mappings to Pintest...", flush=True)
|
|
160
|
+
print(f"☁️ Pushing {len(mappings)} delta mappings to Pintest...", flush=True)
|
|
153
161
|
|
|
154
162
|
payload_base = {
|
|
155
163
|
"branch": self._branch,
|
|
@@ -179,6 +187,7 @@ class CloudMappingDB:
|
|
|
179
187
|
timeout=60,
|
|
180
188
|
)
|
|
181
189
|
resp.raise_for_status()
|
|
190
|
+
push_cache.batch_upsert(self._branch, chunk_data)
|
|
182
191
|
data = resp.json()
|
|
183
192
|
inserted = data.get('inserted', 0)
|
|
184
193
|
updated = data.get('updated', 0)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Dict, List, Tuple
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PushCache:
|
|
7
|
+
"""
|
|
8
|
+
Manages the local SQLite cache for Pintest Cloud delta pushes.
|
|
9
|
+
Tracks previously synchronized test coverage mappings to filter out unmodified entries.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, db_path: Path):
|
|
13
|
+
self.db_path = db_path
|
|
14
|
+
self._init_db()
|
|
15
|
+
|
|
16
|
+
def _init_db(self):
|
|
17
|
+
"""Initialize the local push cache database schema."""
|
|
18
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
19
|
+
conn.execute("PRAGMA journal_mode=WAL")
|
|
20
|
+
conn.execute("""
|
|
21
|
+
CREATE TABLE IF NOT EXISTS push_cache (
|
|
22
|
+
branch TEXT,
|
|
23
|
+
test_name TEXT,
|
|
24
|
+
file_path TEXT,
|
|
25
|
+
ranges TEXT,
|
|
26
|
+
last_pushed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
27
|
+
PRIMARY KEY (branch, test_name, file_path)
|
|
28
|
+
)
|
|
29
|
+
""")
|
|
30
|
+
conn.execute("CREATE INDEX IF NOT EXISTS idx_push_cache_lookup ON push_cache(branch)")
|
|
31
|
+
|
|
32
|
+
def get_cached_state(self, branch: str) -> Dict[Tuple[str, str], str]:
|
|
33
|
+
"""
|
|
34
|
+
Fetch the last successfully pushed state for the active branch.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
{(test_name, file_path): ranges_string}
|
|
38
|
+
"""
|
|
39
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
40
|
+
cursor = conn.execute(
|
|
41
|
+
"SELECT test_name, file_path, ranges FROM push_cache WHERE branch = ?",
|
|
42
|
+
(branch,)
|
|
43
|
+
)
|
|
44
|
+
return {(row[0], row[1]): row[2] for row in cursor}
|
|
45
|
+
|
|
46
|
+
def batch_upsert(self, branch: str, mappings: List[Dict[str, str]]):
|
|
47
|
+
"""
|
|
48
|
+
Atomically update the cache with successfully pushed mappings.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
branch: Active git branch
|
|
52
|
+
mappings: List of dicts [{"test_name": ..., "file_path": ..., "ranges": ...}]
|
|
53
|
+
"""
|
|
54
|
+
with sqlite3.connect(self.db_path) as conn:
|
|
55
|
+
conn.executemany("""
|
|
56
|
+
INSERT INTO push_cache (branch, test_name, file_path, ranges, last_pushed_at)
|
|
57
|
+
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
58
|
+
ON CONFLICT(branch, test_name, file_path) DO UPDATE SET
|
|
59
|
+
ranges = EXCLUDED.ranges,
|
|
60
|
+
last_pushed_at = CURRENT_TIMESTAMP
|
|
61
|
+
""", [(branch, m["test_name"], m["file_path"], m["ranges"]) for m in mappings])
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="pintest-cli",
|
|
8
|
-
version="0.2.
|
|
8
|
+
version="0.2.6",
|
|
9
9
|
description="Run only the tests affected by your code changes.",
|
|
10
10
|
long_description=long_description,
|
|
11
11
|
long_description_content_type="text/markdown",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|