mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Close #8681: viewcode: Support incremental build
Now viewcode supports incremental build. It generates HTML files only when the original python code is updated from last build.
This commit is contained in:
parent
596dfba841
commit
2e01c34acf
1
CHANGES
1
CHANGES
@ -32,6 +32,7 @@ Features added
|
||||
type
|
||||
* #6241: mathjax: Include mathjax.js only on the document using equations
|
||||
* #8651: std domain: cross-reference for a rubric having inline item is broken
|
||||
* #8681: viewcode: Support incremental build
|
||||
* #8132: Add :confval:`project_copyright` as an alias of :confval:`copyright`
|
||||
* #207: Now :confval:`highlight_language` supports multiple languages
|
||||
* #2030: :rst:dir:`code-block` and :rst:dir:`literalinclude` supports automatic
|
||||
|
@ -9,7 +9,8 @@
|
||||
"""
|
||||
|
||||
import traceback
|
||||
from typing import Any, Dict, Iterable, Iterator, Set, Tuple
|
||||
from os import path
|
||||
from typing import Any, Dict, Iterable, Iterator, Optional, Set, Tuple, cast
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
@ -17,6 +18,7 @@ from docutils.nodes import Element, Node
|
||||
import sphinx
|
||||
from sphinx import addnodes
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.pycode import ModuleAnalyzer
|
||||
@ -138,6 +140,40 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnod
|
||||
return None
|
||||
|
||||
|
||||
def get_module_filename(app: Sphinx, modname: str) -> Optional[str]:
|
||||
"""Get module filename for *modname*."""
|
||||
source_info = app.emit_firstresult('viewcode-find-source', modname)
|
||||
if source_info:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
filename, source = ModuleAnalyzer.get_module_source(modname)
|
||||
return filename
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def should_generate_module_page(app: Sphinx, modname: str) -> bool:
|
||||
"""Check generation of module page is needed."""
|
||||
module_filename = get_module_filename(app, modname)
|
||||
if module_filename is None:
|
||||
# Always (re-)generate module page when module filename is not found.
|
||||
return True
|
||||
|
||||
builder = cast(StandaloneHTMLBuilder, app.builder)
|
||||
basename = modname.replace('.', '/') + builder.out_suffix
|
||||
page_filename = path.join(app.outdir, '_modules/', basename)
|
||||
|
||||
try:
|
||||
if path.getmtime(module_filename) <= path.getmtime(page_filename):
|
||||
# generation is not needed if the HTML page is newer than module file.
|
||||
return False
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def collect_pages(app: Sphinx) -> Iterator[Tuple[str, Dict[str, Any], str]]:
|
||||
env = app.builder.env
|
||||
if not hasattr(env, '_viewcode_modules'):
|
||||
@ -154,6 +190,9 @@ def collect_pages(app: Sphinx) -> Iterator[Tuple[str, Dict[str, Any], str]]:
|
||||
app.verbosity, lambda x: x[0]):
|
||||
if not entry:
|
||||
continue
|
||||
if not should_generate_module_page(app, modname):
|
||||
continue
|
||||
|
||||
code, tags, used, refname = entry
|
||||
# construct a page name for the highlighted source
|
||||
pagename = '_modules/' + modname.replace('.', '/')
|
||||
|
Loading…
Reference in New Issue
Block a user