Speed up doc builds with spack list --format=html (#6945)
- Generating the HTML from for >2300 packages from RST in Sphinx seems to take forever. - Add an option to `spack list` to generate straight HTML instead. - This reduces the doc build time to about a minute (from 5 minutes on a mac laptop).
This commit is contained in:
parent
1fb38c9e04
commit
50ca4979e1
2
lib/spack/docs/.gitignore
vendored
2
lib/spack/docs/.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
package_list.rst
|
package_list.html
|
||||||
command_index.rst
|
command_index.rst
|
||||||
spack*.rst
|
spack*.rst
|
||||||
llnl*.rst
|
llnl*.rst
|
||||||
|
@ -83,7 +83,7 @@ help:
|
|||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f package_list.rst command_index.rst
|
-rm -f command_index.rst
|
||||||
-rm -rf $(BUILDDIR)/* $(APIDOC_FILES)
|
-rm -rf $(BUILDDIR)/* $(APIDOC_FILES)
|
||||||
|
|
||||||
html:
|
html:
|
||||||
|
@ -68,9 +68,10 @@
|
|||||||
#
|
#
|
||||||
# Generate package list using spack command
|
# Generate package list using spack command
|
||||||
#
|
#
|
||||||
with open('package_list.rst', 'w') as plist_file:
|
with open('package_list.html', 'w') as plist_file:
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
[spack_root + '/bin/spack', 'list', '--format=rst'], stdout=plist_file)
|
[spack_root + '/bin/spack', 'list', '--format=html'],
|
||||||
|
stdout=plist_file)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find all the `cmd-spack-*` references and add them to a command index
|
# Find all the `cmd-spack-*` references and add them to a command index
|
||||||
|
12
lib/spack/docs/package_list.rst
Normal file
12
lib/spack/docs/package_list.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
.. _package-list:
|
||||||
|
|
||||||
|
============
|
||||||
|
Package List
|
||||||
|
============
|
||||||
|
|
||||||
|
This is a list of things you can install using Spack. It is
|
||||||
|
automatically generated based on the packages in the latest Spack
|
||||||
|
release.
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
:file: package_list.html
|
@ -23,12 +23,14 @@
|
|||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import cgi
|
import cgi
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import math
|
||||||
|
|
||||||
from six import StringIO
|
from six import StringIO
|
||||||
|
|
||||||
@ -113,23 +115,35 @@ def name_only(pkgs):
|
|||||||
colify(pkgs, indent=indent)
|
colify(pkgs, indent=indent)
|
||||||
|
|
||||||
|
|
||||||
@formatter
|
def github_url(pkg):
|
||||||
def rst(pkgs):
|
|
||||||
"""Print out information on all packages in restructured text."""
|
|
||||||
|
|
||||||
def github_url(pkg):
|
|
||||||
"""Link to a package file on github."""
|
"""Link to a package file on github."""
|
||||||
url = 'https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/{0}/package.py'
|
url = 'https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/{0}/package.py'
|
||||||
return url.format(pkg.name)
|
return url.format(pkg.name)
|
||||||
|
|
||||||
def rst_table(elts):
|
|
||||||
|
def rst_table(elts):
|
||||||
"""Print out a RST-style table."""
|
"""Print out a RST-style table."""
|
||||||
cols = StringIO()
|
cols = StringIO()
|
||||||
ncol, widths = colify(elts, output=cols, tty=True)
|
ncol, widths = colify(elts, output=cols, tty=True)
|
||||||
header = ' '.join('=' * (w - 1) for w in widths)
|
header = ' '.join('=' * (w - 1) for w in widths)
|
||||||
return '%s\n%s%s' % (header, cols.getvalue(), header)
|
return '%s\n%s%s' % (header, cols.getvalue(), header)
|
||||||
|
|
||||||
pkg_names = pkgs
|
|
||||||
|
def rows_for_ncols(elts, ncols):
|
||||||
|
"""Print out rows in a table with ncols of elts laid out vertically."""
|
||||||
|
clen = int(math.ceil(len(elts) / ncols))
|
||||||
|
for r in range(clen):
|
||||||
|
row = []
|
||||||
|
for c in range(ncols):
|
||||||
|
i = c * clen + r
|
||||||
|
row.append(elts[i] if i < len(elts) else None)
|
||||||
|
yield row
|
||||||
|
|
||||||
|
|
||||||
|
@formatter
|
||||||
|
def rst(pkg_names):
|
||||||
|
"""Print out information on all packages in restructured text."""
|
||||||
|
|
||||||
pkgs = [spack.repo.get(name) for name in pkg_names]
|
pkgs = [spack.repo.get(name) for name in pkg_names]
|
||||||
|
|
||||||
print('.. _package-list:')
|
print('.. _package-list:')
|
||||||
@ -183,6 +197,102 @@ def rst_table(elts):
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
@formatter
|
||||||
|
def html(pkg_names):
|
||||||
|
"""Print out information on all packages in Sphinx HTML.
|
||||||
|
|
||||||
|
This is intended to be inlined directly into Sphinx documentation.
|
||||||
|
We write HTML instead of RST for speed; generating RST from *all*
|
||||||
|
packages causes the Sphinx build to take forever. Including this as
|
||||||
|
raw HTML is much faster.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Read in all packages
|
||||||
|
pkgs = [spack.repo.get(name) for name in pkg_names]
|
||||||
|
|
||||||
|
# Start at 2 because the title of the page from Sphinx is id1.
|
||||||
|
span_id = 2
|
||||||
|
|
||||||
|
# HTML header with an increasing id span
|
||||||
|
def head(n, span_id, title, anchor=None):
|
||||||
|
if anchor is None:
|
||||||
|
anchor = title
|
||||||
|
print(('<span id="id%d"></span>'
|
||||||
|
'<h1>%s<a class="headerlink" href="#%s" '
|
||||||
|
'title="Permalink to this headline">¶</a>'
|
||||||
|
'</h1>') % (span_id, title, anchor))
|
||||||
|
|
||||||
|
# Start with the number of packages, skipping the title and intro
|
||||||
|
# blurb, which we maintain in the RST file.
|
||||||
|
print('<p>')
|
||||||
|
print('Spack currently has %d mainline packages:' % len(pkgs))
|
||||||
|
print('</p>')
|
||||||
|
|
||||||
|
# Table of links to all packages
|
||||||
|
print('<table border="1" class="docutils">')
|
||||||
|
print('<tbody valign="top">')
|
||||||
|
for i, row in enumerate(rows_for_ncols(pkg_names, 3)):
|
||||||
|
print('<tr class="row-odd">' if i % 2 == 0 else
|
||||||
|
'<tr class="row-even">')
|
||||||
|
for name in row:
|
||||||
|
print('<td>')
|
||||||
|
print('<a class="reference internal" href="#%s">%s</a></td>'
|
||||||
|
% (name, name))
|
||||||
|
print('</td>')
|
||||||
|
print('</tr>')
|
||||||
|
print('</tbody>')
|
||||||
|
print('</table>')
|
||||||
|
print('<hr class="docutils"/>')
|
||||||
|
|
||||||
|
# Output some text for each package.
|
||||||
|
for pkg in pkgs:
|
||||||
|
print('<div class="section" id="%s">' % pkg.name)
|
||||||
|
head(2, span_id, pkg.name)
|
||||||
|
span_id += 1
|
||||||
|
|
||||||
|
print('<dl class="docutils">')
|
||||||
|
|
||||||
|
print('<dt>Homepage:</dt>')
|
||||||
|
print('<dd><ul class="first last simple">')
|
||||||
|
print(('<li>'
|
||||||
|
'<a class="reference external" href="%s">%s</a>'
|
||||||
|
'</li>') % (pkg.homepage, cgi.escape(pkg.homepage)))
|
||||||
|
print('</ul></dd>')
|
||||||
|
|
||||||
|
print('<dt>Spack package:</dt>')
|
||||||
|
print('<dd><ul class="first last simple">')
|
||||||
|
print(('<li>'
|
||||||
|
'<a class="reference external" href="%s">%s/package.py</a>'
|
||||||
|
'</li>') % (github_url(pkg), pkg.name))
|
||||||
|
print('</ul></dd>')
|
||||||
|
|
||||||
|
if pkg.versions:
|
||||||
|
print('<dt>Versions:</dt>')
|
||||||
|
print('<dd>')
|
||||||
|
print(', '.join(str(v) for v in reversed(sorted(pkg.versions))))
|
||||||
|
print('</dd>')
|
||||||
|
|
||||||
|
for deptype in spack.all_deptypes:
|
||||||
|
deps = pkg.dependencies_of_type(deptype)
|
||||||
|
if deps:
|
||||||
|
print('<dt>%s Dependencies:</dt>' % deptype.capitalize())
|
||||||
|
print('<dd>')
|
||||||
|
print(', '.join(
|
||||||
|
d if d not in pkg_names else
|
||||||
|
'<a class="reference internal" href="#%s">%s</a>' % (d, d)
|
||||||
|
for d in deps))
|
||||||
|
print('</dd>')
|
||||||
|
|
||||||
|
print('<dt>Description:</dt>')
|
||||||
|
print('<dd>')
|
||||||
|
print(cgi.escape(pkg.format_doc(indent=2)))
|
||||||
|
print('</dd>')
|
||||||
|
print('</dl>')
|
||||||
|
|
||||||
|
print('<hr class="docutils"/>')
|
||||||
|
print('</div>')
|
||||||
|
|
||||||
|
|
||||||
def list(parser, args):
|
def list(parser, args):
|
||||||
# Retrieve the names of all the packages
|
# Retrieve the names of all the packages
|
||||||
pkgs = set(spack.repo.all_package_names())
|
pkgs = set(spack.repo.all_package_names())
|
||||||
|
Loading…
Reference in New Issue
Block a user