Bug 920638 - Integrate moz.build symbols and Python API docs into Sphinx; r=mshal
authorGregory Szorc <gps@mozilla.com>
Thu, 10 Oct 2013 10:35:44 -0700
changeset 164134 1190ae280ceceafa7f5138db7388ecb26286ceee
parent 164133 714ed2e78ce290f161f5cf8e9424998245e2508d
child 164135 40c7c53fe9b065bbd8ab6a70fdc8c755d349e33d
child 170408 b6ed3352861b07ebd5b531abc1a6e7a63ecc5cd3
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmshal
bugs920638
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 920638 - Integrate moz.build symbols and Python API docs into Sphinx; r=mshal
build/docs/conf.py
build/docs/index.rst
build/docs/mozbuild-symbols.rst
build/docs/python/makeutils.rst
build/docs/python/mozbuild.action.rst
build/docs/python/mozbuild.backend.rst
build/docs/python/mozbuild.compilation.rst
build/docs/python/mozbuild.controller.rst
build/docs/python/mozbuild.frontend.rst
build/docs/python/mozbuild.rst
build/docs/python/mozpack.chrome.rst
build/docs/python/mozpack.packager.rst
build/docs/python/mozpack.rst
build/docs/python/mozversioncontrol.rst
python/mozbuild/mozbuild/frontend/mach_commands.py
python/mozbuild/mozbuild/frontend/sandbox_symbols.py
python/mozbuild/mozbuild/mach_commands.py
python/mozbuild/mozbuild/sphinx.py
--- a/build/docs/conf.py
+++ b/build/docs/conf.py
@@ -14,16 +14,17 @@ here = os.path.abspath(os.path.dirname(_
 mozilla_dir = os.path.normpath(os.path.join(here, '..', '..'))
 
 import mdn_theme
 
 extensions = [
     'sphinx.ext.autodoc',
     'sphinx.ext.graphviz',
     'sphinx.ext.todo',
+    'mozbuild.sphinx',
 ]
 
 templates_path = ['_templates']
 source_suffix = '.rst'
 master_doc = 'index'
 project = u'Mozilla Build System'
 year = datetime.now().year
 
--- a/build/docs/index.rst
+++ b/build/docs/index.rst
@@ -13,16 +13,17 @@ Overview
 Important Concepts
 ==================
 .. toctree::
    :maxdepth: 1
 
    build-overview
    Mozconfig Files <mozconfigs>
    mozbuild-files
+   mozbuild-symbols
    Profile Guided Optimization <pgo>
    slow
    environment-variables
    build-targets
    python
    test_manifests
    mozinfo
    preprocessor
@@ -35,16 +36,28 @@ mozbuild is a Python package containing 
 Mozilla build system.
 
 .. toctree::
    :maxdepth: 1
 
    mozbuild/index
    mozbuild/dumbmake
 
+Python Packages
+===============
+
+.. toctree::
+   :maxdepth: 2
+
+   python/codegen
+   python/makeutils
+   python/mozbuild
+   python/mozpack
+   python/mozversioncontrol
+
 
 Indices and tables
 ==================
 
 * :ref:`genindex`
 * :ref:`modindex`
 * :ref:`search`
 
new file mode 100644
--- /dev/null
+++ b/build/docs/mozbuild-symbols.rst
@@ -0,0 +1,7 @@
+.. _mozbuild_symbols:
+
+========================
+mozbuild Sandbox Symbols
+========================
+
+.. mozbuildsymbols:: mozbuild.frontend.sandbox_symbols
new file mode 100644
--- /dev/null
+++ b/build/docs/python/makeutils.rst
@@ -0,0 +1,7 @@
+makeutils Module
+================
+
+.. automodule:: makeutils
+    :members:
+    :undoc-members:
+    :show-inheritance:
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.action.rst
@@ -0,0 +1,35 @@
+action Package
+==============
+
+:mod:`link_deps` Module
+-----------------------
+
+.. automodule:: mozbuild.action.link_deps
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`process_install_manifest` Module
+--------------------------------------
+
+.. automodule:: mozbuild.action.process_install_manifest
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`xpccheck` Module
+----------------------
+
+.. automodule:: mozbuild.action.xpccheck
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`xpidl-process` Module
+---------------------------
+
+.. automodule:: mozbuild.action.xpidl-process
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.backend.rst
@@ -0,0 +1,35 @@
+backend Package
+===============
+
+:mod:`base` Module
+------------------
+
+.. automodule:: mozbuild.backend.base
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`common` Module
+--------------------
+
+.. automodule:: mozbuild.backend.common
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`configenvironment` Module
+-------------------------------
+
+.. automodule:: mozbuild.backend.configenvironment
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`recursivemake` Module
+---------------------------
+
+.. automodule:: mozbuild.backend.recursivemake
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.compilation.rst
@@ -0,0 +1,11 @@
+compilation Package
+===================
+
+:mod:`warnings` Module
+----------------------
+
+.. automodule:: mozbuild.compilation.warnings
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.controller.rst
@@ -0,0 +1,19 @@
+controller Package
+==================
+
+:mod:`building` Module
+----------------------
+
+.. automodule:: mozbuild.controller.building
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`clobber` Module
+---------------------
+
+.. automodule:: mozbuild.controller.clobber
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.frontend.rst
@@ -0,0 +1,51 @@
+frontend Package
+================
+
+:mod:`data` Module
+------------------
+
+.. automodule:: mozbuild.frontend.data
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`emitter` Module
+---------------------
+
+.. automodule:: mozbuild.frontend.emitter
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`mach_commands` Module
+---------------------------
+
+.. automodule:: mozbuild.frontend.mach_commands
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`reader` Module
+--------------------
+
+.. automodule:: mozbuild.frontend.reader
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`sandbox` Module
+---------------------
+
+.. automodule:: mozbuild.frontend.sandbox
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`sandbox_symbols` Module
+-----------------------------
+
+.. automodule:: mozbuild.frontend.sandbox_symbols
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozbuild.rst
@@ -0,0 +1,103 @@
+mozbuild Package
+================
+
+:mod:`base` Module
+------------------
+
+.. automodule:: mozbuild.base
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`config` Module
+--------------------
+
+.. automodule:: mozbuild.config
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`html_build_viewer` Module
+-------------------------------
+
+.. automodule:: mozbuild.html_build_viewer
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`mach_commands` Module
+---------------------------
+
+.. automodule:: mozbuild.mach_commands
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`makeutil` Module
+----------------------
+
+.. automodule:: mozbuild.makeutil
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`mozconfig` Module
+-----------------------
+
+.. automodule:: mozbuild.mozconfig
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`mozinfo` Module
+---------------------
+
+.. automodule:: mozbuild.mozinfo
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`pythonutil` Module
+------------------------
+
+.. automodule:: mozbuild.pythonutil
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`sphinx` Module
+--------------------
+
+.. automodule:: mozbuild.sphinx
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`util` Module
+------------------
+
+.. automodule:: mozbuild.util
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`virtualenv` Module
+------------------------
+
+.. automodule:: mozbuild.virtualenv
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+    mozbuild.action
+    mozbuild.backend
+    mozbuild.compilation
+    mozbuild.controller
+    mozbuild.frontend
+    mozbuild.test
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozpack.chrome.rst
@@ -0,0 +1,19 @@
+chrome Package
+==============
+
+:mod:`flags` Module
+-------------------
+
+.. automodule:: mozpack.chrome.flags
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`manifest` Module
+----------------------
+
+.. automodule:: mozpack.chrome.manifest
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozpack.packager.rst
@@ -0,0 +1,35 @@
+packager Package
+================
+
+:mod:`packager` Package
+-----------------------
+
+.. automodule:: mozpack.packager
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`formats` Module
+---------------------
+
+.. automodule:: mozpack.packager.formats
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`l10n` Module
+------------------
+
+.. automodule:: mozpack.packager.l10n
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`unpack` Module
+--------------------
+
+.. automodule:: mozpack.packager.unpack
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozpack.rst
@@ -0,0 +1,76 @@
+mozpack Package
+===============
+
+:mod:`copier` Module
+--------------------
+
+.. automodule:: mozpack.copier
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`errors` Module
+--------------------
+
+.. automodule:: mozpack.errors
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`executables` Module
+-------------------------
+
+.. automodule:: mozpack.executables
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`files` Module
+-------------------
+
+.. automodule:: mozpack.files
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`manifests` Module
+-----------------------
+
+.. automodule:: mozpack.manifests
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`mozjar` Module
+--------------------
+
+.. automodule:: mozpack.mozjar
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`path` Module
+------------------
+
+.. automodule:: mozpack.path
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`unify` Module
+-------------------
+
+.. automodule:: mozpack.unify
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+    mozpack.chrome
+    mozpack.packager
+    mozpack.test
+
new file mode 100644
--- /dev/null
+++ b/build/docs/python/mozversioncontrol.rst
@@ -0,0 +1,11 @@
+mozversioncontrol Package
+=========================
+
+:mod:`repoupdate` Module
+------------------------
+
+.. automodule:: mozversioncontrol.repoupdate
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
--- a/python/mozbuild/mozbuild/frontend/mach_commands.py
+++ b/python/mozbuild/mozbuild/frontend/mach_commands.py
@@ -1,172 +1,74 @@
 # 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 print_function, unicode_literals
 
-import textwrap
-
 from mach.decorators import (
     CommandArgument,
     CommandProvider,
     Command
 )
 
-from mozbuild.frontend.sandbox_symbols import (
-    FUNCTIONS,
-    SPECIAL_VARIABLES,
-    VARIABLES,
-    doc_to_paragraphs,
-)
-
-
-def get_doc(doc):
-    """Split documentation into summary line and everything else."""
-    paragraphs = doc_to_paragraphs(doc)
-
-    summary = paragraphs[0]
-    extra = paragraphs[1:]
-
-    return summary, extra
-
-def print_extra(extra):
-    """Prints the 'everything else' part of documentation intelligently."""
-    for para in extra:
-        for line in textwrap.wrap(para):
-            print(line)
-
-        print('')
-
-    if not len(extra):
-        print('')
+from mozbuild.base import MachCommandBase
 
 
 @CommandProvider
-class MozbuildFileCommands(object):
+class MozbuildFileCommands(MachCommandBase):
     @Command('mozbuild-reference', category='build-dev',
         description='View reference documentation on mozbuild files.')
     @CommandArgument('symbol', default=None, nargs='*',
         help='Symbol to view help on. If not specified, all will be shown.')
     @CommandArgument('--name-only', '-n', default=False, action='store_true',
         help='Print symbol names only.')
     def reference(self, symbol, name_only=False):
+        # mozbuild.sphinx imports some Sphinx modules, so we need to be sure
+        # the optional Sphinx package is installed.
+        self._activate_virtualenv()
+        self.virtualenv_manager.install_pip_package('Sphinx==1.1.3')
+
+        from mozbuild.sphinx import (
+            format_module,
+            function_reference,
+            special_reference,
+            variable_reference,
+        )
+
+        import mozbuild.frontend.sandbox_symbols as m
+
         if name_only:
-            for s in sorted(VARIABLES.keys()):
+            for s in sorted(m.VARIABLES.keys()):
                 print(s)
 
-            for s in sorted(FUNCTIONS.keys()):
+            for s in sorted(m.FUNCTIONS.keys()):
                 print(s)
 
-            for s in sorted(SPECIAL_VARIABLES.keys()):
+            for s in sorted(m.SPECIAL_VARIABLES.keys()):
                 print(s)
 
             return 0
 
         if len(symbol):
             for s in symbol:
-                if s in VARIABLES:
-                    self.variable_reference(s)
+                if s in m.VARIABLES:
+                    for line in variable_reference(s, *m.VARIABLES[s]):
+                        print(line)
                     continue
-                elif s in FUNCTIONS:
-                    self.function_reference(s)
+                elif s in m.FUNCTIONS:
+                    for line in function_reference(s, *m.FUNCTIONS[s]):
+                        print(line)
                     continue
-                elif s in SPECIAL_VARIABLES:
-                    self.special_reference(s)
+                elif s in m.SPECIAL_VARIABLES:
+                    for line in special_reference(s, *m.SPECIAL_VARIABLES[s]):
+                        print(line)
                     continue
 
                 print('Could not find symbol: %s' % s)
                 return 1
 
             return 0
 
-        print('=========')
-        print('VARIABLES')
-        print('=========')
-        print('')
-        print('This section lists all the variables that may be set ')
-        print('in moz.build files.')
-        print('')
-
-        for v in sorted(VARIABLES.keys()):
-            self.variable_reference(v)
-
-        print('=========')
-        print('FUNCTIONS')
-        print('=========')
-        print('')
-        print('This section lists all the functions that may be called ')
-        print('in moz.build files.')
-        print('')
-
-        for f in sorted(FUNCTIONS.keys()):
-            self.function_reference(f)
-
-        print('=================')
-        print('SPECIAL VARIABLES')
-        print('=================')
-        print('')
-
-        for v in sorted(SPECIAL_VARIABLES.keys()):
-            self.special_reference(v)
+        for line in format_module(m):
+            print(line)
 
         return 0
-
-    def variable_reference(self, v):
-        st_typ, in_type, default, doc, tier = VARIABLES[v]
-
-        print(v)
-        print('=' * len(v))
-        print('')
-
-        summary, extra = get_doc(doc)
-
-        print(summary)
-        print('')
-        print('Storage Type: %s' % st_typ.__name__)
-        print('Input Type: %s' % in_type.__name__)
-        print('Default Value: %s' % default)
-        print('')
-        print_extra(extra)
-
-    def function_reference(self, f):
-        attr, args, doc = FUNCTIONS[f]
-
-        print(f)
-        print('=' * len(f))
-        print('')
-
-        summary, extra = get_doc(doc)
-
-        print(summary)
-        print('')
-
-        arg_types = []
-
-        for t in args:
-            if isinstance(t, list):
-                inner_types = [t2.__name__ for t2 in t]
-                arg_types.append(' | ' .join(inner_types))
-                continue
-
-            arg_types.append(t.__name__)
-
-        arg_s = '(%s)' % ', '.join(arg_types)
-
-        print('Arguments: %s' % arg_s)
-        print('')
-        print_extra(extra)
-
-    def special_reference(self, v):
-        typ, doc = SPECIAL_VARIABLES[v]
-
-        print(v)
-        print('=' * len(v))
-        print('')
-
-        summary, extra = get_doc(doc)
-
-        print(summary)
-        print('')
-        print('Type: %s' % typ.__name__)
-        print('')
-        print_extra(extra)
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
@@ -19,44 +19,16 @@ from __future__ import unicode_literals
 
 from collections import OrderedDict
 from mozbuild.util import (
     HierarchicalStringList,
     StrictOrderingOnAppendList,
 )
 
 
-def doc_to_paragraphs(doc):
-    """Take a documentation string and converts it to paragraphs.
-
-    This normalizes the inline strings in VARIABLES and elsewhere in this file.
-
-    It returns a list of paragraphs. It is up to the caller to insert newlines
-    or to wrap long lines (e.g. by using textwrap.wrap()).
-    """
-    lines = [line.strip() for line in doc.split('\n')]
-
-    paragraphs = []
-    current = []
-    for line in lines:
-        if not len(line):
-            if len(current):
-                paragraphs.append(' '.join(current))
-                current = []
-
-            continue
-
-        current.append(line)
-
-    if len(current):
-        paragraphs.append(' '.join(current))
-
-    return paragraphs
-
-
 # This defines the set of mutable global variables.
 #
 # Each variable is a tuple of:
 #
 #   (storage_type, input_types, default_value, docs, tier)
 #
 # Tier says for which specific tier the variable has an effect.
 # Valid tiers are:
@@ -87,91 +59,94 @@ VARIABLES = {
         """C code source files.
 
         This variable contains a list of C source files to compile.
         """, 'compile'),
 
     'DEFINES': (OrderedDict, dict, OrderedDict(),
         """Dictionary of compiler defines to declare.
 
-        These are passed in to the compiler as -Dkey='value' for string values,
-        -Dkey=value for numeric values, or -Dkey if the value is True. Note
-        that for string values, the outer-level of single-quotes will be
-        consumed by the shell. If you want to have a string-literal in the
-        program, the value needs to have double-quotes.
+        These are passed in to the compiler as ``-Dkey='value'`` for string
+        values, ``-Dkey=value`` for numeric values, or ``-Dkey`` if the
+        value is True. Note that for string values, the outer-level of
+        single-quotes will be consumed by the shell. If you want to have
+        a string-literal in the program, the value needs to have
+        double-quotes.
 
-        Example:
-        DEFINES['NS_NO_XPCOM'] = True
-        DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 15
-        DEFINES['DLL_SUFFIX'] = '".so"'
+        Example::
 
-        This will result in the compiler flags -DNS_NO_XPCOM,
-        -DMOZ_EXTENSIONS_DB_SCHEMA=15, and -DDLL_SUFFIX='".so"',
-        respectively. These could also be combined into a single
-        update:
+           DEFINES['NS_NO_XPCOM'] = True
+           DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 15
+           DEFINES['DLL_SUFFIX'] = '".so"'
 
-        DEFINES.update({
-            'NS_NO_XPCOM': True,
-            'MOZ_EXTENSIONS_DB_SCHEMA': 15,
-            'DLL_SUFFIX': '".so"',
-        })
+        This will result in the compiler flags ``-DNS_NO_XPCOM``,
+        ``-DMOZ_EXTENSIONS_DB_SCHEMA=15``, and ``-DDLL_SUFFIX='".so"'``,
+        respectively. These could also be combined into a single
+        update::
+
+           DEFINES.update({
+               'NS_NO_XPCOM': True,
+               'MOZ_EXTENSIONS_DB_SCHEMA': 15,
+               'DLL_SUFFIX': '".so"',
+           })
         """, None),
 
     'DIRS': (list, list, [],
         """Child directories to descend into looking for build frontend files.
 
-        This works similarly to the DIRS variable in make files. Each str value
-        in the list is the name of a child directory. When this file is done
-        parsing, the build reader will descend into each listed directory and
-        read the frontend file there. If there is no frontend file, an error
+        This works similarly to the ``DIRS`` variable in make files. Each str
+        value in the list is the name of a child directory. When this file is
+        done parsing, the build reader will descend into each listed directory
+        and read the frontend file there. If there is no frontend file, an error
         is raised.
 
         Values are relative paths. They can be multiple directory levels
-        above or below. Use ".." for parent directories and "/" for path
+        above or below. Use ``..`` for parent directories and ``/`` for path
         delimiters.
         """, None),
 
     'EXPORT_LIBRARY': (bool, bool, False,
         """Install the library to the static libraries folder.
         """, None),
 
     'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list, [],
         """Additional component files to distribute.
 
-       This variable contains a list of files to copy into $(FINAL_TARGET)/components/.
+       This variable contains a list of files to copy into
+       ``$(FINAL_TARGET)/components/``.
         """, 'libs'),
 
     'EXTRA_JS_MODULES': (StrictOrderingOnAppendList, list, [],
         """Additional JavaScript files to distribute.
 
         This variable contains a list of files to copy into
-        $(FINAL_TARGET)/$(JS_MODULES_PATH). JS_MODULES_PATH defaults to
-        "modules" if left undefined.
+        ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. ``JS_MODULES_PATH`` defaults
+        to ``modules`` if left undefined.
         """, 'libs'),
 
     'EXTRA_PP_JS_MODULES': (StrictOrderingOnAppendList, list, [],
         """Additional JavaScript files to distribute.
 
         This variable contains a list of files to copy into
-        $(FINAL_TARGET)/$(JS_MODULES_PATH), after preprocessing.
-        JS_MODULES_PATH defaults to "modules" if left undefined.
+        ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``, after preprocessing.
+        ``JS_MODULES_PATH`` defaults to ``modules`` if left undefined.
         """, 'libs'),
 
     'EXTRA_PP_COMPONENTS': (StrictOrderingOnAppendList, list, [],
         """Javascript XPCOM files.
 
        This variable contains a list of files to preprocess.  Generated
-       files will be installed in the /components directory of the distribution.
+       files will be installed in the ``/components`` directory of the distribution.
         """, 'libs'),
 
     'CPP_UNIT_TESTS': (StrictOrderingOnAppendList, list, [],
         """C++ source files for unit tests.
 
         This is a list of C++ unit test sources. Entries must be files that
-        exist. These generally have .cpp extensions.
+        exist. These generally have ``.cpp`` extensions.
         """, 'binaries'),
 
     'FAIL_ON_WARNINGS': (bool, bool, False,
         """Whether to treat warnings as errors.
         """, None),
 
     'FORCE_SHARED_LIB': (bool, bool, False,
         """Whether the library in this directory is a shared library.
@@ -194,17 +169,18 @@ VARIABLES = {
         This variable contains a list of objective-C++ GTest unit test sources
         to compile.
         """, 'compile'),
 
     'GTEST_CPP_SOURCES': (list, list, [],
         """C++ source files for GTest unit tests.
 
         This is a list of C++ GTest unit test sources. Entries must be files
-        that exist. These generally have .cpp, .cc, or .cxx extensions.
+        that exist. These generally have ``.cpp``, ``.cc``, or ``.cxx``
+        extensions.
         """, 'compile'),
 
     'HOST_CPPSRCS': (StrictOrderingOnAppendList, list, [],
         """C++ source files to compile with the host compiler.
 
         This variable contains a list of C++ source files to compile.
         """, 'compile'),
 
@@ -214,57 +190,59 @@ VARIABLES = {
         This variable contains a list of C source files to compile.
         """, 'compile'),
 
     'IS_COMPONENT': (bool, bool, False,
         """Whether the library contains a binary XPCOM component manifest.
         """, None),
 
     'PARALLEL_DIRS': (list, list, [],
-        """A parallel version of DIRS.
+        """A parallel version of ``DIRS``.
 
         Ideally this variable does not exist. It is provided so a transition
         from recursive makefiles can be made. Once the build system has been
         converted to not use Makefile's for the build frontend, this will
         likely go away.
         """, None),
 
     'HOST_LIBRARY_NAME': (unicode, unicode, "",
         """Name of target library generated when cross compiling.
         """, 'binaries'),
 
     'JS_MODULES_PATH': (unicode, unicode, "",
-        """Sub-directory of $(FINAL_TARGET) to install EXTRA_JS_MODULES.
+        """Sub-directory of ``$(FINAL_TARGET)`` to install
+        ``EXTRA_JS_MODULES``.
 
-        EXTRA_JS_MODULES files are copied to
-        $(FINAL_TARGET)/$(JS_MODULES_PATH). This variable does not
+        ``EXTRA_JS_MODULES`` files are copied to
+        ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. This variable does not
         need to be defined if the desired destination directory is
-        $(FINAL_TARGET)/modules.
+        ``$(FINAL_TARGET)/modules``.
         """, None),
 
     'LIBRARY_NAME': (unicode, unicode, "",
         """The name of the library generated for a directory.
 
-        Example:
-        In example/components/moz.build,
-        LIBRARY_NAME = 'xpcomsample'
-        would generate example/components/libxpcomsample.so on Linux, or
-        example/components/xpcomsample.lib on Windows.
+        In ``example/components/moz.build``,::
+
+           LIBRARY_NAME = 'xpcomsample'
+
+        would generate ``example/components/libxpcomsample.so`` on Linux, or
+        ``example/components/xpcomsample.lib`` on Windows.
         """, 'binaries'),
 
     'LIBS': (StrictOrderingOnAppendList, list, [],
         """Linker libraries and flags.
 
         A list of libraries and flags to include when linking.
         """, None),
 
     'LIBXUL_LIBRARY': (bool, bool, False,
         """Whether the library in this directory is linked into libxul.
 
-        Implies MOZILLA_INTERNAL_API and FORCE_STATIC_LIB.
+        Implies ``MOZILLA_INTERNAL_API`` and ``FORCE_STATIC_LIB``.
         """, None),
 
     'LOCAL_INCLUDES': (StrictOrderingOnAppendList, list, [],
         """Additional directories to be searched for include files by the compiler.
         """, None),
 
     'MSVC_ENABLE_PGO': (bool, bool, False,
         """Whether profile-guided optimization is enabled in this directory.
@@ -274,29 +252,32 @@ VARIABLES = {
         """System link libraries.
 
         This variable contains a list of system libaries to link against.
         """, None),
 
     'SDK_LIBRARY': (StrictOrderingOnAppendList, list, [],
         """Elements of the distributed SDK.
 
-        Files on this list will be copied into SDK_LIB_DIR ($DIST/sdk/lib).
+        Files on this list will be copied into ``SDK_LIB_DIR``
+        (``$DIST/sdk/lib``).
         """, None),
 
     'SHARED_LIBRARY_LIBS': (StrictOrderingOnAppendList, list, [],
         """Libraries linked into a shared library.
 
-        A list of static library paths which should be linked into the current shared library.
+        A list of static library paths which should be linked into the
+        current shared library.
         """, None),
 
     'SIMPLE_PROGRAMS': (StrictOrderingOnAppendList, list, [],
         """Generate a list of binaries from source.
 
-        A list of sources, one per program, to compile & link with libs into standalone programs.
+        A list of sources, one per program, to compile & link with libs
+        into standalone programs.
         """, 'binaries'),
 
     'SSRCS': (StrictOrderingOnAppendList, list, [],
         """Assembly source files.
 
         This variable contains a list of files to invoke the assembler on.
         """, 'compile'),
 
@@ -329,142 +310,143 @@ VARIABLES = {
         major tiers (keys in this dict) that correspond roughly to applications
         or libraries being built. e.g. base, nspr, js, platform, app. Within
         each tier are phases like export, libs, and tools. The recursive make
         backend iterates over each phase in the first tier then proceeds to the
         next tier until all tiers are exhausted.
 
         Tiers are a way of working around deficiencies in recursive make. These
         will probably disappear once we no longer rely on recursive make for
-        the build backend. They will likely be replaced by DIRS.
+        the build backend. They will likely be replaced by ``DIRS``.
 
         This variable is typically not populated directly. Instead, it is
         populated by calling add_tier_dir().
         """, None),
 
     'EXTERNAL_MAKE_DIRS': (list, list, [],
         """Directories that build with make but don't use moz.build files.
 
-        This is like DIRS except it implies that |make| is used to build the
+        This is like ``DIRS`` except it implies that ``make`` is used to build the
         directory and that the directory does not define itself with moz.build
         files.
         """, None),
 
     'PARALLEL_EXTERNAL_MAKE_DIRS': (list, list, [],
-        """Parallel version of EXTERNAL_MAKE_DIRS.
+        """Parallel version of ``EXTERNAL_MAKE_DIRS``.
         """, None),
 
     'CONFIGURE_SUBST_FILES': (StrictOrderingOnAppendList, list, [],
         """Output files that will be generated using configure-like substitution.
 
-        This is a substitute for AC_OUTPUT in autoconf. For each path in this
+        This is a substitute for ``AC_OUTPUT`` in autoconf. For each path in this
         list, we will search for a file in the srcdir having the name
-        {path}.in. The contents of this file will be read and variable patterns
-        like @foo@ will be substituted with the values of the AC_SUBST
-        variables declared during configure.
+        ``{path}.in``. The contents of this file will be read and variable
+        patterns like ``@foo@`` will be substituted with the values of the
+        ``AC_SUBST`` variables declared during configure.
         """, None),
 
     'MODULE': (unicode, unicode, "",
         """Module name.
 
         Historically, this variable was used to describe where to install header
-        files, but that feature is now handled by EXPORTS_NAMESPACES. MODULE
-        will likely be removed in the future.
+        files, but that feature is now handled by ``EXPORTS_NAMESPACES``.
+        ``MODULE`` will likely be removed in the future.
         """, None),
 
     'EXPORTS': (HierarchicalStringList, list, HierarchicalStringList(),
         """List of files to be exported, and in which subdirectories.
 
-        EXPORTS is generally used to list the include files to be exported to
-        dist/include, but it can be used for other files as well. This variable
+        ``EXPORTS`` is generally used to list the include files to be exported to
+        ``dist/include``, but it can be used for other files as well. This variable
         behaves as a list when appending filenames for export in the top-level
         directory. Files can also be appended to a field to indicate which
-        subdirectory they should be exported to. For example, to export 'foo.h'
-        to the top-level directory, and 'bar.h' to mozilla/dom/, append to
-        EXPORTS like so:
+        subdirectory they should be exported to. For example, to export
+        ``foo.h`` to the top-level directory, and ``bar.h`` to ``mozilla/dom/``,
+        append to ``EXPORTS`` like so::
 
-        EXPORTS += ['foo.h']
-        EXPORTS.mozilla.dom += ['bar.h']
+           EXPORTS += ['foo.h']
+           EXPORTS.mozilla.dom += ['bar.h']
         """, None),
 
     'PROGRAM' : (unicode, unicode, "",
         """Compiled executable name.
 
-        If the configuration token 'BIN_SUFFIX' is set, its value will be
-        automatically appended to PROGRAM. If PROGRAM already ends with
-        BIN_SUFFIX, PROGRAM will remain unchanged.
+        If the configuration token ``BIN_SUFFIX`` is set, its value will be
+        automatically appended to ``PROGRAM``. If ``PROGRAM`` already ends with
+        ``BIN_SUFFIX``, ``PROGRAM`` will remain unchanged.
         """, 'binaries'),
 
     'CPP_SOURCES': (list, list, [],
         """C++ source file list.
 
         This is a list of C++ files to be compiled. Entries must be files that
-        exist. These generally have .cpp, .cc, or .cxx extensions.
+        exist. These generally have ``.cpp``, ``.cc``, or ``.cxx`` extensions.
         """, 'compile'),
 
     'NO_DIST_INSTALL': (bool, bool, False,
         """Disable installing certain files into the distribution directory.
 
         If present, some files defined by other variables won't be
         distributed/shipped with the produced build.
         """, None),
 
     # IDL Generation.
     'XPIDL_SOURCES': (StrictOrderingOnAppendList, list, [],
         """XPCOM Interface Definition Files (xpidl).
 
         This is a list of files that define XPCOM interface definitions.
-        Entries must be files that exist. Entries are almost certainly .idl
+        Entries must be files that exist. Entries are almost certainly ``.idl``
         files.
         """, 'libs'),
 
     'XPIDL_MODULE': (unicode, unicode, "",
         """XPCOM Interface Definition Module Name.
 
-        This is the name of the .xpt file that is created by linking
-        XPIDL_SOURCES together. If unspecified, it defaults to be the same as
-        MODULE.
+        This is the name of the ``.xpt`` file that is created by linking
+        ``XPIDL_SOURCES`` together. If unspecified, it defaults to be the same
+        as ``MODULE``.
         """, None),
 
     'IPDL_SOURCES': (StrictOrderingOnAppendList, list, [],
         """IPDL source files.
 
-        These are .ipdl files that will be parsed and converted to .cpp files.
+        These are ``.ipdl`` files that will be parsed and converted to
+        ``.cpp`` files.
         """, 'export'),
 
     'WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
         """WebIDL source files.
 
-        These will be parsed and converted to .cpp and .h files.
+        These will be parsed and converted to ``.cpp`` and ``.h`` files.
         """, 'export'),
 
     'GENERATED_EVENTS_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
         """WebIDL source files for generated events.
 
-        These will be parsed and converted to .cpp and .h files.
+        These will be parsed and converted to ``.cpp`` and ``.h`` files.
         """, 'export'),
 
     'TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
          """Test WebIDL source files.
 
-         These will be parsed and converted to .cpp and .h files if tests are
-         enabled.
+         These will be parsed and converted to ``.cpp`` and ``.h`` files
+         if tests are enabled.
          """, 'export'),
 
     'GENERATED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
          """Generated WebIDL source files.
 
          These will be generated from some other files.
          """, 'export'),
 
     'PREPROCESSED_TEST_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
          """Preprocessed test WebIDL source files.
 
          These will be preprocessed, then parsed and converted to .cpp
-         and .h files if tests are enabled.
+         and ``.h`` files if tests are enabled.
          """, 'export'),
 
     'PREPROCESSED_WEBIDL_FILES': (StrictOrderingOnAppendList, list, [],
          """Preprocessed WebIDL source files.
 
          These will be preprocessed before being parsed and converted.
          """, 'export'),
 
