Skip to content

Commit 3d91809

Browse files
Update scripts and CI
1 parent d093fa9 commit 3d91809

7 files changed

Lines changed: 74 additions & 131 deletions

File tree

.github/workflows/ci.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,23 @@ jobs:
3535
- name: Check internal broken links across the whole site
3636
run: python src/main/ci_internal_links.py --all
3737

38-
- name: Check generated abstract pages
38+
- name: Check Q315 links
3939
run: python src/main/ci_internal_links.py --root Q315
4040

4141
- name: Check canonical abstract CSS references
4242
run: python src/main/abstract/css_assets.py check
4343

44-
- name: Check abstract HTML contract pilot
45-
run: python src/main/abstract/validate_abstract_html.py Q315/Q3062/index.html
44+
- name: Check every canonical Q315 document
45+
run: python src/main/abstract/validate_abstract_html.py Q315
46+
47+
- name: Check rendered Q315 labels are current
48+
run: python src/main/abstract/render_page.py --check
49+
50+
- name: Check Q315 structural repairs are current
51+
run: python src/main/abstract/repair_structure.py --check
52+
53+
- name: Check Q315 round-trip has no regressions
54+
run: |
55+
python src/main/abstract/verify_content_roundtrip.py \
56+
--max-mismatches 214 \
57+
--report "${RUNNER_TEMP}/q315-content-roundtrip.json"

