diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2018-01-16 00:12:11 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-16 00:12:11 -0800 |
commit | 50ca4979e1cf9d02ab748ef9e0c599ba56ae089d (patch) | |
tree | 9380bed4ecae8684b326797a79da31c2f06b8a9a /lib | |
parent | 1fb38c9e042f9fb349718616e9522a8d99f80128 (diff) | |
download | spack-50ca4979e1cf9d02ab748ef9e0c599ba56ae089d.tar.gz spack-50ca4979e1cf9d02ab748ef9e0c599ba56ae089d.tar.bz2 spack-50ca4979e1cf9d02ab748ef9e0c599ba56ae089d.tar.xz spack-50ca4979e1cf9d02ab748ef9e0c599ba56ae089d.zip |
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).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/docs/.gitignore | 2 | ||||
-rw-r--r-- | lib/spack/docs/Makefile | 2 | ||||
-rw-r--r-- | lib/spack/docs/conf.py | 5 | ||||
-rw-r--r-- | lib/spack/docs/package_list.rst | 12 | ||||
-rw-r--r-- | lib/spack/spack/cmd/list.py | 138 |
5 files changed, 141 insertions, 18 deletions
diff --git a/lib/spack/docs/.gitignore b/lib/spack/docs/.gitignore index 9afb658706..0b6258af50 100644 --- a/lib/spack/docs/.gitignore +++ b/lib/spack/docs/.gitignore @@ -1,4 +1,4 @@ -package_list.rst +package_list.html command_index.rst spack*.rst llnl*.rst diff --git a/lib/spack/docs/Makefile b/lib/spack/docs/Makefile index 3503794021..9b07a39fbb 100644 --- a/lib/spack/docs/Makefile +++ b/lib/spack/docs/Makefile @@ -83,7 +83,7 @@ help: @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: - -rm -f package_list.rst command_index.rst + -rm -f command_index.rst -rm -rf $(BUILDDIR)/* $(APIDOC_FILES) html: diff --git a/lib/spack/docs/conf.py b/lib/spack/docs/conf.py index 94d301f6d9..2d38211b4c 100644 --- a/lib/spack/docs/conf.py +++ b/lib/spack/docs/conf.py @@ -68,9 +68,10 @@ os.environ['COLIFY_SIZE'] = '25x120' # # 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( - [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 diff --git a/lib/spack/docs/package_list.rst b/lib/spack/docs/package_list.rst new file mode 100644 index 0000000000..2deb5bfc0f --- /dev/null +++ b/lib/spack/docs/package_list.rst @@ -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 diff --git a/lib/spack/spack/cmd/list.py b/lib/spack/spack/cmd/list.py index 3549de361a..85d94a3fce 100644 --- a/lib/spack/spack/cmd/list.py +++ b/lib/spack/spack/cmd/list.py @@ -23,12 +23,14 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## from __future__ import print_function +from __future__ import division import argparse import cgi import fnmatch import re import sys +import math from six import StringIO @@ -113,23 +115,35 @@ def name_only(pkgs): colify(pkgs, indent=indent) -@formatter -def rst(pkgs): - """Print out information on all packages in restructured text.""" +def github_url(pkg): + """Link to a package file on github.""" + url = 'https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/{0}/package.py' + return url.format(pkg.name) + + +def rst_table(elts): + """Print out a RST-style table.""" + cols = StringIO() + ncol, widths = colify(elts, output=cols, tty=True) + header = ' '.join('=' * (w - 1) for w in widths) + return '%s\n%s%s' % (header, cols.getvalue(), header) - def github_url(pkg): - """Link to a package file on github.""" - url = 'https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/{0}/package.py' - return url.format(pkg.name) - def rst_table(elts): - """Print out a RST-style table.""" - cols = StringIO() - ncol, widths = colify(elts, output=cols, tty=True) - header = ' '.join('=' * (w - 1) for w in widths) - return '%s\n%s%s' % (header, cols.getvalue(), header) +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.""" - pkg_names = pkgs pkgs = [spack.repo.get(name) for name in pkg_names] print('.. _package-list:') @@ -183,6 +197,102 @@ def rst(pkgs): 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): # Retrieve the names of all the packages pkgs = set(spack.repo.all_package_names()) |