Changelog¶
0.1.1¶
- Released:
2026-06-14
Added per-mount
path_checkoption ("error"default /"warn"/"off"). Directives inside a mounted bundle that reference a file outside the bundle root (a leading-slash path, or one that climbs out with..) now fail the build by default, keeping bundles self-contained. Setpath_check = "warn"or"off"to relax it.Documented and added regression tests confirming that build diagnostics (warnings and errors) for mounted documents are emitted with the absolute path of the external source file plus a line number — so an editor’s problem matcher, a terminal Ctrl+click, or a CI annotation can jump straight to the real source. Covered across docutils-native directives, Sphinx core, and third-party extensions (
sphinxcontrib.plantuml/sphinxcontrib.mermaid). See Diagnostic locations are absolute.Added regression tests confirming Sphinx’s incremental rebuild re-reads mounted documents when their content changes. Two paths are covered: a file-list-mounted doc whose own source is edited, and a mounted doc whose referenced file changes while the doc itself is untouched — the latter across every file-referencing directive (
literalinclude,include,csv-table :file:,raw :file:,image,figure,graphviz,uml,mermaid). Detection needs no extension code: it rides on the absolute external paths recorded inProject._docname_to_pathandenv.dependencies, which Sphinx stats on each rebuild.The CI test matrix now exercises Sphinx 8 on Python 3.12, alongside the existing Sphinx 7 and Sphinx 9 cells. The matrix previously covered only the lower (
>=7.4) and upper (<10) bounds of the supported Sphinx range, leaving Sphinx 8 in the middle untested; all three major versions are now verified on every CI run.
0.1.0¶
- Released:
2026-05-21
Initial release of sphinx-mounts — a Sphinx extension that mounts external
RST source trees into a Sphinx build without copying or symlinking the
files. Sources stay where they live (a Bazel bazel-bin/ output tree, a
sibling repository, a generated cache directory) and are made visible to
Sphinx at a configured docname prefix.
Mount-aware project¶
Mount-aware
sphinx.project.Projectsubclass that injects external docnames atbuilder-initedtime. Sphinx’s reader opens the absolute external path directly: storing absolute paths inProject._docname_to_pathmeans that when Sphinx later computessrcdir / stored_paththe absolute right operand wins and the external file is read in place.Discovery iterates whatever Sphinx has registered in
source_suffix, so any format with a parser extension is supported:.rstby default,.mdwhenmyst_parseris loaded, plus anything else a project plugs in. See Source formats: RST, Markdown, and anything Sphinx knows about.Two mount modes, mutually exclusive per mount: directory mode (
dir = "..."walks a tree) and file-list mode (files = [...]cherry-picks individual files, possibly just one). File-list basenames become flat docname tails undermount_at; every listed file must have an extension Sphinx knows about.mount_atis now optional. When omitted, the bundle mounts at the host project root — a bundle filetutorial.rstbecomes docnametutorial. Useful when you want to pull a whole directory in as a source bundle with no prefix renaming.New per-mount
strict_mount_atboolean (defaultfalse) makes a host directory at<srcdir>/<mount_at>/a build error before file discovery. The default per-docname collision check stays the only gate whenstrict_mount_atis left off; the new flag is for tightly-disciplined projects that want any host directory at the mount point to fail loudly rather than pass silently. Rejected at config validation when combined with a root mount, since the host srcdir always exists. See Strict mode: rejecting a pre-existing host directory.Relative paths declared in
ubproject.tomlare anchored to the TOML file’s own directory (not toconfdir). The TOML is therefore self-describing — placing it in a subdirectory of confdir no longer silently re-anchors its paths.conf.py-declared mounts still anchor toconfdiras before. See How relative paths in dir / files are resolved.Directory mounts are now walked with ignore-python — the same Rust
ignorecrate binding that drives sphinx-codelinks and ubCode. In-bundle.gitignoreand.ignorefiles are respected by default; parent directories are not scanned (so mounts under a host-gitignored path such asbazel-bin/still discover their files). See File discovery.Per-mount
include/excludelists replace the earlierexclude_patternsfield, aligning with sphinx-codelinks’source_discoverschema (includeallowlist,excludedenylist, both gitignore-style). A new per-mountgitignoreboolean (defaulttrue) lets a project opt out of honouring a sibling repository’s.gitignorewhen mounting it.Bazel integration test fixture and
tox -e bazelenvironment.
Declarative TOML config¶
New
mounts_from_tomlconfig value (default"ubproject.toml") names a TOML file relative toconfdir. The TOML file is the primary config target, so IDE plugins, language servers, and other non-Python tooling can read the mount mapping without evaluatingconf.py. Schema is a top-level[[mounts]]array of tables. See Configuration for the rationale.mounts = [...]inconf.pycontinues to work as a fallback when no TOML file is present, or whenmounts_from_tomlis set toNone. If both are present, the TOML file wins.
Toctree integration¶
New
attach_toper-mount option auto-wires the mount’s entry doc into a host toctree at build time, so the host doc can stay buildable when the mount is absent.toctree_index(0-based) picks which toctree in the host doc to extend; an out-of-range index fails the build loudly with anExtensionError.entry_doc(default"index") selects which file inside the mount is wired in.If
attach_tois set and the host doc contains no toctree, the extension adds one at the end of the first top-level section. The host keeps full control of its content prefix; injected references are always at the bottom. See Toctree integration.