mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
ffb069ffd5
Previously, code for staging the Sphinx documentation from moz.build metadata lived in a mach command and in the moztreedocs module. This patch moves the invocation to the Sphinx extension. When the code is part of the Sphinx extension, it will run when executed with sphinx-build. This is a prerequisite to getting RTD working, since sphinx-build is the only supported entrypoint for generating documentation there. With this patch, we can now invoke sphinx-build to build the documentation. The `mach build-docs` command is no longer needed. --HG-- extra : rebase_source : 86e76c7d598ffa23dae858254eecedbdd12706a4 extra : histedit_source : 1826aa5ddfafdff62847cc293d1f0950b236caac
127 lines
4.4 KiB
Python
127 lines
4.4 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, # You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import os
|
|
|
|
from mozbuild.frontend.reader import BuildReader
|
|
from mozpack.copier import FileCopier
|
|
from mozpack.files import FileFinder
|
|
from mozpack.manifests import InstallManifest
|
|
|
|
import sphinx
|
|
import sphinx.apidoc
|
|
|
|
|
|
class SphinxManager(object):
|
|
"""Manages the generation of Sphinx documentation for the tree."""
|
|
|
|
def __init__(self, topsrcdir, main_path, output_dir):
|
|
self._topsrcdir = topsrcdir
|
|
self._output_dir = output_dir
|
|
self._docs_dir = os.path.join(output_dir, '_staging')
|
|
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()
|
|
|
|
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
|
|
self.add_tree(os.path.join(reldir, value),
|
|
os.path.join(reldir, 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)
|
|
|
|
def generate_docs(self, app):
|
|
"""Generate/stage documentation."""
|
|
app.info('Reading Sphinx metadata from build configuration')
|
|
self.read_build_config()
|
|
app.info('Staging static documentation')
|
|
self._synchronize_docs()
|
|
app.info('Generating Python API documentation')
|
|
self._generate_python_api_docs()
|
|
|
|
def _generate_python_api_docs(self):
|
|
"""Generate Python API doc files."""
|
|
out_dir = os.path.join(self._docs_dir, 'python')
|
|
base_args = ['sphinx', '--no-toc', '-o', out_dir]
|
|
|
|
for p in sorted(self._python_package_dirs):
|
|
full = os.path.join(self._topsrcdir, p)
|
|
|
|
finder = FileFinder(full, find_executables=False)
|
|
dirs = {os.path.dirname(f[0]) for f in finder.find('**')}
|
|
|
|
excludes = {d for d in dirs if d.endswith('test')}
|
|
|
|
args = list(base_args)
|
|
args.append(full)
|
|
args.extend(excludes)
|
|
|
|
sphinx.apidoc.main(args)
|
|
|
|
def _synchronize_docs(self):
|
|
m = InstallManifest()
|
|
|
|
m.add_symlink(self._conf_py_path, 'conf.py')
|
|
|
|
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:
|
|
source_path = os.path.join(root, f)
|
|
rel_source = source_path[len(source_dir) + 1:]
|
|
|
|
m.add_symlink(source_path, os.path.join(dest, rel_source))
|
|
|
|
copier = FileCopier()
|
|
m.populate_registry(copier)
|
|
copier.copy(self._docs_dir)
|
|
|
|
with open(self._index_path, 'rb') as fh:
|
|
data = fh.read()
|
|
|
|
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 = ['python/%s' % p for p in packages]
|
|
packages = '\n '.join(sorted(packages))
|
|
data = data.format(indexes=indexes, python_packages=packages)
|
|
|
|
with open(os.path.join(self._docs_dir, 'index.rst'), 'wb') as fh:
|
|
fh.write(data)
|