"""The dependencies collector components for sphinx.environment."""
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
from sphinx.environment.collectors import EnvironmentCollector
from sphinx.util.osutil import _relative_path, fs_encoding
if TYPE_CHECKING:
from collections.abc import Set
from docutils import nodes
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from sphinx.util.typing import ExtensionMetadata
class DependenciesCollector(EnvironmentCollector):
"""dependencies collector for sphinx.environment."""
def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None:
env.dependencies.pop(docname, None)
def merge_other(
self,
app: Sphinx,
env: BuildEnvironment,
docnames: Set[str],
other: BuildEnvironment,
) -> None:
for docname in docnames:
if docname in other.dependencies:
env.dependencies[docname] = other.dependencies[docname]
def process_doc(self, app: Sphinx, doctree: nodes.document) -> None:
"""Process docutils-generated dependency info."""
cwd = Path.cwd()
deps = doctree.settings.record_dependencies
if not deps:
return
for dep in deps.list:
# the dependency path is relative to the working dir, so get
# one relative to the srcdir
if isinstance(dep, bytes):
dep = dep.decode(fs_encoding)
relpath = _relative_path(cwd / dep, app.srcdir)
app.env.note_dependency(relpath)
def setup(app: Sphinx) -> ExtensionMetadata:
app.add_env_collector(DependenciesCollector)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}