Skip to content

Commit 56a0336

Browse files
authored
Merge pull request #223 from QuantStrategyLab/codex/sync-qsl-requires-map-20260710
fix(qpk): sync QSL requires-map pin
2 parents 2d2e178 + 292eab7 commit 56a0336

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

scripts/open_downstream_qpk_pin_prs.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222
QSL_QPK_REQUIREMENT_RE = re.compile(
2323
r"(quant-platform-kit\s*@\s*git\+https://github\.com/QuantStrategyLab/QuantPlatformKit\.git@)[a-f0-9]{40}"
2424
)
25+
QSL_REQUIRES_TABLE_RE = re.compile(
26+
r"(?ms)^[ \t]*(?P<header>\[qsl\.requires\][^\n]*\n)(?P<body>.*?)(?=^[ \t]*\[|\Z)"
27+
)
28+
QSL_QPK_REQUIRES_MAP_RE = re.compile(
29+
r"""(^[ \t]*(?:["']quant-platform-kit["']|quant-platform-kit|["']quant_platform_kit["']|quant_platform_kit)\s*=\s*)(['"])[a-f0-9]{40}(\2)""",
30+
re.MULTILINE,
31+
)
2532

2633

2734
@dataclass(frozen=True)
@@ -65,7 +72,17 @@ def update_qsl_compat_qpk_pin(repo_dir: Path, qpk_sha: str) -> bool:
6572
return False
6673

6774
original = qsl_path.read_text(encoding="utf-8")
68-
updated, replacements = QSL_QPK_REQUIREMENT_RE.subn(rf"\g<1>{qpk_sha}", original)
75+
updated, requirement_replacements = QSL_QPK_REQUIREMENT_RE.subn(rf"\g<1>{qpk_sha}", original)
76+
requires_map_replacements = 0
77+
78+
def update_requires_table(match: re.Match[str]) -> str:
79+
nonlocal requires_map_replacements
80+
body, replacements = QSL_QPK_REQUIRES_MAP_RE.subn(rf"\g<1>\g<2>{qpk_sha}\g<3>", match.group("body"))
81+
requires_map_replacements += replacements
82+
return match.group("header") + body
83+
84+
updated = QSL_REQUIRES_TABLE_RE.sub(update_requires_table, updated)
85+
replacements = requirement_replacements + requires_map_replacements
6986
if replacements == 0 or updated == original:
7087
return False
7188

tests/test_qpk_pin_consistency.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,43 @@ def test_update_qsl_compat_qpk_pin_rewrites_only_qpk_requirement(self) -> None:
8181
self.assertIn(f"QuantPlatformKit.git@{TARGET}", updated)
8282
self.assertIn(f"UsEquityStrategies.git@{STALE}", updated)
8383

84+
def test_update_qsl_compat_qpk_pin_rewrites_qsl_requires_map(self) -> None:
85+
with tempfile.TemporaryDirectory() as tmp:
86+
qsl_path = Path(tmp) / "qsl.toml"
87+
qsl_path.write_text(
88+
"[qsl.requires]\n"
89+
f'quant_platform_kit = "{STALE}"\n'
90+
f'quant-platform-kit = "{STALE}"\n'
91+
f'crypto_strategies = "{STALE}"\n'
92+
"\n[runtime]\n"
93+
f'quant_platform_kit = "{STALE}"\n',
94+
encoding="utf-8",
95+
)
96+
97+
self.assertTrue(update_qsl_compat_qpk_pin(Path(tmp), TARGET))
98+
updated = qsl_path.read_text(encoding="utf-8")
99+
100+
self.assertIn(f'quant_platform_kit = "{TARGET}"', updated)
101+
self.assertIn(f'quant-platform-kit = "{TARGET}"', updated)
102+
self.assertIn(f'crypto_strategies = "{STALE}"', updated)
103+
self.assertIn(f'[runtime]\nquant_platform_kit = "{STALE}"', updated)
104+
105+
def test_update_qsl_compat_qpk_pin_rewrites_single_quoted_qsl_requires_map(self) -> None:
106+
with tempfile.TemporaryDirectory() as tmp:
107+
qsl_path = Path(tmp) / "qsl.toml"
108+
qsl_path.write_text(
109+
"[qsl.requires]\n"
110+
f"quant_platform_kit = '{STALE}'\n"
111+
f"'quant-platform-kit' = '{STALE}'\n",
112+
encoding="utf-8",
113+
)
114+
115+
self.assertTrue(update_qsl_compat_qpk_pin(Path(tmp), TARGET))
116+
updated = qsl_path.read_text(encoding="utf-8")
117+
118+
self.assertIn(f"quant_platform_kit = '{TARGET}'", updated)
119+
self.assertIn(f"'quant-platform-kit' = '{TARGET}'", updated)
120+
84121

85122
if __name__ == "__main__":
86123
unittest.main()

0 commit comments

Comments
 (0)