diff options
Diffstat (limited to 'website/defs.bzl')
-rw-r--r-- | website/defs.bzl | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/website/defs.bzl b/website/defs.bzl deleted file mode 100644 index f52946c15..000000000 --- a/website/defs.bzl +++ /dev/null @@ -1,178 +0,0 @@ -"""Wrappers for website documentation.""" - -load("//tools:defs.bzl", "short_path") - -# DocInfo is a provider which simple adds sufficient metadata to the source -# files (and additional data files) so that a jeyll header can be constructed -# dynamically. This is done the via BUILD system so that the plain -# documentation files can be viewable without non-compliant markdown headers. -DocInfo = provider( - fields = [ - "layout", - "description", - "permalink", - "category", - "subcategory", - "weight", - "editpath", - "authors", - ], -) - -def _doc_impl(ctx): - return [ - DefaultInfo( - files = depset(ctx.files.src + ctx.files.data), - ), - DocInfo( - layout = ctx.attr.layout, - description = ctx.attr.description, - permalink = ctx.attr.permalink, - category = ctx.attr.category, - subcategory = ctx.attr.subcategory, - weight = ctx.attr.weight, - editpath = short_path(ctx.files.src[0].short_path), - authors = ctx.attr.authors, - ), - ] - -doc = rule( - implementation = _doc_impl, - doc = "Annotate a document for jekyll headers.", - attrs = { - "src": attr.label( - doc = "The markdown source file.", - mandatory = True, - allow_single_file = True, - ), - "data": attr.label_list( - doc = "Additional data files (e.g. images).", - allow_files = True, - ), - "layout": attr.string( - doc = "The document layout.", - default = "docs", - ), - "description": attr.string( - doc = "The document description.", - default = "", - ), - "permalink": attr.string( - doc = "The document permalink.", - mandatory = True, - ), - "category": attr.string( - doc = "The document category.", - default = "", - ), - "subcategory": attr.string( - doc = "The document subcategory.", - default = "", - ), - "weight": attr.string( - doc = "The document weight.", - default = "50", - ), - "authors": attr.string_list(), - }, -) - -def _docs_impl(ctx): - # Tarball is the actual output. - tarball = ctx.actions.declare_file(ctx.label.name + ".tgz") - - # But we need an intermediate builder to translate the files. - builder = ctx.actions.declare_file("%s-builder" % ctx.label.name) - builder_content = [ - "#!/bin/bash", - "set -euo pipefail", - "declare -r T=$(mktemp -d)", - "function cleanup {", - " rm -rf $T", - "}", - "trap cleanup EXIT", - ] - for dep in ctx.attr.deps: - doc = dep[DocInfo] - - # Sanity check the permalink. - if not doc.permalink.endswith("/"): - fail("permalink %s for target %s should end with /" % ( - doc.permalink, - ctx.label.name, - )) - - # Construct the header. - header = """\ -description: {description} -permalink: {permalink} -category: {category} -subcategory: {subcategory} -weight: {weight} -editpath: {editpath} -authors: {authors} -layout: {layout}""" - - for f in dep.files.to_list(): - # Is this a markdown file? If not, then we ensure that it ends up - # in the same path as the permalink for relative addressing. - if not f.basename.endswith(".md"): - builder_content.append("mkdir -p $T/%s" % doc.permalink) - builder_content.append("cp %s $T/%s" % (f.path, doc.permalink)) - continue - - # Is this a post? If yes, then we must put this in the _posts - # directory. This directory is treated specially with respect to - # pagination and page generation. - dest = f.short_path - if doc.layout == "post": - dest = "_posts/" + f.basename - builder_content.append("echo Processing %s... >&2" % f.short_path) - builder_content.append("mkdir -p $T/$(dirname %s)" % dest) - - # Construct the header dynamically. We include the title field from - # the markdown itself, as this is the g3doc format required. The - # title will be injected by the web layout however, so we don't - # want this to appear in the document. - args = dict([(k, getattr(doc, k)) for k in dir(doc)]) - builder_content.append("title=\"$(grep -E '^# ' %s | head -n 1 | cut -d'#' -f2- || true)\"" % f.path) - builder_content.append("cat >$T/%s <<EOF" % dest) - builder_content.append("---") - builder_content.append("title: $title") - builder_content.append(header.format(**args)) - builder_content.append("---") - builder_content.append("EOF") - - # To generate the final page, we need to strip out the title (which - # was pulled above to generate the annotation in the frontmatter, - # and substitute the [TOC] tag with the {% toc %} plugin tag. Note - # that the pipeline here is almost important, as the grep will - # return non-zero if the file is empty, but we ignore that within - # the pipeline. - builder_content.append("grep -v -E '^# ' %s | sed -e 's|^\\[TOC\\]$|- TOC\\n{:toc}|' >>$T/%s" % - (f.path, dest)) - - builder_content.append("declare -r filename=$(readlink -m %s)" % tarball.path) - builder_content.append("(cd $T && tar -zcf \"${filename}\" .)\n") - ctx.actions.write(builder, "\n".join(builder_content), is_executable = True) - - # Generate the tarball. - ctx.actions.run( - inputs = depset(ctx.files.deps), - outputs = [tarball], - progress_message = "Generating %s" % ctx.label, - executable = builder, - ) - return [DefaultInfo( - files = depset([tarball]), - )] - -docs = rule( - implementation = _docs_impl, - doc = "Construct a site tarball from doc dependencies.", - attrs = { - "deps": attr.label_list( - doc = "All document dependencies.", - ), - }, -) |