Beispiel #1
0
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"]
Beispiel #2
0
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 [""]
Beispiel #3
0
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"]
Beispiel #4
0
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"]
Beispiel #5
0
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"]
Beispiel #6
0
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 [""]