Add DependenciesCollector

This commit is contained in:
Takeshi KOMIYA 2016-12-18 00:12:54 +09:00
parent d1405e4774
commit 08766abf52
3 changed files with 64 additions and 24 deletions

View File

@ -97,12 +97,14 @@ builtin_extensions = (
'sphinx.domains.python', 'sphinx.domains.python',
'sphinx.domains.rst', 'sphinx.domains.rst',
'sphinx.domains.std', 'sphinx.domains.std',
'sphinx.environment.collectors.asset',
'sphinx.directives', 'sphinx.directives',
'sphinx.directives.code', 'sphinx.directives.code',
'sphinx.directives.other', 'sphinx.directives.other',
'sphinx.directives.patches', 'sphinx.directives.patches',
'sphinx.roles', 'sphinx.roles',
# collectors should be loaded by specific order
'sphinx.environment.collectors.dependencies',
'sphinx.environment.collectors.asset',
) # type: Tuple[unicode, ...] ) # type: Tuple[unicode, ...]
CONFIG_FILENAME = 'conf.py' CONFIG_FILENAME = 'conf.py'

View File

@ -26,7 +26,7 @@ from six.moves import cPickle as pickle
from docutils import nodes from docutils import nodes
from docutils.io import NullOutput from docutils.io import NullOutput
from docutils.core import Publisher from docutils.core import Publisher
from docutils.utils import Reporter, relative_path, get_source_line from docutils.utils import Reporter, get_source_line
from docutils.parsers.rst import roles from docutils.parsers.rst import roles
from docutils.parsers.rst.languages import en as english from docutils.parsers.rst.languages import en as english
from docutils.frontend import OptionParser from docutils.frontend import OptionParser
@ -37,7 +37,7 @@ from sphinx.util import logging
from sphinx.util import get_matching_docs, docname_join, FilenameUniqDict, status_iterator from sphinx.util import get_matching_docs, docname_join, FilenameUniqDict, status_iterator
from sphinx.util.nodes import clean_astext, WarningStream, is_translatable, \ from sphinx.util.nodes import clean_astext, WarningStream, is_translatable, \
process_only_nodes process_only_nodes
from sphinx.util.osutil import SEP, getcwd, fs_encoding, ensuredir from sphinx.util.osutil import SEP, ensuredir
from sphinx.util.i18n import find_catalog_files from sphinx.util.i18n import find_catalog_files
from sphinx.util.console import bold # type: ignore from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import sphinx_domains from sphinx.util.docutils import sphinx_domains
@ -313,7 +313,6 @@ class BuildEnvironment(object):
self.all_docs.pop(docname, None) self.all_docs.pop(docname, None)
self.reread_always.discard(docname) self.reread_always.discard(docname)
self.metadata.pop(docname, None) self.metadata.pop(docname, None)
self.dependencies.pop(docname, None)
self.titles.pop(docname, None) self.titles.pop(docname, None)
self.longtitles.pop(docname, None) self.longtitles.pop(docname, None)
@ -340,8 +339,6 @@ class BuildEnvironment(object):
if docname in other.reread_always: if docname in other.reread_always:
self.reread_always.add(docname) self.reread_always.add(docname)
self.metadata[docname] = other.metadata[docname] self.metadata[docname] = other.metadata[docname]
if docname in other.dependencies:
self.dependencies[docname] = other.dependencies[docname]
self.titles[docname] = other.titles[docname] self.titles[docname] = other.titles[docname]
self.longtitles[docname] = other.longtitles[docname] self.longtitles[docname] = other.longtitles[docname]
@ -728,7 +725,6 @@ class BuildEnvironment(object):
doctree = pub.document doctree = pub.document
# post-processing # post-processing
self.process_dependencies(docname, doctree)
self.process_metadata(docname, doctree) self.process_metadata(docname, doctree)
self.create_title_from(docname, doctree) self.create_title_from(docname, doctree)
for manager in itervalues(self.managers): for manager in itervalues(self.managers):
@ -857,23 +853,6 @@ class BuildEnvironment(object):
# post-processing of read doctrees # post-processing of read doctrees
def process_dependencies(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
"""Process docutils-generated dependency info."""
cwd = getcwd()
frompath = path.join(path.normpath(self.srcdir), 'dummy')
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(frompath,
path.normpath(path.join(cwd, dep)))
self.dependencies[docname].add(relpath)
def process_metadata(self, docname, doctree): def process_metadata(self, docname, doctree):
# type: (unicode, nodes.Node) -> None # type: (unicode, nodes.Node) -> None
"""Process the docinfo part of the doctree as metadata. """Process the docinfo part of the doctree as metadata.

View File

@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
"""
sphinx.environment.collectors.dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The dependencies collector components for sphinx.environment.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from os import path
from docutils.utils import relative_path
from sphinx.util.osutil import getcwd, fs_encoding
from sphinx.environment.collectors import EnvironmentCollector
if False:
# For type annotation
from docutils import nodes # NOQA
from sphinx.sphinx import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA
class DependenciesCollector(EnvironmentCollector):
"""dependencies collector for sphinx.environment."""
def clear_doc(self, app, env, docname):
# type: (Sphinx, BuildEnvironment, unicode) -> None
env.dependencies.pop(docname, None)
def merge_other(self, app, env, docnames, other):
# type: (Sphinx, BuildEnvironment, Set[unicode], BuildEnvironment) -> None
for docname in docnames:
if docname in other.dependencies:
env.dependencies[docname] = other.dependencies[docname]
def process_doc(self, app, doctree):
# type: (Sphinx, nodes.Node) -> None
"""Process docutils-generated dependency info."""
cwd = getcwd()
frompath = path.join(path.normpath(app.srcdir), 'dummy')
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(frompath,
path.normpath(path.join(cwd, dep)))
app.env.dependencies[app.env.docname].add(relpath)
def setup(app):
# type: (Sphinx) -> None
app.add_env_collector(DependenciesCollector)