# HG changeset patch # User Damien Correia # Date 1544447885 -3600 # Node ID 2703c8a7a968484a658ba9ee7d7d74b3c2dd32b6 # Parent 942151432421ec5f1300c89f66c2f223cd39394b Added Custom sphinx-autodoc script to generate api documentation diff -r 942151432421 -r 2703c8a7a968 buildout.cfg --- a/buildout.cfg Mon Dec 10 14:14:57 2018 +0100 +++ b/buildout.cfg Mon Dec 10 14:18:05 2018 +0100 @@ -22,7 +22,6 @@ ../pyams_default_theme ../pyams_file ../pyams_form - ../pyams_gis ../pyams_i18n ../pyams_ldap ../pyams_mail @@ -59,7 +58,6 @@ pyams_default_theme pyams_file pyams_form - pyams_gis pyams_i18n pyams_ldap pyams_mail @@ -74,6 +72,7 @@ pyams_skin pyams_template pyams_thesaurus + pyams_user_guide pyams_utils pyams_viewlet pyams_workflow diff -r 942151432421 -r 2703c8a7a968 setup.py --- a/setup.py Mon Dec 10 14:14:57 2018 +0100 +++ b/setup.py Mon Dec 10 14:18:05 2018 +0100 @@ -14,7 +14,7 @@ ############################################################################## """ -This module contains PyAMS ser guide +This module contains PyAMS user guide """ import os from setuptools import setup, find_packages @@ -67,4 +67,9 @@ 'sphinx_rtd_theme', # -*- Extra requirements: -*- ], - entry_points={}) + entry_points={ + 'console_scripts': [ + 'pyams_autodoc = pyams_user_guide.scripts:beautydoc', + ], + }, + ) diff -r 942151432421 -r 2703c8a7a968 src/pyams_user_guide/__init__.py diff -r 942151432421 -r 2703c8a7a968 src/pyams_user_guide/scripts/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_user_guide/scripts/__init__.py Mon Dec 10 14:18:05 2018 +0100 @@ -0,0 +1,51 @@ +#!/var/local/env/pycharm/bin/python3.5 +import os +from .beautydoc import main +import shlex + +packages_pyams = [ + 'pyams_alchemy', + 'pyams_cache', + 'pyams_catalog', + 'pyams_content', + 'pyams_content_es', + 'pyams_default_theme', + 'pyams_file', + 'pyams_form', + 'pyams_gis', + 'pyams_i18n', + 'pyams_ldap', + 'pyams_mail', + 'pyams_media', + 'pyams_notify', + 'pyams_notify_ws', + 'pyams_pagelet', + 'pyams_portal', + 'pyams_scheduler', + 'pyams_security', + 'pyams_sequence', + 'pyams_skin', + 'pyams_template', + 'pyams_thesaurus', + 'pyams_utils', + 'pyams_viewlet', + 'pyams_workflow', + 'pyams_zmi', + 'pyams_zmq', + 'pyams_zodbbrowser'] + +path_project = '/var/local/src/pyams/' +output_directory = '../src/source/api-doc/' + +def beautydoc(): + """ + Generate api-doc rst files. + Execute a custom sphinx-autodoc for each source code package in packages_pyams + :return: rst files + """ + for p in packages_pyams: + directory = p + packages_pyams_source = os.path.join(*[path_project, p, 'src', directory]) + outputdir = os.path.join(output_directory, directory) + # Command line + main(shlex.split('-f -T -M --maxdepth=2 -o {} {}'.format(outputdir, packages_pyams_source))) diff -r 942151432421 -r 2703c8a7a968 src/pyams_user_guide/scripts/beautydoc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_user_guide/scripts/beautydoc.py Mon Dec 10 14:18:05 2018 +0100 @@ -0,0 +1,197 @@ +#!/var/local/env/pycharm/bin/python3.5 +from sphinx.ext.apidoc import * +import sphinx.ext.apidoc as sp +import sys + +sys.path[0:0] = [ + '/var/local/src/pyams/pyams_alchemy/src', + '/var/local/src/pyams/pyams_cache/src', + '/var/local/src/pyams/pyams_catalog/src', + '/var/local/src/pyams/pyams_content/src', + '/var/local/src/pyams/pyams_content_es/src', + '/var/local/src/pyams/pyams_default_theme/src', + '/var/local/src/pyams/pyams_file/src', + '/var/local/src/pyams/pyams_form/src', + '/var/local/src/pyams/pyams_gis/src', + '/var/local/src/pyams/pyams_i18n/src', + '/var/local/src/pyams/pyams_ldap/src', + '/var/local/src/pyams/pyams_mail/src', + '/var/local/src/pyams/pyams_media/src', + '/var/local/src/pyams/pyams_notify/src', + '/var/local/src/pyams/pyams_notify_ws/src', + '/var/local/src/pyams/pyams_pagelet/src', + '/var/local/src/pyams/pyams_portal/src', + '/var/local/src/pyams/pyams_scheduler/src', + '/var/local/src/pyams/pyams_security/src', + '/var/local/src/pyams/pyams_sequence/src', + '/var/local/src/pyams/pyams_skin/src', + '/var/local/src/pyams/pyams_template/src', + '/var/local/src/pyams/pyams_thesaurus/src', + '/var/local/src/pyams/pyams_utils/src', + '/var/local/src/pyams/pyams_viewlet/src', + '/var/local/src/pyams/pyams_workflow/src', + '/var/local/src/pyams/pyams_zmi/src', + '/var/local/src/pyams/pyams_zmq/src', + '/var/local/src/pyams/pyams_zodbbrowser/src', + '/var/local/env/pycharm/lib/python3.5/site-packages', + ] + + +def makename(package, module): + # type: (unicode, unicode) -> unicode + """Join package and module with a dot.""" + # Both package and module can be None/empty. + if package: + name = package + if module: + name += '.' + module + else: + name = module + return name + + +def format_heading(level, text, escape=True): + # type: (int, unicode, bool) -> unicode + """Create a heading of [1, 2 or 3 supported].""" + if escape: + text = rst.escape(text) + underlining = ['=','-','~', '+', ][level - 1] * len(text) + return '%s\n%s\n\n' % (text, underlining) + + +def format_directive(module, package=None): + # type: (unicode, unicode) -> unicode + """Create the automodule directive and add the options.""" + directive = '.. automodule:: %s\n' % makename(package, module) + for option in OPTIONS: + directive += ' :%s:\n' % option + return directive + + +def create_module_file(package, module, opts): + # type: (unicode, unicode, Any) -> None + """Build the text of the file and write the file.""" + if not opts.noheadings: + text = format_heading(1, '%s module' % module) + else: + text = '' + # text += format_heading(2, ':mod:`%s` Module' % module) + text += format_directive(module, package) + write_file(makename(package, module), text, opts) + + +def format_submodule(module): + # type: (unicode, unicode, Any) -> unicode + """Reformat submodule title""" + modulelist = module.split('.') + sub = modulelist.pop() + modulelist.append('\ ``' + sub + '``') + if modulelist: + module = '.'.join(modulelist) + + return module + + +def create_package_file(root, master_package, subroot, py_files, opts, subs, is_namespace, excludes=[]): # NOQA + # type: (unicode, unicode, unicode, List[unicode], Any, List[unicode], bool, List[unicode]) -> None # NOQA + """Build the text of the file and write the file.""" + myname = makename(master_package, subroot) + text ='.. _%s:\n\n' % myname + text += format_heading(1, ('\ :mod:`%s` package |package| ' if not is_namespace else "%s namespace") + % myname, escape=False) + + + #text += format_heading(1, ('%s package' if not is_namespace else "%s namespace") + # % makename(master_package, subroot)) + + if opts.modulefirst and not is_namespace: + text += format_directive(subroot, master_package) + text += '\n' + + # build a list of directories that are szvpackages (contain an INITPY file) + # and also checks the INITPY file is not empty, or there are other python + # source files in that folder. + # (depending on settings - but shall_skip() takes care of that) + subs = [sub for sub in subs if not + shall_skip(path.join(root, sub, INITPY), opts, excludes)] + # if there are some package directories, add a TOC for theses subpackages + if subs: + text += format_heading(2, 'Subpackages') + text += '.. toctree::\n\n' + for sub in subs: + text += ' %s.%s\n' % (makename(master_package, subroot), sub) + text += '\n' + + submods = [path.splitext(sub)[0] for sub in py_files + if not shall_skip(path.join(root, sub), opts, excludes) and + sub != INITPY] + if submods: + #text += format_heading(2, 'Submodules') + if opts.separatemodules: + text += '.. toctree::\n' + text += ' :maxdepth: %s\n\n' % opts.maxdepth + for submod in submods: + modfile = makename(master_package, makename(subroot, submod)) + text += ' %s\n' % modfile + + # generate separate file for this module + if not opts.noheadings: + filetext = format_heading(2, '%s' % format_submodule(modfile), escape=False) + else: + filetext = '' + filetext += format_directive(makename(subroot, submod), + master_package) + write_file(modfile, filetext, opts) + else: + for submod in submods: + modfile = makename(master_package, makename(subroot, submod)) + if not opts.noheadings: + text += format_heading(2, '%s' % format_submodule(modfile), escape=False) + text += format_directive(makename(subroot, submod), + master_package) + text += '\n' + text += '\n' + + if not opts.modulefirst and not is_namespace: + text += format_heading(2, 'Module contents') + text += format_directive(subroot, master_package) + + # if there are some package directories, add a TOC for theses subpackages + if subs: + text += format_heading(2, 'Subpackages') + text += '.. toctree::\n\n' + for sub in subs: + text += ' %s.%s\n' % (makename(master_package, subroot), sub) + text += '\n' + text += '\n.. |package| unicode:: 0x229e\n' + write_file(makename(master_package, subroot), text, opts) + + +def create_modules_toc_file(modules, opts, name='modules'): + # type: (List[unicode], Any, unicode) -> None + """Create the module's index.""" + text = format_heading(2, '%s' % opts.header, escape=False) + text += '.. toctree::\n' + text += ' :maxdepth: %s\n\n' % opts.maxdepth + + modules.sort() + prev_module = '' # type: unicode + for module in modules: + # look if the module is a subpackage and, if yes, ignore it + if module.startswith(prev_module + '.'): + continue + prev_module = module + text += ' %s\n' % module + + write_file(name, text, opts) + + +sp.makename = makename +sp.create_modules_toc_file = create_modules_toc_file +sp.create_package_file = create_package_file +sp.format_heading = format_heading + + +if __name__ == '__main__': + + sys.exit(sphinx.ext.apidoc.main()) diff -r 942151432421 -r 2703c8a7a968 src/source/api-doc/README.txt --- a/src/source/api-doc/README.txt Mon Dec 10 14:14:57 2018 +0100 +++ b/src/source/api-doc/README.txt Mon Dec 10 14:18:05 2018 +0100 @@ -1,2 +1,6 @@ -Don't edit these files manually +gsDon't edit these files manually Theses RST files are generated automatically using the source code and python docstring of packages. + +To generale api-doc run: + +./bin/pyams_autodoc