@@ -509,35 +491,38 @@ VARIABLES = {
 #  (method attribute, (argument types), docs)
 #
 # The first element is an attribute on Sandbox that should be a function type.
 #
 FUNCTIONS = {
     'include': ('_include', (str,),
         """Include another mozbuild file in the context of this one.
 
-        This is similar to a #include in C languages. The filename passed to
+        This is similar to a ``#include`` in C languages. The filename passed to
         the function will be read and its contents will be evaluated within the
         context of the calling file.
 
         If a relative path is given, it is evaluated as relative to the file
         currently being processed. If there is a chain of multiple include(),
         the relative path computation is from the most recent/active file.
 
-        If an absolute path is given, it is evaluated from TOPSRCDIR. In other
-        words, include('/foo') references the path TOPSRCDIR + '/foo'.
+        If an absolute path is given, it is evaluated from ``TOPSRCDIR``. In
+        other words, ``include('/foo')`` references the path
+        ``TOPSRCDIR + '/foo'``.
 
         Example usage
-        -------------
+        ^^^^^^^^^^^^^
+
+        Include ``sibling.build`` from the current directory.::
 
-        # Include "sibling.build" from the current directory.
-        include('sibling.build')
+           include('sibling.build')
 
-        # Include "foo.build" from a path within the top source directory.
-        include('/elsewhere/foo.build')
+        Include ``foo.build`` from a path within the top source directory::
+
+           include('/elsewhere/foo.build')
         """),
 
     'add_tier_dir': ('_add_tier_directory', (str, [str, list], bool, bool),
         """Register a directory for tier traversal.
 
         This is the preferred way to populate the TIERS variable.
 
         Tiers are how the build system is organized. The build process is
@@ -549,30 +534,34 @@ FUNCTIONS = {
         This function is typically only called by the main moz.build file or a
         file directly included by the main moz.build file. An error will be
         raised if it is called when it shouldn't be.
 
         An error will also occur if you attempt to add the same directory to
         the same tier multiple times.
 
         Example usage
-        -------------
+        ^^^^^^^^^^^^^
+
+        Register a single directory with the 'platform' tier::
 
-        # Register a single directory with the 'platform' tier.
-        add_tier_dir('platform', 'xul')
+           add_tier_dir('platform', 'xul')
+
+        Register multiple directories with the 'app' tier.::
 
-        # Register multiple directories with the 'app' tier.
-        add_tier_dir('app', ['components', 'base'])
+           add_tier_dir('app', ['components', 'base'])
+
+        Register a directory as having static content (no dependencies)::
 
-        # Register a directory as having static content (no dependencies).
-        add_tier_dir('base', 'foo', static=True)
+           add_tier_dir('base', 'foo', static=True)
 
-        # Register a directory as having external content (same as static
-        # content, but traversed with export, libs, and tools subtiers.
-        add_tier_dir('base', 'bar', external=True)
+        Register a directory as having external content (same as static
+        content, but traversed with export, libs, and tools subtiers::
+
+           add_tier_dir('base', 'bar', external=True)
         """),
 
     'warning': ('_warning', (str,),
         """Issue a warning.
 
         Warnings are string messages that are printed during execution.
 
         Warnings are ignored during execution.
@@ -601,48 +590,48 @@ SPECIAL_VARIABLES = {
         The top object directory is the parent directory which will contain
         the output of the build. This is commonly referred to as "the object
         directory."
         """),
 
     'RELATIVEDIR': (str,
         """Constant defining the relative path of this file.
 
-        The relative path is from TOPSRCDIR. This is defined as relative to the
-        main file being executed, regardless of whether additional files have
-        been included using include().
+        The relative path is from ``TOPSRCDIR``. This is defined as relative
+        to the main file being executed, regardless of whether additional
+        files have been included using ``include()``.
         """),
 
     'SRCDIR': (str,
         """Constant defining the source directory of this file.
 
-        This is the path inside TOPSRCDIR where this file is located. It is the
-        same as TOPSRCDIR + RELATIVEDIR.
+        This is the path inside ``TOPSRCDIR`` where this file is located. It
+        is the same as ``TOPSRCDIR + RELATIVEDIR``.
         """),
 
     'OBJDIR': (str,
         """The path to the object directory for this file.
 
-        Is is the same as TOPOBJDIR + RELATIVEDIR.
+        Is is the same as ``TOPOBJDIR + RELATIVEDIR``.
         """),
 
     'CONFIG': (dict,
         """Dictionary containing the current configuration variables.
 
         All the variables defined by the configuration system are available
-        through this object. e.g. ENABLE_TESTS, CFLAGS, etc.
+        through this object. e.g. ``ENABLE_TESTS``, ``CFLAGS``, etc.
 
         Values in this container are read-only. Attempts at changing values
         will result in a run-time error.
 
         Access to an unknown variable will return None.
         """),
 
     '__builtins__': (dict,
         """Exposes Python built-in types.
 
         The set of exposed Python built-ins is currently:
 
-            True
-            False
-            None
+        - True
+        - False
+        - None
         """),
 }
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -918,25 +918,50 @@ class MachDebug(object):
 @CommandProvider
 class Documentation(MachCommandBase):
     """Helps manage in-tree documentation."""
 
     @Command('build-docs', category='build-dev',
         description='Generate documentation for the tree.')
     @CommandArgument('--format', default='html',
         help='Documentation format to write.')
+    @CommandArgument('--api-docs', action='store_true',
+        help='If specified, we will generate api docs templates for in-tree '
+            'Python. This will likely create and/or modify files in '
+            'build/docs. It is meant to be run by build maintainers when new '
+            'Python modules are added to the tree.')
     @CommandArgument('outdir', default='<DEFAULT>', nargs='?',
         help='Where to write output.')
-    def build_docs(self, format=None, outdir=None):
+    def build_docs(self, format=None, api_docs=False, outdir=None):
         self._activate_virtualenv()
 
         self.virtualenv_manager.install_pip_package('mdn-sphinx-theme==0.3')
 
+        if api_docs:
+            import sphinx.apidoc
+            outdir = os.path.join(self.topsrcdir, 'build', 'docs', 'python')
+
+            base_args = [sys.argv[0], '--no-toc', '-o', outdir]
+
+            packages = [
+                ('python/codegen',),
+                ('python/mozbuild/mozbuild', 'test'),
+                ('python/mozbuild/mozpack', 'test'),
+                ('python/mozversioncontrol/mozversioncontrol',),
+            ]
+
+            for package in packages:
+                extra_args = [os.path.join(self.topsrcdir, package[0])]
+                extra_args.extend(package[1:])
+
+                sphinx.apidoc.main(base_args + extra_args)
+
+            return 0
+
         import sphinx
-
         if outdir == '<DEFAULT>':
             outdir = os.path.join(self.topobjdir, 'docs', format)
 
         args = [
             sys.argv[0],
             '-b', format,
             os.path.join(self.topsrcdir, 'build', 'docs'),
             outdir,
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/sphinx.py
@@ -0,0 +1,155 @@
+# 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 absolute_import
+
+import importlib
+
+from sphinx.util.compat import Directive
+from sphinx.util.docstrings import prepare_docstring
+
+
+def function_reference(f, attr, args, doc):
+    lines = []
+
+    lines.extend([
+        f,
+        '-' * len(f),
+        '',
+    ])
+
+    docstring = prepare_docstring(doc)
+
+    lines.extend([
+        docstring[0],
+        '',
+    ])
+
+    arg_types = []
+
+    for t in args:
+        if isinstance(t, list):
+            inner_types = [t2.__name__ for t2 in t]
+            arg_types.append(' | ' .join(inner_types))
+            continue
+
+        arg_types.append(t.__name__)
+
+    arg_s = '(%s)' % ', '.join(arg_types)
+
+    lines.extend([
+        ':Arguments: %s' % arg_s,
+        '',
+    ])
+
+    lines.extend(docstring[1:])
+    lines.append('')
+
+    return lines
+
+
+def variable_reference(v, st_type, in_type, default, doc, tier):
+    lines = [
+        v,
+        '-' * len(v),
+        '',
+    ]
+
+    docstring = prepare_docstring(doc)
+
+    lines.extend([
+        docstring[0],
+        '',
+    ])
+
+    lines.extend([
+        ':Storage Type: ``%s``' % st_type.__name__,
+        ':Input Type: ``%s``' % in_type.__name__,
+        ':Default Value: %s' % default,
+        '',
+    ])
+
+    lines.extend(docstring[1:])
+    lines.append('')
+
+    return lines
+
+
+def special_reference(v, typ, doc):
+    lines = [
+        v,
+        '-' * len(v),
+        '',
+    ]
+
+    docstring = prepare_docstring(doc)
+
+    lines.extend([
+        docstring[0],
+        '',
+        ':Type: ``%s``' % typ.__name__,
+        '',
+    ])
+
+    lines.extend(docstring[1:])
+    lines.append('')
+
+    return lines
+
+
+def format_module(m):
+    lines = []
+    lines.extend([
+        'Variables',
+        '=========',
+        '',
+    ])
+
+    for v in sorted(m.VARIABLES):
+        lines.extend(variable_reference(v, *m.VARIABLES[v]))
+
+    lines.extend([
+        'Functions',
+        '=========',
+        '',
+    ])
+
+    for func in sorted(m.FUNCTIONS):
+        lines.extend(function_reference(func, *m.FUNCTIONS[func]))
+
+    lines.extend([
+        'Special Variables',
+        '=================',
+        '',
+    ])
+
+    for v in sorted(m.SPECIAL_VARIABLES):
+        lines.extend(special_reference(v, *m.SPECIAL_VARIABLES[v]))
+
+    return lines
+
+
+class MozbuildSymbols(Directive):
+    """Directive to insert mozbuild sandbox symbol information."""
+
+    required_arguments = 1
+
+    def run(self):
+        module = importlib.import_module(self.arguments[0])
+        fname = module.__file__
+        if fname.endswith('.pyc'):
+            fname = fname[0:-1]
+
+        self.state.document.settings.record_dependencies.add(fname)
+
+        # We simply format out the documentation as rst then feed it back
+        # into the parser for conversion. We don't even emit ourselves, so
+        # there's no record of us.
+        self.state_machine.insert_input(format_module(module), fname)
+
+        return []
+
+
+def setup(app):
+    app.add_directive('mozbuildsymbols', MozbuildSymbols)