зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1454640 - [docs] Memoize the result of processing sphinx moz.build variables r=mshal
Now that we can rebuild docs with the liveserver, there are some optimizations we should make. One of those is processing the sphinx moz.build variables. This patch makes sure we don't re-process moz.build if we've already done so in a previous rebuild. MozReview-Commit-ID: 2AIr1KeAPQV --HG-- extra : source : 30b4083534b51213a1b9fe0d86f996cfa0e7fa54
This commit is contained in:
Родитель
03da91b713
Коммит
a33ec550e5
|
@ -8,6 +8,7 @@ import os
|
|||
|
||||
from mozbuild.base import MozbuildObject
|
||||
from mozbuild.frontend.reader import BuildReader
|
||||
from mozbuild.util import memoize
|
||||
from mozpack.copier import FileCopier
|
||||
from mozpack.files import FileFinder
|
||||
from mozpack.manifests import InstallManifest
|
||||
|
@ -21,6 +22,41 @@ build = MozbuildObject.from_environment(cwd=here)
|
|||
MAIN_DOC_PATH = os.path.join(build.topsrcdir, 'tools', 'docs')
|
||||
|
||||
|
||||
@memoize
|
||||
def read_build_config(docdir):
|
||||
"""Read the active build config and return the relevant doc paths.
|
||||
|
||||
The return value is cached so re-generating with the same docdir won't
|
||||
invoke the build system a second time."""
|
||||
trees = {}
|
||||
python_package_dirs = set()
|
||||
|
||||
# Reading the Sphinx variables doesn't require a full build context.
|
||||
# Only define the parts we need.
|
||||
class fakeconfig(object):
|
||||
topsrcdir = build.topsrcdir
|
||||
|
||||
reader = BuildReader(fakeconfig())
|
||||
for path, name, key, value in reader.find_sphinx_variables():
|
||||
reldir = os.path.join(os.path.dirname(path), value)
|
||||
|
||||
if name == 'SPHINX_TREES':
|
||||
assert key
|
||||
if key.startswith('/'):
|
||||
key = key[1:]
|
||||
else:
|
||||
key = os.path.join(reldir, key)
|
||||
|
||||
if key in trees:
|
||||
raise Exception('%s has already been registered as a destination.' % key)
|
||||
trees[key] = reldir
|
||||
|
||||
if name == 'SPHINX_PYTHON_PACKAGE_DIRS':
|
||||
python_package_dirs.add(reldir)
|
||||
|
||||
return trees, python_package_dirs
|
||||
|
||||
|
||||
class _SphinxManager(object):
|
||||
"""Manages the generation of Sphinx documentation for the tree."""
|
||||
|
||||
|
@ -29,58 +65,18 @@ class _SphinxManager(object):
|
|||
self.conf_py_path = os.path.join(main_path, 'conf.py')
|
||||
self.index_path = os.path.join(main_path, 'index.rst')
|
||||
|
||||
self._trees = {}
|
||||
self._python_package_dirs = set()
|
||||
|
||||
# Instance variables that get set in self.generate_docs()
|
||||
self.staging_dir = None
|
||||
|
||||
def read_build_config(self):
|
||||
"""Read the active build config and add docs to this instance."""
|
||||
|
||||
# Reading the Sphinx variables doesn't require a full build context.
|
||||
# Only define the parts we need.
|
||||
class fakeconfig(object):
|
||||
def __init__(self, topsrcdir):
|
||||
self.topsrcdir = topsrcdir
|
||||
|
||||
config = fakeconfig(self.topsrcdir)
|
||||
reader = BuildReader(config)
|
||||
|
||||
for path, name, key, value in reader.find_sphinx_variables():
|
||||
reldir = os.path.dirname(path)
|
||||
if name == 'SPHINX_TREES':
|
||||
assert key
|
||||
if key.startswith('/'):
|
||||
key = key[1:]
|
||||
else:
|
||||
key = os.path.join(reldir, key)
|
||||
self.add_tree(os.path.join(reldir, value), key)
|
||||
|
||||
if name == 'SPHINX_PYTHON_PACKAGE_DIRS':
|
||||
self.add_python_package_dir(os.path.join(reldir, value))
|
||||
|
||||
def add_tree(self, source_dir, dest_dir):
|
||||
"""Add a directory from where docs should be sourced."""
|
||||
if dest_dir in self._trees:
|
||||
raise Exception('%s has already been registered as a destination.'
|
||||
% dest_dir)
|
||||
|
||||
self._trees[dest_dir] = source_dir
|
||||
|
||||
def add_python_package_dir(self, source_dir):
|
||||
"""Add a directory containing Python packages.
|
||||
|
||||
Added directories will have Python API docs generated automatically.
|
||||
"""
|
||||
self._python_package_dirs.add(source_dir)
|
||||
self.trees = None
|
||||
self.python_package_dirs = None
|
||||
|
||||
def generate_docs(self, app):
|
||||
"""Generate/stage documentation."""
|
||||
self.staging_dir = os.path.join(app.outdir, '_staging')
|
||||
|
||||
app.info('Reading Sphinx metadata from build configuration')
|
||||
self.read_build_config()
|
||||
self.trees, self.python_package_dirs = read_build_config(app.srcdir)
|
||||
|
||||
app.info('Staging static documentation')
|
||||
self._synchronize_docs()
|
||||
app.info('Generating Python API documentation')
|
||||
|
@ -91,7 +87,7 @@ class _SphinxManager(object):
|
|||
out_dir = os.path.join(self.staging_dir, 'python')
|
||||
base_args = ['sphinx', '--no-toc', '-o', out_dir]
|
||||
|
||||
for p in sorted(self._python_package_dirs):
|
||||
for p in sorted(self.python_package_dirs):
|
||||
full = os.path.join(self.topsrcdir, p)
|
||||
|
||||
finder = FileFinder(full)
|
||||
|
@ -110,7 +106,7 @@ class _SphinxManager(object):
|
|||
|
||||
m.add_link(self.conf_py_path, 'conf.py')
|
||||
|
||||
for dest, source in sorted(self._trees.items()):
|
||||
for dest, source in sorted(self.trees.items()):
|
||||
source_dir = os.path.join(self.topsrcdir, source)
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for f in files:
|
||||
|
@ -126,10 +122,10 @@ class _SphinxManager(object):
|
|||
with open(self.index_path, 'rb') as fh:
|
||||
data = fh.read()
|
||||
|
||||
indexes = ['%s/index' % p for p in sorted(self._trees.keys())]
|
||||
indexes = ['%s/index' % p for p in sorted(self.trees.keys())]
|
||||
indexes = '\n '.join(indexes)
|
||||
|
||||
packages = [os.path.basename(p) for p in self._python_package_dirs]
|
||||
packages = [os.path.basename(p) for p in self.python_package_dirs]
|
||||
packages = ['python/%s' % p for p in packages]
|
||||
packages = '\n '.join(sorted(packages))
|
||||
data = data.format(indexes=indexes, python_packages=packages)
|
||||
|
|
Загрузка…
Ссылка в новой задаче