def _build(*, out_dir, temp_dir): """Callback function that implements the bulk of main(). Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. """ # Create a hermetic copy of our input. This helps ensure that only files # listed in BUILD.bazel will render onto the website. symlink_input("drake/doc/styleguide/jekyll_input.txt", temp_dir, copy=True, strip_prefix=[ "drake/doc/styleguide/", "styleguide/", ]) # Prepare the files for Jekyll. _add_title(temp_dir=temp_dir, filename="pyguide.md", title="Google Python Style Guide for Drake") # Run the documentation generator. check_call([ "/usr/bin/jekyll", "build", "--source", temp_dir, "--destination", out_dir, ]) # The filenames to suggest as the starting points for preview. return ["cppguide.html", "pyguide.html"]
def _build(*, out_dir, temp_dir): """Callback function that implements the bulk of main(). Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. """ # Create a hermetic copy of our input. This helps ensure that only files # listed in BUILD.bazel will render onto the website. symlink_input("drake/doc/pages_input.txt", temp_dir, copy=True) # Run the documentation generator. check_call([ "jekyll", "build", "--source", os.path.join(temp_dir, "drake/doc"), "--destination", out_dir, ]) # Tidy up. perl_cleanup_html_output(out_dir=out_dir) # The filename to suggest as the starting point for preview; in this case, # it's an empty filename (i.e., the index page). return [""]
def _build(*, out_dir, temp_dir, modules, quick): """Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. """ manifest = runfiles.Create() # Find drake's sources. drake_workspace = os.path.dirname( os.path.realpath(manifest.Rlocation("drake/.bazelproject"))) assert os.path.exists(drake_workspace), drake_workspace assert os.path.exists(join(drake_workspace, "WORKSPACE")), drake_workspace # Find doxygen. doxygen = manifest.Rlocation("doxygen/doxygen") assert os.path.exists(doxygen), doxygen # Find dot. dot = "/usr/bin/dot" assert os.path.exists(dot), dot # Configure doxygen. doxyfile = _generate_doxyfile(manifest=manifest, out_dir=out_dir, temp_dir=temp_dir, dot=(dot if not quick else "")) # Prepare our input. symlink_input("drake/doc/doxygen_cxx/doxygen_input.txt", temp_dir) _symlink_headers(drake_workspace=drake_workspace, temp_dir=temp_dir, modules=modules) # Run doxygen. check_call([doxygen, doxyfile], cwd=temp_dir) # Post-process its log, and check for errors. If we are building only a # subset of the docs, we are likely to encounter errors due to the missing # sections, so we'll only enable the promotion of warnings to errors when # we're building all of the C++ documentation. check_for_errors = (len(modules) == 0) with open(f"{temp_dir}/doxygen.log", encoding="utf-8") as f: lines = [ line.strip().replace(f"{temp_dir}/", "") for line in f.readlines() ] _postprocess_doxygen_log(lines, check_for_errors) # The nominal pages to offer for preview. return ["", "classes.html", "modules.html"]
def _build(*, out_dir, temp_dir, modules, quick): """Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. """ manifest = runfiles.Create() # Find drake's sources. drake_workspace = os.path.dirname(os.path.realpath( manifest.Rlocation("drake/.bazelproject"))) assert os.path.exists(drake_workspace), drake_workspace assert os.path.exists(join(drake_workspace, "WORKSPACE")), drake_workspace # Find doxygen. doxygen = manifest.Rlocation("doxygen/doxygen") assert os.path.exists(doxygen), doxygen # Find dot. dot = "/usr/bin/dot" assert os.path.exists(dot), dot # Configure doxygen. doxyfile = _generate_doxyfile( manifest=manifest, out_dir=out_dir, temp_dir=temp_dir, dot=(dot if not quick else "")) # Prepare our input. symlink_input( "drake/doc/doxygen_cxx/doxygen_input.txt", temp_dir) _symlink_headers( drake_workspace=drake_workspace, temp_dir=temp_dir, modules=modules) # Run doxygen. check_call([doxygen, doxyfile], cwd=temp_dir) # The nominal pages to offer for preview. return ["", "classes.html", "modules.html"]
def _build(*, out_dir, temp_dir, modules, quick): """Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. """ manifest = runfiles.Create() # Find drake's sources. drake_workspace = os.path.dirname( os.path.realpath(manifest.Rlocation("drake/.bazelproject"))) assert os.path.exists(drake_workspace), drake_workspace assert os.path.exists(join(drake_workspace, "WORKSPACE")), drake_workspace # Find doxygen. doxygen = manifest.Rlocation("doxygen/doxygen") assert os.path.exists(doxygen), doxygen # Find dot. dot = "/usr/bin/dot" assert os.path.exists(dot), dot # Configure doxygen. doxyfile = _generate_doxyfile(manifest=manifest, out_dir=out_dir, temp_dir=temp_dir, dot=(dot if not quick else "")) # Prepare our input. symlink_input("drake/doc/doxygen_cxx/doxygen_input.txt", temp_dir) _symlink_headers(drake_workspace=drake_workspace, temp_dir=temp_dir, modules=modules) # Run doxygen. check_call([doxygen, doxyfile], cwd=temp_dir) # Post-process its log, and check for errors. If we are building only a # subset of the docs, we are likely to encounter errors due to the missing # sections, so we'll only enable the promotion of warnings to errors when # we're building all of the C++ documentation. check_for_errors = (len(modules) == 0) with open(f"{temp_dir}/doxygen.log", encoding="utf-8") as f: lines = [ line.strip().replace(f"{temp_dir}/", "") for line in f.readlines() ] _postprocess_doxygen_log(lines, check_for_errors) # Collect the list of all HTML output files. html_files = [] for dirpath, _, filenames in os.walk(out_dir): for filename in filenames: if filename.endswith(".html"): html_files.append(relpath(join(dirpath, filename), out_dir)) # Fix the formatting of deprecation text (see drake#15619 for an example). perl_statements = [ # Remove quotes around the removal date. r's#(removed from Drake on or after) "(....-..-..)" *\.#\1 \2.#;', # Remove all quotes within the explanation text, i.e., the initial and # final quotes, as well as internal quotes that might be due to C++ # multi-line string literals. # - The quotes must appear after a "_deprecatedNNNNNN" anchor. # - The quotes must appear before a "<br />" end-of-line. # Example lines: # <dl class="deprecated"><dt><b><a class="el" href="deprecated.html#_deprecated000013">Deprecated:</a></b></dt><dd>"Use RotationMatrix::MakeFromOneVector()." <br /> # noqa # <dd><a class="anchor" id="_deprecated000013"></a>"Use RotationMatrix::MakeFromOneVector()." <br /> # noqa r'while (s#(?<=_deprecated\d{6}")([^"]*)"(.*?<br)#\1\2#) {};', ] while html_files: # Work in batches of 100, so we don't overflow the argv limit. first, html_files = html_files[:100], html_files[100:] check_call(["perl", "-pi", "-e", "".join(perl_statements)] + first, cwd=out_dir) # The nominal pages to offer for preview. return ["", "classes.html", "modules.html"]
def _build(*, out_dir, temp_dir, modules): """Generates into out_dir; writes scratch files into temp_dir. As a precondition, both directories must already exist and be empty. If modules are provided, only generate those modules and their children. """ assert len(os.listdir(temp_dir)) == 0 assert len(os.listdir(out_dir)) == 0 sphinx_build = "/usr/share/sphinx/scripts/python3/sphinx-build" if not os.path.isfile(sphinx_build): print("Please re-run 'sudo setup/ubuntu/install_prereqs.sh' with the " "'--with-doc-only' flag") sys.exit(1) # Create a hermetic copy of our input. This helps ensure that only files # listed in BUILD.bazel will render onto the website. symlink_input("drake/doc/pydrake/sphinx_input.txt", temp_dir, strip_prefix=["drake/doc/"]) input_dir = join(temp_dir, "pydrake") # Process the command-line request for which modules to document. all_modules = _get_pydrake_modules() if not modules: modules_to_document = set(all_modules) else: modules_to_document = set() for x in modules: if x not in all_modules: print(f"error: Unknown module '{x}'") sys.exit(1) # Add the requested module and its parents. tokens = x.split(".") while tokens: modules_to_document.add(".".join(tokens)) tokens.pop() # Add the requsted module's children. for y in all_modules: if y.startswith(x + "."): modules_to_document.add(y) # Generate tables of contents. for name in sorted(list(modules_to_document)): if name == "pydrake": rst_name = "index.rst" else: rst_name = name + ".rst" _write_module(name, join(input_dir, rst_name)) # Run the documentation generator. os.environ["LANG"] = "en_US.UTF-8" check_call([ sphinx_build, "-b", "html", # HTML output. "-a", "-E", # Don't use caching. "-N", # Disable colored output. "-T", # Traceback (for plugin). "-d", join(temp_dir, "doctrees"), input_dir, out_dir, ]) # The filename to suggest as the starting point for preview; in this case, # it's an empty filename (i.e., the index page). return [""]