Skip to content

Commit e0d1a36

Browse files
committed
Constrain external docs migration districts
1 parent 35d65ae commit e0d1a36

2 files changed

Lines changed: 43 additions & 9 deletions

File tree

scripts/docs_districts/validate_docs_migration_map.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
from scripts.docs_districts.docs_thematic_common import REPO_ROOT, load_classifier, validate_classifier_shape
1010

1111

12-
def main() -> int:
13-
classifier = load_classifier(REPO_ROOT)
12+
EXTERNAL_OWNER_ROUTE_DISTRICT = "traces"
13+
14+
15+
def validate_migration_map(classifier: dict, repo_root: Path = REPO_ROOT) -> list[str]:
1416
errors = validate_classifier_shape(classifier)
1517
districts = classifier.get("districts", {})
1618

@@ -36,16 +38,28 @@ def main() -> int:
3638
if target_dir != district_path:
3739
if not external_owner_route:
3840
errors.append(f"pattern migration target_dir {target_dir} does not match district {district}")
39-
elif external_owner_route != target_dir:
40-
errors.append(
41-
f"pattern migration external_owner_route {external_owner_route} must match target_dir {target_dir}"
42-
)
43-
elif not (REPO_ROOT / external_owner_route).is_dir():
44-
errors.append(f"pattern migration external owner route does not exist: {external_owner_route}")
41+
else:
42+
if district != EXTERNAL_OWNER_ROUTE_DISTRICT:
43+
errors.append(
44+
f"pattern migration external owner route {source_glob} must use district "
45+
f"{EXTERNAL_OWNER_ROUTE_DISTRICT}, got {district}"
46+
)
47+
if external_owner_route != target_dir:
48+
errors.append(
49+
f"pattern migration external_owner_route {external_owner_route} must match target_dir {target_dir}"
50+
)
51+
elif not (repo_root / external_owner_route).is_dir():
52+
errors.append(f"pattern migration external owner route does not exist: {external_owner_route}")
4553

4654
if source_glob.startswith("docs/") and "README" in source_glob.upper():
4755
errors.append(f"pattern migration must not catch README surfaces: {source_glob}")
4856

57+
return errors
58+
59+
60+
def main() -> int:
61+
classifier = load_classifier(REPO_ROOT)
62+
errors = validate_migration_map(classifier, REPO_ROOT)
4963
if errors:
5064
raise SystemExit("docs migration map validation failed:\n- " + "\n- ".join(errors))
5165
print("docs migration map validated")

tests/test_docs_migration_map.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from __future__ import annotations
2+
import copy, tempfile
23
import sys, unittest
34
from pathlib import Path
45
ROOT=Path(__file__).resolve().parents[1]; sys.path.insert(0,str(ROOT/'scripts'))
5-
from scripts.docs_districts.docs_thematic_common import load_classifier
6+
from scripts.docs_districts.docs_thematic_common import build_plan, load_classifier
7+
from scripts.docs_districts.validate_docs_migration_map import validate_migration_map
68
class DocsMigrationMapTests(unittest.TestCase):
79
def setUp(self): self.c=load_classifier(ROOT)
810
def test_all_exact_migrations_target_known_districts(self):
@@ -15,6 +17,24 @@ def test_external_pattern_routes_are_explicit(self):
1517
self.assertIn('external_owner_route', item)
1618
self.assertEqual(item['external_owner_route'], item['target_dir'])
1719
self.assertTrue((ROOT/item['external_owner_route']).is_dir(), item['external_owner_route'])
20+
def test_external_pattern_routes_are_bound_to_traces_district(self):
21+
classifier=copy.deepcopy(self.c)
22+
rule=next(item for item in classifier['pattern_migrations'] if item['source_glob']=='docs/EXPERIENCE_*.md')
23+
rule['district']='decisions'
24+
errors=validate_migration_map(classifier, ROOT)
25+
self.assertIn('must use district traces, got decisions', '\n'.join(errors))
26+
def test_experience_wildcard_routes_to_external_owner_route(self):
27+
name='EXPERIENCE_'+'ROUTE.md'
28+
source='docs/'+name
29+
with tempfile.TemporaryDirectory() as tmp:
30+
root=Path(tmp)
31+
(root/'docs').mkdir()
32+
(root/'docs'/name).write_text('# Experience route\n', encoding='utf-8')
33+
(root/'mechanics'/'experience'/'legacy'/'raw').mkdir(parents=True)
34+
moves=build_plan(root,self.c)
35+
move=next(item for item in moves if item['source']==source)
36+
self.assertEqual(move['target'],'mechanics/experience/legacy/raw/'+name)
37+
self.assertEqual(move['district'],'traces')
1838
def test_no_current_root_allowlist_item_is_exact_moved(self):
1939
allow=set(self.c['current_root_allowlist']); moved={Path(i['source']).name for i in self.c['exact_migrations']}; self.assertFalse(allow & moved)
2040
if __name__=='__main__': unittest.main()

0 commit comments

Comments
 (0)