Source code for desiutil.api

# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-
"""
============
desiutil.api
============

This package contains code for creating API files for use with Sphinx documentation.
The resulting api file simply has a Sphinx-readable link to every ``*.py`` file.
"""
import os
import sys
from argparse import ArgumentParser
from . import __version__ as desiutilVersion
from .log import log
from .setup import find_version_directory

# Do not generate an API entry for these files.
_exclude_file = ('_version.py', )


[docs]def _test_file(d, f): """Do not generate an API entry for test files. """ return os.path.basename(d) == 'test' or os.path.basename(d) == 'tests'
[docs]def find_modules(name): """Find ``*.py`` files in the package directory corresponding to `name`. Parameters ---------- name : :class:`str` The name of the package. Returns ------- :class:`list` The modules found in the package. """ productroot = find_version_directory(name) modules = [] for dirpath, dirnames, filenames in os.walk(productroot): if dirpath == productroot: d = '' else: d = dirpath.replace(productroot + '/', '') log.debug(d) for f in filenames: mod = [name] if f.endswith('.py') and f not in _exclude_file and not _test_file(d, f): if d: mod += d.split('/') if f != '__init__.py': mod.append(f.replace('.py', '')) modules.append('.'.join(mod)) log.debug('.'.join(mod)) return modules
[docs]def write_api(modules, options): """Write out a file containing the modules found. Parameters ---------- modules : :class:`list` The names of the modules found in the package. options: :class:`~argparse.Namespace` The command-line options. Returns ------- :class:`int` An integer suitable for passing to :func:`sys.exit`. """ title = f"{options.name} API" lines = ['='*len(title), title, '='*len(title), ''] for m in sorted(modules): lines += [f'.. automodule:: {m}', ' :members:', ''] if os.path.exists(options.api): if options.overwrite: log.warning("%s will be overwritten!", options.api) else: log.error("%s already exists!", options.api) return 1 with open(options.api, 'w') as a: a.write('\n'.join(lines)) return 0
[docs]def main(): """Entry-point for command-line scripts. Returns ------- :class:`int` An integer suitable for passing to :func:`sys.exit`. """ parser = ArgumentParser(description="Create or update a doc/api.rst file.", prog=os.path.basename(sys.argv[0])) parser.add_argument('-a', '--api', dest='api', default=os.path.join(os.path.abspath('.'), 'doc', 'api.rst'), help='Set the name of the API file (default %(default)s).') parser.add_argument('-o', '--overwrite', dest='overwrite', action='store_true', help='Overwrite any existing API file.') parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + desiutilVersion) parser.add_argument('name', help='The top-level name of the package.') options = parser.parse_args() modules = find_modules(options.name) return write_api(modules, options)