From 83737d253d0f21fe64348b8cb1be1a92aef243f9 Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Wed, 28 Aug 2013 09:56:43 +1000 Subject: [PATCH] Add auto code api doc generation This will document the python api to: heat.api heat.engine (not the resources as we have docs for those) heat.rpc (copied from ceilometer) Change-Id: I5a400f72d4ec115fb700ab8b24dbccf0b5cd3200 --- doc/source/conf.py | 131 ++++++++++++++++++++++++++++++- doc/source/index.rst | 6 +- doc/source/sourcecode/.gitignore | 1 + 3 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 doc/source/sourcecode/.gitignore diff --git a/doc/source/conf.py b/doc/source/conf.py index 09707d2e..3805446a 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -27,10 +27,131 @@ import os import sys +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", "..")) + +sys.path.insert(0, ROOT) +sys.path.insert(0, BASE_DIR) + +# This is required for ReadTheDocs.org, but isn't a bad idea anyway. +os.environ['DJANGO_SETTINGS_MODULE'] = 'openstack_dashboard.settings' + + +def write_autodoc_index(): + + def find_autodoc_modules(module_name, sourcedir): + """Return a list of modules in the SOURCE directory.""" + modlist = [] + os.chdir(os.path.join(sourcedir, module_name)) + print "SEARCHING %s" % sourcedir + for root, dirs, files in os.walk("."): + for filename in files: + if filename.endswith(".py"): + # remove the pieces of the root + elements = root.split(os.path.sep) + # replace the leading "." with the module name + elements[0] = module_name + # and get the base module name + base, extension = os.path.splitext(filename) + if not (base == "__init__"): + elements.append(base) + result = ".".join(elements) + #print result + modlist.append(result) + return modlist + + RSTDIR = os.path.abspath(os.path.join(BASE_DIR, "sourcecode")) + SRCS = {'heat': ROOT} + + EXCLUDED_MODULES = ('heat.tests', + 'heat.testing', + 'heat.cmd', + 'heat.common', + 'heat.cloudinit', + 'heat.cfn_client', + 'heat.doc', + 'heat.db', + 'heat.engine.resources', + 'heat.locale', + 'heat.openstack') + CURRENT_SOURCES = {} + + if not(os.path.exists(RSTDIR)): + os.mkdir(RSTDIR) + CURRENT_SOURCES[RSTDIR] = ['autoindex.rst', '.gitignore'] + + INDEXOUT = open(os.path.join(RSTDIR, "autoindex.rst"), "w") + INDEXOUT.write("=================\n") + INDEXOUT.write("Source Code Index\n") + INDEXOUT.write("=================\n") + + for modulename, path in SRCS.items(): + sys.stdout.write("Generating source documentation for %s\n" % + modulename) + INDEXOUT.write("\n%s\n" % modulename.capitalize()) + INDEXOUT.write("%s\n" % ("=" * len(modulename),)) + INDEXOUT.write(".. toctree::\n") + INDEXOUT.write(" :maxdepth: 1\n") + INDEXOUT.write("\n") + + MOD_DIR = os.path.join(RSTDIR, modulename) + CURRENT_SOURCES[MOD_DIR] = [] + if not(os.path.exists(MOD_DIR)): + os.mkdir(MOD_DIR) + for module in find_autodoc_modules(modulename, path): + if any([module.startswith(exclude) + for exclude + in EXCLUDED_MODULES]): + print "Excluded module %s." % module + continue + mod_path = os.path.join(path, *module.split(".")) + generated_file = os.path.join(MOD_DIR, "%s.rst" % module) + + INDEXOUT.write(" %s/%s\n" % (modulename, module)) + + # Find the __init__.py module if this is a directory + if os.path.isdir(mod_path): + source_file = ".".join((os.path.join(mod_path, "__init__"), + "py",)) + else: + source_file = ".".join((os.path.join(mod_path), "py")) + + CURRENT_SOURCES[MOD_DIR].append("%s.rst" % module) + # Only generate a new file if the source has changed or we don't + # have a doc file to begin with. + if not os.access(generated_file, os.F_OK) or \ + os.stat(generated_file).st_mtime < \ + os.stat(source_file).st_mtime: + print "Module %s updated, generating new documentation." \ + % module + FILEOUT = open(generated_file, "w") + header = "The :mod:`%s` Module" % module + FILEOUT.write("%s\n" % ("=" * len(header),)) + FILEOUT.write("%s\n" % header) + FILEOUT.write("%s\n" % ("=" * len(header),)) + FILEOUT.write(".. automodule:: %s\n" % module) + FILEOUT.write(" :members:\n") + FILEOUT.write(" :undoc-members:\n") + FILEOUT.write(" :show-inheritance:\n") + FILEOUT.write(" :noindex:\n") + FILEOUT.close() + + INDEXOUT.close() + + # Delete auto-generated .rst files for sources which no longer exist + for directory, subdirs, files in list(os.walk(RSTDIR)): + for old_file in files: + if old_file not in CURRENT_SOURCES.get(directory, []): + print "Removing outdated file for %s" % old_file + os.remove(os.path.join(directory, old_file)) + + +write_autodoc_index() + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../../')) +#sys.path.insert(0, os.path.abspath('.')) # -- General configuration ---------------------------------------------------- @@ -42,9 +163,15 @@ sys.path.insert(0, os.path.abspath('../../')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.pngmath', + 'sphinx.ext.viewcode', 'oslo.sphinx', 'heat.doc.resources'] +todo_include_todos = True + # Add any paths that contain templates here, relative to this directory. if os.getenv('HUDSON_PUBLISH_DOCS'): templates_path = ['_ga', '_templates'] @@ -139,7 +266,7 @@ html_theme_options = { # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/doc/source/index.rst b/doc/source/index.rst index 90b40ca9..fd8542f6 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -56,13 +56,13 @@ Developers Documentation Code Documentation ================== .. toctree:: - :maxdepth: 1 + :maxdepth: 3 - api/autoindex + sourcecode/autoindex Indices and tables ================== * :ref:`genindex` * :ref:`modindex` -* :ref:`search` \ No newline at end of file +* :ref:`search` diff --git a/doc/source/sourcecode/.gitignore b/doc/source/sourcecode/.gitignore new file mode 100644 index 00000000..30d85567 --- /dev/null +++ b/doc/source/sourcecode/.gitignore @@ -0,0 +1 @@ +*.rst -- 2.45.2