tools/docs/moztreedocs/__init__.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/docs/moztreedocs/__init__.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,113 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, # You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +from __future__ import unicode_literals
     1.9 +
    1.10 +import os
    1.11 +
    1.12 +from mozpack.copier import FileCopier
    1.13 +from mozpack.files import FileFinder
    1.14 +from mozpack.manifests import InstallManifest
    1.15 +
    1.16 +import sphinx
    1.17 +import sphinx.apidoc
    1.18 +
    1.19 +
    1.20 +class SphinxManager(object):
    1.21 +    """Manages the generation of Sphinx documentation for the tree."""
    1.22 +
    1.23 +    def __init__(self, topsrcdir, main_path, output_dir):
    1.24 +        self._topsrcdir = topsrcdir
    1.25 +        self._output_dir = output_dir
    1.26 +        self._conf_py_path = os.path.join(main_path, 'conf.py')
    1.27 +        self._index_path = os.path.join(main_path, 'index.rst')
    1.28 +        self._trees = {}
    1.29 +        self._python_package_dirs = set()
    1.30 +
    1.31 +    def add_tree(self, source_dir, dest_dir):
    1.32 +        """Add a directory from where docs should be sourced."""
    1.33 +        if dest_dir in self._trees:
    1.34 +            raise Exception('%s has already been registered as a destination.'
    1.35 +                % dest_dir)
    1.36 +
    1.37 +        self._trees[dest_dir] = source_dir
    1.38 +
    1.39 +    def add_python_package_dir(self, source_dir):
    1.40 +        """Add a directory containing Python packages.
    1.41 +
    1.42 +        Added directories will have Python API docs generated automatically.
    1.43 +        """
    1.44 +        self._python_package_dirs.add(source_dir)
    1.45 +
    1.46 +    def generate_docs(self, fmt):
    1.47 +        """Generate documentation using Sphinx."""
    1.48 +        self._synchronize_docs()
    1.49 +        self._generate_python_api_docs()
    1.50 +
    1.51 +        old_env = os.environ.copy()
    1.52 +        try:
    1.53 +            os.environ['MOZILLA_DIR'] = self._topsrcdir
    1.54 +            args = [
    1.55 +                'sphinx',
    1.56 +                '-b', fmt,
    1.57 +                os.path.join(self._output_dir, 'staging'),
    1.58 +                os.path.join(self._output_dir, fmt),
    1.59 +            ]
    1.60 +
    1.61 +            return sphinx.main(args)
    1.62 +        finally:
    1.63 +            os.environ.clear()
    1.64 +            os.environ.update(old_env)
    1.65 +
    1.66 +    def _generate_python_api_docs(self):
    1.67 +        """Generate Python API doc files."""
    1.68 +        out_dir = os.path.join(self._output_dir, 'staging', 'python')
    1.69 +        base_args = ['sphinx', '--no-toc', '-o', out_dir]
    1.70 +
    1.71 +        for p in sorted(self._python_package_dirs):
    1.72 +            full = os.path.join(self._topsrcdir, p)
    1.73 +
    1.74 +            finder = FileFinder(full, find_executables=False)
    1.75 +            dirs = {os.path.dirname(f[0]) for f in finder.find('**')}
    1.76 +
    1.77 +            excludes = {d for d in dirs if d.endswith('test')}
    1.78 +
    1.79 +            args = list(base_args)
    1.80 +            args.append(full)
    1.81 +            args.extend(excludes)
    1.82 +
    1.83 +            sphinx.apidoc.main(args)
    1.84 +
    1.85 +    def _synchronize_docs(self):
    1.86 +        m = InstallManifest()
    1.87 +
    1.88 +        m.add_symlink(self._conf_py_path, 'conf.py')
    1.89 +
    1.90 +        for dest, source in sorted(self._trees.items()):
    1.91 +            source_dir = os.path.join(self._topsrcdir, source)
    1.92 +            for root, dirs, files in os.walk(source_dir):
    1.93 +                for f in files:
    1.94 +                    source_path = os.path.join(root, f)
    1.95 +                    rel_source = source_path[len(source_dir) + 1:]
    1.96 +
    1.97 +                    m.add_symlink(source_path, os.path.join(dest, rel_source))
    1.98 +
    1.99 +        stage_dir = os.path.join(self._output_dir, 'staging')
   1.100 +        copier = FileCopier()
   1.101 +        m.populate_registry(copier)
   1.102 +        copier.copy(stage_dir)
   1.103 +
   1.104 +        with open(self._index_path, 'rb') as fh:
   1.105 +            data = fh.read()
   1.106 +
   1.107 +        indexes = ['%s/index' % p for p in sorted(self._trees.keys())]
   1.108 +        indexes = '\n   '.join(indexes)
   1.109 +
   1.110 +        packages = [os.path.basename(p) for p in self._python_package_dirs]
   1.111 +        packages = ['python/%s' % p for p in packages]
   1.112 +        packages = '\n   '.join(sorted(packages))
   1.113 +        data = data.format(indexes=indexes, python_packages=packages)
   1.114 +
   1.115 +        with open(os.path.join(stage_dir, 'index.rst'), 'wb') as fh:
   1.116 +            fh.write(data)

mercurial