diff --git a/Makefile b/Makefile index 8bf528dd26..d2620b422c 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,13 @@ install: configured clean: configured ( cd $(BUILD) && make clean ) + ( cd $(BUILD) && make doc-clean ) + +doc: configured + ( cd $(BUILD) && make doc ) + +doc-clean: configured + ( cd $(BUILD) && make doc-clean ) dist: cmake_version # Minimum Bro source package diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a5a97d5c3b..47c03d6cb6 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -11,6 +11,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_reST_docs.py.in ${CMAKE_CURRENT_BINARY_DIR}/generate_reST_docs.py @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/BroToReST.py.in + ${CMAKE_CURRENT_BINARY_DIR}/BroToReST.py + @ONLY) add_custom_target(doc COMMAND "${CMAKE_COMMAND}" -E copy_directory @@ -30,7 +33,6 @@ add_custom_target(doc SOURCES ${DOC_SOURCES}) add_dependencies(doc bro) -# TODO: add dependency that's a check for `python`, `sphinx-build`, etc. add_custom_target(doc-clean COMMAND "${CMAKE_COMMAND}" -E remove_directory diff --git a/doc/README b/doc/README index 2a34ea6bdf..150260ed09 100644 --- a/doc/README +++ b/doc/README @@ -1 +1,44 @@ -TODO. +This directory contains scripts and templates that can be used to automate +the generation of Bro script documentation. Two build targets are defined +by CMake: + +``make doc`` + + This target depends on a Python interpreter (>=2.5) and + `Sphinx `_ being installed. Sphinx can be + installed like:: + + > sudo easy_install sphinx + + This target will also first build the bro binary if it is not already + since the generation of reStructuredText (reST) documentation from + Bro scripts is integrated within the parsing process. + + After completion, HTML documentation can be located inside the CMake + ``build/`` directory as ``build/doc/out/html``. The generated reST + documentation will be located in ``build/doc/source/policy``. + +``make doc-clean`` + + This target removes Sphinx inputs and outputs from the CMake ``build/`` dir. + +To schedule a script to be documented, edit ``scripts/generate_reST_docs.py.in`` +and try adding the name of the script along with an optional script group to +the ``docs`` dictionary. That python script also shows other, more specialized +methods for generating documentation for some types of corner-cases. + +When adding a new logical grouping for generated scripts, create a new +reST document in ``source/policy/.rst`` and add some default +documentation. References to (and summaries of) documents associated with +the group get appended to this file during the ``make doc`` process. + +The Sphinx source tree template in ``source/`` can be modified to add more +common/general documentation, style sheets, JavaScript, etc. The Sphinx +config file is produced from ``conf.py.in``, so that can be edited to change +various Sphinx options, like setting the default HTML rendering theme. +There is also a custom Sphinx domain implemented in ``source/ext/bro.py`` +which adds some reST directives and roles that aid in generating useful +index entries and cross-references. + +See ``example.bro`` for an example of how to document a Bro script such that +``make doc`` will be able to produce reST/HTML documentation for it. diff --git a/doc/scripts/BroToReST.py.in b/doc/scripts/BroToReST.py.in new file mode 100755 index 0000000000..89a8e1cc57 --- /dev/null +++ b/doc/scripts/BroToReST.py.in @@ -0,0 +1,152 @@ +#! /usr/bin/env python + +import os +import subprocess +import shutil +import glob +import string +import sys + +BRO = "@CMAKE_BINARY_DIR@/src/bro" +BROPATHDEV = "`@CMAKE_BINARY_DIR@/bro-path-dev`" +BRO_ARGS = "--doc-scripts" +DOC_DST_DIR = "@DOC_SOURCE_WORKDIR@/policy" +BROPATH = subprocess.Popen("@CMAKE_BINARY_DIR@/bro-path-dev", shell=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.readline() + +class BroToReST: + """A class to encapsulate the the generation of reST documentation from + a given Bro script. + """ + + bro_src_file = None + doc_src_file = None + load_via_stdin = False + group = None + + def __init__(self, src_file, load_method=False, search_dir=None, group=None): + """ + :param src_file: the file name of a Bro script (not a path) + :param load_method: T if script must be loaded by Bro via a stdin + redirection of "@load