@@ -122,11 +122,15 @@ def build_index(versions: str, skip_content: bool) -> None:
122122
123123 from mcp_server_python_docs .ingestion .inventory import ingest_inventory
124124 from mcp_server_python_docs .ingestion .publish import (
125+ _version_sort_key ,
125126 generate_build_path ,
127+ parse_expected_versions ,
126128 publish_index ,
127129 )
128130 from mcp_server_python_docs .ingestion .sphinx_json import (
131+ build_sphinx_json_command ,
129132 ingest_sphinx_json_dir ,
133+ make_sphinx_json_env ,
130134 populate_synonyms ,
131135 rebuild_fts_indexes ,
132136 write_json_build_requirements ,
@@ -144,7 +148,7 @@ def build_index(versions: str, skip_content: bool) -> None:
144148 "3.13" : {"tag" : "v3.13.12" , "sphinx_pin" : "sphinx<9.0.0" },
145149 }
146150
147- version_list = [ v . strip () for v in versions . split ( "," ) if v . strip ()]
151+ version_list = parse_expected_versions ( versions )
148152 if not version_list :
149153 logger .error ("No valid versions specified. Example: --versions 3.13" )
150154 raise SystemExit (1 )
@@ -159,8 +163,7 @@ def build_index(versions: str, skip_content: bool) -> None:
159163 raise SystemExit (1 )
160164
161165 # Determine default version: highest version number (MVER-02)
162- sorted_versions = sorted (version_list , key = lambda v : [int (x ) for x in v .split ("." )])
163- default_version = sorted_versions [- 1 ]
166+ default_version = max (version_list , key = _version_sort_key )
164167
165168 # Build into a timestamped artifact, not directly to index.db (PUBL-01)
166169 build_db_path = generate_build_path ()
@@ -259,25 +262,15 @@ def build_index(versions: str, skip_content: bool) -> None:
259262 json_out = os .path .join (doc_dir , "build" , "json" )
260263 sphinx_compat_dir = Path (clone_dir ) / "_sphinx_json_compat"
261264 write_sphinx_json_sitecustomize (sphinx_compat_dir )
262- sphinx_env = os .environ .copy ()
263- sphinx_env ["PYTHONPATH" ] = (
264- str (sphinx_compat_dir )
265- if not sphinx_env .get ("PYTHONPATH" )
266- else f"{ sphinx_compat_dir } { os .pathsep } { sphinx_env ['PYTHONPATH' ]} "
267- )
265+ sphinx_env = make_sphinx_json_env (sphinx_compat_dir )
268266
269267 logger .info (
270268 "Running sphinx-build -b json for Python %s "
271269 "(this may take 3-8 minutes)..." ,
272270 version ,
273271 )
274272 result = subprocess .run (
275- [
276- sphinx_build , "-b" , "json" ,
277- "-D" , "html_theme=classic" ,
278- "-j" , "auto" ,
279- doc_dir , json_out ,
280- ],
273+ build_sphinx_json_command (sphinx_build , doc_dir , json_out ),
281274 capture_output = True ,
282275 text = True ,
283276 cwd = doc_dir ,
@@ -375,7 +368,10 @@ def validate_corpus(db_path: str | None) -> None:
375368 """
376369 from pathlib import Path
377370
378- from mcp_server_python_docs .ingestion .publish import run_smoke_tests
371+ from mcp_server_python_docs .ingestion .publish import (
372+ parse_expected_versions ,
373+ run_smoke_tests ,
374+ )
379375 from mcp_server_python_docs .storage .db import get_index_path , get_readonly_connection
380376
381377 if db_path is not None :
@@ -392,20 +388,28 @@ def validate_corpus(db_path: str | None) -> None:
392388
393389 # Auto-detect symbol-only builds from the last published ingestion run
394390 require_content = True
391+ expected_versions : list [str ] | None = None
395392 try :
396393 ro_conn = get_readonly_connection (target )
397394 row = ro_conn .execute (
398- "SELECT notes FROM ingestion_runs "
395+ "SELECT version, notes FROM ingestion_runs "
399396 "WHERE status = 'published' ORDER BY id DESC LIMIT 1"
400397 ).fetchone ()
401398 ro_conn .close ()
402- if row and row [0 ] and "build_mode=symbol_only" in row [0 ]:
399+ if row and row [0 ]:
400+ expected_versions = parse_expected_versions (row [0 ])
401+ if row and row [1 ] and "build_mode=symbol_only" in row [1 ]:
403402 require_content = False
404403 logger .info ("Detected symbol-only build — skipping content checks" )
405- except Exception :
406- pass # If we can't read the metadata, default to full validation
407-
408- passed , messages = run_smoke_tests (target , require_content = require_content )
404+ except Exception as e :
405+ # If we can't read the metadata, default to full validation
406+ logger .debug ("Could not read ingestion_runs metadata: %s" , e )
407+
408+ passed , messages = run_smoke_tests (
409+ target ,
410+ require_content = require_content ,
411+ expected_versions = expected_versions ,
412+ )
409413
410414 for msg in messages :
411415 if msg .startswith ("OK:" ):
0 commit comments