35a2bf9d90
Background: This is a follow-up to the PR that adds sphinx docs. Read the Docs is a hosting platform for documentation, primarily Python docs. It supports builds at commit time as well as at specific git labels to support versioned docs. I have claimed the protobuf.readthedocs.io project and can add any Googlers who need access to be able to configure and trigger builds. https://readthedocs.org/projects/protobuf/builds/ It's also relatively easy to create a new project to test the documentation builds from a fork, such as https://readthedocs.org/projects/tswast-protobuf/builds/ About this change: Once web hooks are configured, Read the Docs will automatically build the docs for the latest changes on the master branch. I needed to update `python/setup.py` to support installation from the root of the repository because Read the Docs does not `cd python` before installing the protobuf package with `setup.py install`. To support this, I updated the file paths to use the absolute path to files. The `__file__` special variable comes in handy for this, as it provides the path to the `setup.py` file. A banner is added to the docs when published to readthedocs. This links to the official documentation and the future home of the stable API reference on googleapis.dev.
174 lines
5.2 KiB
Python
Executable File
174 lines
5.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Protocol Buffers - Google's data interchange format
|
|
# Copyright 2008 Google Inc. All rights reserved.
|
|
# https://developers.google.com/protocol-buffers/
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# * Redistributions in binary form must reproduce the above
|
|
# copyright notice, this list of conditions and the following disclaimer
|
|
# in the documentation and/or other materials provided with the
|
|
# distribution.
|
|
# * Neither the name of Google Inc. nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
"""Script to generate a list of all modules to use in autosummary.
|
|
|
|
This script creates a ReStructured Text file for each public module in the
|
|
protobuf Python package. The script also updates the table of contents in
|
|
``docs/index.rst`` to point to these module references.
|
|
|
|
To build the docs with Sphinx:
|
|
|
|
1. Install the needed packages (``sphinx``, ``sphinxcontrib-napoleon`` for
|
|
Google-style docstring support). I've created a conda environment file to
|
|
make this easier:
|
|
|
|
.. code:: bash
|
|
|
|
conda env create -f python/docs/environment.yml
|
|
|
|
2. (Optional) Generate reference docs files and regenerate index:
|
|
|
|
.. code:: bash
|
|
|
|
cd python/docs
|
|
python generate_docs.py
|
|
|
|
3. Run Sphinx.
|
|
|
|
.. code:: bash
|
|
|
|
make html
|
|
"""
|
|
|
|
import pathlib
|
|
import re
|
|
|
|
|
|
DOCS_DIR = pathlib.Path(__file__).parent.resolve()
|
|
PYTHON_DIR = DOCS_DIR.parent
|
|
SOURCE_DIR = PYTHON_DIR / "google" / "protobuf"
|
|
SOURCE_POSIX = SOURCE_DIR.as_posix()
|
|
IGNORED_PACKAGES = (
|
|
"compiler",
|
|
"internal",
|
|
"pyext",
|
|
"util",
|
|
)
|
|
IGNORED_MODULES = (
|
|
"any_test_pb2",
|
|
"api_pb2",
|
|
"unittest",
|
|
"source_context_pb2",
|
|
"test_messages_proto3_pb2",
|
|
"test_messages_proto2",
|
|
)
|
|
TOC_REGEX = re.compile(
|
|
r"\.\. START REFTOC.*\.\. END REFTOC\.\n",
|
|
flags=re.DOTALL,
|
|
)
|
|
TOC_TEMPLATE = """.. START REFTOC, generated by generate_docs.py.
|
|
.. toctree::
|
|
|
|
{toctree}
|
|
|
|
.. END REFTOC.
|
|
"""
|
|
|
|
AUTOMODULE_TEMPLATE = """.. DO NOT EDIT, generated by generate_docs.py.
|
|
|
|
.. ifconfig:: build_env == 'readthedocs'
|
|
|
|
.. warning::
|
|
|
|
You are reading the documentation for the `latest committed changes
|
|
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
|
|
the `Protocol Buffers package for Python
|
|
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
|
|
Some features may not yet be released. Read the documentation for the
|
|
latest released package at `googleapis.dev
|
|
<https://googleapis.dev/python/protobuf/latest/>`_.
|
|
|
|
{module}
|
|
{underline}
|
|
|
|
.. automodule:: {module}
|
|
:members:
|
|
:inherited-members:
|
|
:undoc-members:
|
|
"""
|
|
|
|
|
|
def find_modules():
|
|
modules = []
|
|
for module_path in SOURCE_DIR.glob("**/*.py"):
|
|
package_posix = module_path.parent.as_posix()
|
|
if any(ignored in package_posix for ignored in IGNORED_PACKAGES):
|
|
continue
|
|
if any(ignored in module_path.stem for ignored in IGNORED_MODULES):
|
|
continue
|
|
|
|
package_name = "google.protobuf{}".format(
|
|
package_posix[len(SOURCE_POSIX) :].replace("/", ".")
|
|
)
|
|
if module_path.name == "__init__.py":
|
|
modules.append(package_name)
|
|
else:
|
|
module_name = module_path.stem
|
|
modules.append("{}.{}".format(package_name, module_name))
|
|
|
|
return modules
|
|
|
|
|
|
def write_automodule(module):
|
|
contents = AUTOMODULE_TEMPLATE.format(module=module, underline="=" * len(module),)
|
|
automodule_path = DOCS_DIR.joinpath(*module.split(".")).with_suffix(".rst")
|
|
try:
|
|
automodule_path.parent.mkdir(parents=True)
|
|
except FileExistsError:
|
|
pass
|
|
with open(automodule_path, "w") as automodule_file:
|
|
automodule_file.write(contents)
|
|
|
|
|
|
def replace_toc(modules):
|
|
toctree = [module.replace(".", "/") for module in modules]
|
|
with open(DOCS_DIR / "index.rst", "r") as index_file:
|
|
index_contents = index_file.read()
|
|
toc = TOC_TEMPLATE.format(
|
|
toctree="\n ".join(toctree)
|
|
)
|
|
index_contents = re.sub(TOC_REGEX, toc, index_contents)
|
|
with open(DOCS_DIR / "index.rst", "w") as index_file:
|
|
index_file.write(index_contents)
|
|
|
|
|
|
def main():
|
|
modules = list(sorted(find_modules()))
|
|
for module in modules:
|
|
print("Generating reference for {}".format(module))
|
|
write_automodule(module)
|
|
print("Generating index.rst")
|
|
replace_toc(modules)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|