Render the command help from the crash binary as Sphinx sources: an
index page whose toctree is the command list, and one page per command,
so the left navigation shows the command list under "crash command
help". The pages live in doc/help/ and are rebuilt by "make website";
"make doc" creates a placeholder index so the documentation still builds
without a crash binary.
Also build the maintenance guide as an orphan page, so maintenance.html
is generated without appearing in the navigation.
Signed-off-by: Rui Yang <yangrr.2009(a)tsinghua.org.cn>
---
.gitignore | 1 +
Makefile | 2 +-
doc/Makefile | 10 ++-
doc/conf.py | 5 +-
doc/extensions.rst | 2 +-
doc/index.rst | 2 +
doc/maintenance.rst | 12 ++--
scripts/gen-help-rst.py | 106 ++++++++++++++++++++++++++++
scripts/gen-help-site.py | 146 ---------------------------------------
9 files changed, 129 insertions(+), 157 deletions(-)
create mode 100644 scripts/gen-help-rst.py
delete mode 100755 scripts/gen-help-site.py
diff --git a/.gitignore b/.gitignore
index 320805190f55..1f6cd8212d5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ TAGS
/compile_commands.json
/_site/
+/doc/help/
diff --git a/Makefile b/Makefile
index 45c62f42c0bc..11dcde08f0ef 100644
--- a/Makefile
+++ b/Makefile
@@ -859,8 +859,8 @@ SITE_DIR=_site
website: ${PROGRAM}
rm -rf ${SITE_DIR}
+ python3 scripts/gen-help-rst.py --crash $(abspath ${PROGRAM}) --out $(abspath doc/help)
$(MAKE) -C doc website WEBSITE_DIR=$(abspath ${SITE_DIR})
- python3 scripts/gen-help-site.py --crash $(abspath ${PROGRAM}) --out $(abspath
${SITE_DIR})
@echo "Site generated in ${SITE_DIR}"
.PHONY: doc htmldocs pdfdocs cleandocs website
diff --git a/doc/Makefile b/doc/Makefile
index a75b2ac3959c..bf9568f073fd 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -20,12 +20,16 @@ help:
@echo " pdf / latexpdf to make a PDF file (requires a LaTeX toolchain)"
@echo " clean / cleandocs to remove the build directory"
-html htmldocs:
+help/index.rst:
+ @mkdir -p help
+ @printf 'Crash command help\n==================\n\nThe command help pages are
generated from the crash binary when the\ndocumentation website is built.\n' > $@
+
+html htmldocs: help/index.rst
$(SPHINXBUILD) -b html $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-website:
+website: help/index.rst
$(SPHINXBUILD) -b html -d $(BUILDDIR)/doctrees $(SPHINXOPTS) $(SOURCEDIR)
$(WEBSITE_DIR)
@echo
@echo "Build finished. The HTML pages are in $(WEBSITE_DIR)."
@@ -38,4 +42,4 @@ pdf latexpdf: latex
@echo "Build finished. The PDF is in $(BUILDDIR)/latex."
clean cleandocs:
- rm -rf $(BUILDDIR)
+ rm -rf $(BUILDDIR) help
diff --git a/doc/conf.py b/doc/conf.py
index 19d159c05296..6a4dd19e02d5 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -31,7 +31,7 @@ master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['output', 'Thumbs.db', '.DS_Store',
'maintenance.rst']
+exclude_patterns = ['output', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
@@ -48,6 +48,9 @@ smartquotes = False
# The theme to use for HTML and HTML Help pages.
html_theme = 'sphinx_rtd_theme'
+html_theme_options = {
+ 'collapse_navigation': False,
+}
# 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,
diff --git a/doc/extensions.rst b/doc/extensions.rst
index 761b1c6cfc42..e12e23364579 100644
--- a/doc/extensions.rst
+++ b/doc/extensions.rst
@@ -50,7 +50,7 @@ To add the module's command(s) to a running crash session, enter:
``crash> extend <path-to>/<module>.so``
The command(s) registered by the extension module will appear in the crash
-`help <help_pages/help.html>`__ menu. The module can be installed
+`help <help/help.html>`__ menu. The module can be installed
automatically if the ``extend`` command above is entered in either
*./.crashrc* or *$HOME/.crashrc*.
diff --git a/doc/index.rst b/doc/index.rst
index 8e6b0da56357..d0760eb4a00b 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -11,7 +11,9 @@ produced a core dump (a *dumpfile*).
.. toctree::
:hidden:
+ :maxdepth: 2
+ help/index
whitepaper
extensions
links
diff --git a/doc/maintenance.rst b/doc/maintenance.rst
index a50fc92b317a..0eb8fae15b63 100644
--- a/doc/maintenance.rst
+++ b/doc/maintenance.rst
@@ -1,3 +1,5 @@
+:orphan:
+
Crash Utility Maintenance Guide
===============================
@@ -589,7 +591,7 @@ make_configure @./configure ${CONF_TARGET_FLAG} -p
"RPMPKG=${RPMPKG}" -b @make
--no-print-directory gdb_merge The ``make_configure`` dependency re-compiles
``configure.c`` every time. Then ``configure`` is called, optionally passing
the CONF_TARGET_FLAG if it had been invoked with
-``make TARGET=<``*architecture>*, and the RPMPKG release string if it was
+``make TARGET=<architecture>``, and the RPMPKG release string if it was
invoked with ``make RPMPKG=`` <*version*>, and most importantly, the ``-b``
argument. ``configure -b`` creates a copy of the ``Makefile``, where it
modifies the original in order to set the
@@ -996,7 +998,7 @@ by the initialization banner:
However, GDB can be configured such that it runs on the host architecture, but
can analyze the binary executable and core file of a different architecture.
The crash utility itself can be built to target a different architecture by
-invoking it with ``make TARGET=<``*architecture>*, subject to the restrictions
+invoking it with ``make TARGET=<architecture>``, subject to the restrictions
shown in this :ref:`table <target_arch>`. So, for example, this crash utility
binary was built on an x86_64 host by invoking ``make TARGET=ARM64``; note
that it shows both ``--host`` and ``--target`` values:
@@ -1086,7 +1088,7 @@ As a result of the build procedure, two files are stored in the
1. the TARGET architecture is stored in the ``crash.target`` file. This file is
used to make the TARGET architecture "sticky" across subsequent builds, and
- will also prevent an attempt to invoke ``make TARGET=<``*architecture>* on a
+ will also prevent an attempt to invoke ``make TARGET=<architecture>`` on a
previously built tree that has a different TARGET architecture.
2. a copy of the ``gdb-`` <*version*>.``patch`` file; this file is used to
recognize whether the top-level version of the file has changed, and therefore
@@ -4845,7 +4847,7 @@
https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
Mon Sep 24 2018 Dave Anderson - 7.2.4-1 - Update to latest upstream release
\* Thu Jul 12 2018 Fedora Release Engineering - 7.2.3-2 - Rebuilt for
https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild \*
Fri May 18 2018 Dave Anderson - 7.2.3-1 - Update to latest upstream release
-``...``*(remainder of changelog not shown)*
+``...`` *(remainder of changelog not shown)*
.. _rhel:
@@ -4894,7 +4896,7 @@ ELF kdump vmcores form s390x KASLR kernels Resolves: rhbz#1786996
Mon Jun 10 2019 Dave Anderson - 7.2.6-2 - Fix "p" command regression Resolves:
rhbz#1718417 - Fix arm64 debug kernel read error message during initialization
Resolves: rhbz#1718736
-\* Mon May 6 2019 Dave Anderson - 7.2.6-1 - Rebase to latest upstream sources Resolves:
rhbz#1686560 - Utilize the VMCOREINFO PT_NOTE in /proc/kcore header Resolves: rhbz#1627528
- Support extraction of CONFIG_PROC_VMCORE_DEVICE_DUMP data from dumpfile header Resolves:
rhbz#1702535 ``...``*(remainder
+\* Mon May 6 2019 Dave Anderson - 7.2.6-1 - Rebase to latest upstream sources Resolves:
rhbz#1686560 - Utilize the VMCOREINFO PT_NOTE in /proc/kcore header Resolves: rhbz#1627528
- Support extraction of CONFIG_PROC_VMCORE_DEVICE_DUMP data from dumpfile header Resolves:
rhbz#1702535 ``...`` *(remainder
of changelog not shown)*
.. _centos:
diff --git a/scripts/gen-help-rst.py b/scripts/gen-help-rst.py
new file mode 100644
index 000000000000..f717e8fb1614
--- /dev/null
+++ b/scripts/gen-help-rst.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+"""Generate the crash command help pages as Sphinx sources.
+
+The crash binary is the single source of truth for the command help: this
+script asks it for the help menu and for each command's help page, then
+writes an index page (the command list, used as the toctree) and one RST
+page per command.
+
+Usage:
+ scripts/gen-help-rst.py --crash ./crash --out doc/help
+"""
+import argparse
+import os
+import subprocess
+import sys
+
+
+def run_help(crash, what):
+ """Return the text of "crash -h
<what>"."""
+ cmd = [crash, "--no_scroll", "--no_crashrc", "-h",
what]
+ result = subprocess.run(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ if result.returncode != 0:
+ sys.stderr.write(result.stderr.decode("utf-8", "replace"))
+ raise SystemExit("failed to run: %s" % " ".join(cmd))
+ return result.stdout.decode("utf-8", "replace")
+
+
+def parse_menu(text):
+ """Split the "help commands" output (names, with BREAK row
markers)."""
+ rows = []
+ row = []
+ for line in text.splitlines():
+ line = line.strip()
+ if line == "BREAK":
+ if row:
+ rows.append(row)
+ row = []
+ elif line:
+ row.append(line)
+ if row:
+ rows.append(row)
+ return rows
+
+
+def page_name(cmd):
+ if cmd == "*":
+ return "pointer"
+ return cmd
+
+
+def strip_text(text):
+ lines = text.splitlines()
+ while lines and not lines[0].strip():
+ lines.pop(0)
+ while lines and not lines[-1].strip():
+ lines.pop()
+ return "\n".join(lines)
+
+
+def literal(text):
+ return "\n".join(" " + line if line.strip() else ""
+ for line in text.split("\n"))
+
+
+def write_page(path, cmd, text):
+ title = page_name(cmd)
+ body = [title, "=" * len(title), "", "::",
"", literal(text), ""]
+ with open(path, "w", encoding="utf-8") as f:
+ f.write("\n".join(body))
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--crash", required=True, help="path to the crash
binary")
+ parser.add_argument("--out", required=True, help="output
directory")
+ args = parser.parse_args()
+
+ crash = os.path.abspath(args.crash)
+ out = os.path.abspath(args.out)
+ if not os.path.isfile(crash):
+ raise SystemExit("no such crash binary: %s" % crash)
+ os.makedirs(out, exist_ok=True)
+
+ menu_rows = parse_menu(run_help(crash, "commands"))
+ commands = [cmd for row in menu_rows for cmd in row]
+
+ entries = []
+ for cmd in commands:
+ name = page_name(cmd)
+ write_page(os.path.join(out, name + ".rst"), cmd,
+ strip_text(run_help(crash, cmd)))
+ entries.append(name)
+
+ index = ["Crash command help", "=" * len("crash command
help"), "",
+ ".. toctree::", " :maxdepth: 1", ""]
+ index += [" " + e for e in entries]
+ index.append("")
+ with open(os.path.join(out, "index.rst"), "w",
encoding="utf-8") as f:
+ f.write("\n".join(index))
+
+ print("generated %d help pages in %s" % (len(entries), out))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/gen-help-site.py b/scripts/gen-help-site.py
deleted file mode 100755
index dd3c1deeb63a..000000000000
--- a/scripts/gen-help-site.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python3
-"""Generate the crash command help pages for the documentation site.
-
-The crash binary is the single source of truth for the command help: this
-script asks it for the help menu and for each command's help page, then wraps
-the text in small HTML pages.
-
-Usage:
- scripts/gen-help-site.py --crash ./crash --out _site
-"""
-import argparse
-import html
-import os
-import subprocess
-import sys
-
-CSS = """
-body { font-family: sans-serif; max-width: 60em; margin: 2em auto;
- padding: 0 1em; color: #222; line-height: 1.4; }
-h1 { font-size: 1.35em; }
-h1 tt, td tt { font-family: monospace; }
-pre { background: #f5f5f5; border: 1px solid #ddd; padding: 1em;
- overflow-x: auto; font-size: .9em; line-height: 1.35; }
-a { color: #005a9c; }
-table.menu { border-collapse: collapse; }
-table.menu td { padding: .2em 1.8em .2em 0; white-space: nowrap; }
-""".strip()
-
-HELP_PAGE = """<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<title>crash help: {cmd}</title>
-<style>{css}</style>
-</head>
-<body>
-<h1>crash utility help page: <tt>{cmd}</tt></h1>
-<pre>{text}</pre>
-<p><a href="../help.html">← back to the crash help
menu</a></p>
-</body>
-</html>
-"""
-
-MENU_PAGE = """<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<title>crash utility help pages</title>
-<style>{css}</style>
-</head>
-<body>
-<h1>crash utility help pages</h1>
-<p><a href="index.html">← back to the crash
documentation</a></p>
-<table class="menu">
-{rows}
-</table>
-</body>
-</html>
-"""
-
-
-def run_help(crash, what):
- """Return the text of "crash -h
<what>"."""
- cmd = [crash, "--no_scroll", "--no_crashrc", "-h",
what]
- result = subprocess.run(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- if result.returncode != 0:
- sys.stderr.write(result.stderr.decode("utf-8", "replace"))
- raise SystemExit("failed to run: %s" % " ".join(cmd))
- return result.stdout.decode("utf-8", "replace")
-
-
-def parse_menu(text):
- """Split the "help commands" output (names, with BREAK row
markers)."""
- rows = []
- row = []
- for line in text.splitlines():
- line = line.strip()
- if line == "BREAK":
- if row:
- rows.append(row)
- row = []
- elif line:
- row.append(line)
- if row:
- rows.append(row)
- return rows
-
-
-def page_name(cmd):
- if cmd == "*":
- return "pointer"
- return cmd
-
-
-def strip_text(text):
- lines = text.splitlines()
- while lines and not lines[0].strip():
- lines.pop(0)
- while lines and not lines[-1].strip():
- lines.pop()
- return "\n".join(lines)
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument("--crash", required=True, help="path to the crash
binary")
- parser.add_argument("--out", required=True, help="output
directory")
- args = parser.parse_args()
-
- crash = os.path.abspath(args.crash)
- out = os.path.abspath(args.out)
- if not os.path.isfile(crash):
- raise SystemExit("no such crash binary: %s" % crash)
-
- pages_dir = os.path.join(out, "help_pages")
- os.makedirs(pages_dir, exist_ok=True)
-
- menu_rows = parse_menu(run_help(crash, "commands"))
- commands = [cmd for row in menu_rows for cmd in row]
-
- table = []
- for row in menu_rows:
- cells = []
- for cmd in row:
- target = "help_pages/%s.html" % page_name(cmd)
- cells.append('<td><a
href="%s">%s</a></td>'
- % (html.escape(target), html.escape(cmd)))
- table.append("<tr>%s</tr>" % "".join(cells))
-
- with open(os.path.join(out, "help.html"), "w",
encoding="utf-8") as f:
- f.write(MENU_PAGE.format(css=CSS, rows="\n".join(table)))
-
- for cmd in commands:
- text = strip_text(run_help(crash, cmd))
- path = os.path.join(pages_dir, page_name(cmd) + ".html")
- with open(path, "w", encoding="utf-8") as f:
- f.write(HELP_PAGE.format(cmd=html.escape(cmd),
- css=CSS,
- text=html.escape(text)))
- print("generated help.html and %d help pages in %s"
- % (len(commands), out))
-
-
-if __name__ == "__main__":
- main()