.gitignore

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,17 @@ test.py
1717
# Q315 abstract workflow generated artifacts
1818
src/main/abstract/pilots/
1919
src/main/abstract/snapshots/
20-
src/main/abstract/travel-content*.csv
21-
src/main/abstract/travel-content*.quickstatements
20+
# CSV reports, translation scratch files, and QuickStatements are disposable
21+
# migration output. Durable inputs belong in data/ or have an explicit
22+
# exception below.
23+
src/main/abstract/*.csv
24+
src/main/abstract/*.quickstatements
25+
!src/main/abstract/abstract-functions.quickstatements
2226
src/main/abstract/content-migration-registry.csv
2327
src/main/abstract/content-migration-report.json
2428
src/main/abstract/content-roundtrip.json
25-
src/main/abstract/missing-content-review.csv
26-
src/main/abstract/missing-content*.quickstatements
27-
src/main/abstract/content-corrections-review.csv
28-
src/main/abstract/content-corrections.quickstatements
29-
src/main/abstract/abstract-composition.quickstatements
3029
*.quickstatements.state.json
31-
src/main/abstract/abstract-composition-partial.quickstatements
32-
src/main/abstract/abstract-composition-review.csv
33-
src/main/abstract/abstract-composition-structure.quickstatements
3430
src/main/abstract/abstract-composition-markup.txt
35-
src/main/abstract/abstract-composition.quickstatements
3631

3732
.vscode
3833
.obsidian

src/main/abstract/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ python3 src/main/abstract/verify_content_roundtrip.py
8888
Both renderers take `--page QID` to scope to a single page. `verify_content_roundtrip.py`
8989
is the completion gate; residual mismatches are structural and must be placed
9090
inside their corresponding canonical containers, not appended elsewhere.
91+
CI runs both renderers in `--check` mode and rejects any increase over the
92+
documented 214-pair structural round-trip baseline. It also validates every
93+
HTML document below `Q315/`; passing a directory to `validate_abstract_html.py`
94+
discovers its HTML files recursively.
9195

9296
## Direct Wikibase bot
9397

@@ -96,7 +100,7 @@ the MediaWiki API. Validation is the default and does not require credentials:
96100

97101
```bash
98102
python3 src/main/wikibase_write.py \
99-
src/main/abstract/missing-label-updates.quickstatements
103+
/path/to/generated-batch.quickstatements
100104
```
101105

102106
Create a dedicated bot password in the Wikibase user preferences, copy
@@ -105,7 +109,7 @@ enable writes:
105109

106110
```bash
107111
python3 src/main/wikibase_write.py \
108-
src/main/abstract/missing-label-updates.quickstatements --apply
112+
/path/to/generated-batch.quickstatements --apply
109113
```
110114

111115
The writer supports the commands generated in this repository: `CREATE`,

src/main/abstract/gen_compose_research.py

Lines changed: 0 additions & 106 deletions
This file was deleted.

src/main/abstract/validate_abstract_html.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,23 +86,38 @@ def validate(path: Path) -> list[str]:
8686

8787
def build_parser() -> argparse.ArgumentParser:
8888
parser = argparse.ArgumentParser(description=__doc__)
89-
parser.add_argument("paths", type=Path, nargs="+")
89+
parser.add_argument(
90+
"paths",
91+
type=Path,
92+
nargs="+",
93+
help="HTML files or directories to search recursively",
94+
)
9095
return parser
9196

9297

93-
def main(argv: Sequence[str] | None = None) -> int:
94-
args = build_parser().parse_args(argv)
98+
def html_documents(paths: Sequence[Path]) -> tuple[list[Path], list[str]]:
99+
documents: list[Path] = []
95100
errors: list[str] = []
96-
for path in args.paths:
97-
if not path.is_file():
98-
errors.append(f"{path}: file does not exist")
101+
for path in paths:
102+
if path.is_dir():
103+
documents.extend(sorted(path.rglob("*.html")))
104+
elif path.is_file():
105+
documents.append(path)
99106
else:
100-
errors.extend(validate(path))
107+
errors.append(f"{path}: file or directory does not exist")
108+
return documents, errors
109+
110+
111+
def main(argv: Sequence[str] | None = None) -> int:
112+
args = build_parser().parse_args(argv)
113+
documents, errors = html_documents(args.paths)
114+
for path in documents:
115+
errors.extend(validate(path))
101116
if errors:
102117
for error in errors:
103118
print(f"ERROR: {error}")
104119
return 1
105-
print(f"Validated {len(args.paths)} abstract HTML document(s)")
120+
print(f"Validated {len(documents)} abstract HTML document(s)")
106121
return 0
107122

108123

src/main/abstract/verify_content_roundtrip.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ def main() -> int:
146146
default="",
147147
help="restrict verification to a single abstract page QID",
148148
)
149+
parser.add_argument(
150+
"--max-mismatches",
151+
type=int,
152+
help=(
153+
"fail only when mismatch count exceeds this known structural "
154+
"baseline (default: require complete equivalence)"
155+
),
156+
)
149157
parser.add_argument("--report", type=Path, default=DEFAULT_REPORT)
150158
args = parser.parse_args()
151159
repo_root = args.repo_root.resolve()
@@ -160,6 +168,8 @@ def main() -> int:
160168
f"Round-trip status: {report['status']}; "
161169
f"language-page mismatches: {report['mismatch_count']}"
162170
)
171+
if args.max_mismatches is not None:
172+
return 0 if report["mismatch_count"] <= args.max_mismatches else 1
163173
return 0 if report["status"] == "equivalent" else 1
164174

165175

src/test/test_abstract_content.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
from abstract.model import FunctionCall, MonolingualText
1313
from abstract.prepare_travel_content import validate_quickstatements
14-
from abstract.validate_abstract_html import validate
14+
from abstract.validate_abstract_html import html_documents, validate
1515

1616

1717
class AbstractFunctionTests(unittest.TestCase):
@@ -84,6 +84,19 @@ def test_argument_outside_call_is_rejected(self):
8484
self.assertEqual(len(errors), 1)
8585
self.assertIn("contained in q-call", errors[0])
8686

87+
def test_directories_are_discovered_recursively(self):
88+
with tempfile.TemporaryDirectory() as directory:
89+
root = Path(directory)
90+
nested = root / "nested"
91+
nested.mkdir()
92+
page = nested / "page.html"
93+
page.write_text("<html></html>", encoding="utf-8")
94+
95+
documents, errors = html_documents([root])
96+
97+
self.assertEqual(documents, [page])
98+
self.assertEqual(errors, [])
99+
87100

88101
class TravelContentQuickStatementsTests(unittest.TestCase):
89102
def test_validator_accepts_complete_queryable_languages(self):

0 commit comments

Comments
 (0)