Build encyclopedia: moved the HTML out of the java class into templates

--
MOS_MIGRATED_REVID=87704425
diff --git a/src/main/java/com/google/devtools/build/docgen/PredefinedAttributes.java b/src/main/java/com/google/devtools/build/docgen/PredefinedAttributes.java
index c885cc1..1d2b35e 100644
--- a/src/main/java/com/google/devtools/build/docgen/PredefinedAttributes.java
+++ b/src/main/java/com/google/devtools/build/docgen/PredefinedAttributes.java
@@ -14,334 +14,49 @@
 package com.google.devtools.build.docgen;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.io.ByteStreams;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 
 /**
  * A class to contain the base definition of common BUILD rule attributes.
+ * 
+ * <p>It looks for the {@code {common,binary,test}} directory of the attributes template directory.
+ * Each file in that directory should be named after the attribute name and contains the HTML
+ * description of the attribute.
  */
 public class PredefinedAttributes {
 
-  public static final Map<String, RuleDocumentationAttribute> COMMON_ATTRIBUTES = ImmutableMap
-      .<String, RuleDocumentationAttribute>builder()
-      .put("deps", RuleDocumentationAttribute.create("deps", DocgenConsts.COMMON_ATTRIBUTES,
-          "A list of dependencies of this rule.\n"
-        + "<i>(List of <a href=\"build-ref.html#labels\">labels</a>; optional)</i><br/>\n"
-        + "The precise semantics of what it means for this rule to depend on\n"
-        + "another using <code>deps</code> are specific to the kind of this rule,\n"
-        + "and the rule-specific documentation below goes into more detail.\n"
-        + "At a minimum, though, the targets named via <code>deps</code> will\n"
-        + "appear in the <code>*.runfiles</code> area of this rule, if it has\n"
-        + "one.\n"
-        + "<p>Most often, a <code>deps</code> dependency is used to allow one\n"
-        + "module to use symbols defined in another module written in the\n"
-        + "same programming language and separately compiled.  Cross-language\n"
-        + "dependencies are also permitted in many cases: for example,\n"
-        + "a <code>java_library</code> rule may depend on C++ code in\n"
-        + "a <code>cc_library</code> rule, by declaring the latter in\n"
-        + "the <code>deps</code> attribute.  See the definition\n"
-        + "of <a href=\"build-ref.html#deps\">dependencies</a> for more\n"
-        + "information.</p>\n"
-        + "<p>Almost all rules permit a <code>deps</code> attribute, but where\n"
-        + "this attribute is not allowed, this fact is documented under the\n"
-        + "specific rule.</p>"))
-      .put("data", RuleDocumentationAttribute.create("data", DocgenConsts.COMMON_ATTRIBUTES,
-          "The list of files needed by this rule at runtime.\n"
-        + "<i>(List of <a href=\"build-ref.html#labels\">labels</a>; optional)</i><br/>\n"
-        + "Targets named in the <code>data</code> attribute will appear in\n"
-        + "the <code>*.runfiles</code> area of this rule, if it has one.  This\n"
-        + "may include data files needed by a binary or library, or other\n"
-        + "programs needed by it.  See the\n"
-        + "<a href=\"build-ref.html#data\">data dependencies</a> section for more\n"
-        + "information about how to depend on and use data files.\n"
-        + "<p>Almost all rules permit a <code>data</code> attribute, but where\n"
-        + "this attribute is not allowed, this fact is documented under the\n"
-        + "specific rule.</p>"))
-      .put("licenses", RuleDocumentationAttribute.create("licenses",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(List of strings; optional)</i><br/>\n"
-        + "A list of license-type strings to be used for this particular build rule.\n"
-        + "Overrides the <code>BUILD</code>-file scope defaults defined by the\n"
-        + "<a href=\"#licenses\"><code>licenses()</code></a> directive."))
-      .put("distribs", RuleDocumentationAttribute.create("distribs",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(List of strings; optional)</i><br/>\n"
-        + "A list of distribution-method strings to be used for this particular build rule.\n"
-        + "Overrides the <code>BUILD</code>-file scope defaults defined by the\n"
-        + "<a href=\"#distribs\"><code>distribs()</code></a> directive."))
-      .put("deprecation", RuleDocumentationAttribute.create("deprecation",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(String; optional)</i><br/>\n"
-        + "An explanatory warning message associated with this rule.\n"
-        + "Typically this is used to notify users that a rule has become obsolete,\n"
-        + "or has become superseded by another rule, is private to a package, or is\n"
-        + "perhaps \"considered harmful\" for some reason. It is a good idea to include\n"
-        + "some reference (like a webpage, a bug number or example migration CLs) so\n"
-        + "that one can easily find out what changes are required to avoid the message.\n"
-        + "If there is a new target that can be used as a drop in replacement, it is a good idea\n"
-        + "to just migrate all users of the old target.\n"
-        + "<p>\n"
-        + "This attribute has no effect on the way things are built, but it\n"
-        + "may affect a build tool's diagnostic output.  The build tool issues a\n"
-        + "warning when a rule with a <code>deprecation</code> attribute is\n"
-        + "depended upon by another rule.</p>\n"
-        + "<p>\n"
-        + "Intra-package dependencies are exempt from this warning, so that,\n"
-        + "for example, building the tests of a deprecated rule does not\n"
-        + "encounter a warning.</p>\n"
-        + "<p>\n"
-        + "If a deprecated rule depends on another deprecated rule, no warning\n"
-        + "message is issued.</p>\n"
-        + "<p>\n"
-        + "Once people have stopped using it, the package can be removed or marked as\n"
-        + "<a href=\"#common.obsolete\"><code>obsolete</code></a>.</p>"))
-      .put("obsolete", RuleDocumentationAttribute.create("obsolete",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(Boolean; optional; default 0)</i><br/>\n"
-        + "If 1, only obsolete targets can depend on this target. It is an error when\n"
-        + "a non-obsolete target depends on an obsolete target.\n"
-        + "<p>\n"
-        + "As a transition, one can first mark a package as in\n"
-        + "<a href=\"#common.deprecation\"><code>deprecation</code></a>.</p>\n"
-        + "<p>\n"
-        + "This attribute is useful when you want to prevent a target from\n"
-        + "being used but are yet not ready to delete the sources.</p>"))
-      .put("testonly", RuleDocumentationAttribute.create("testonly",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(Boolean; optional; default 0 except as noted)</i><br />\n"
-        + "If 1, only testonly targets (such as tests) can depend on this target.\n"
-        + "<p>Equivalently, a rule that is not <code>testonly</code> is not allowed to\n"
-        + "depend on any rule that is <code>testonly</code>.</p>\n"
-        + "<p>Tests (<code>*_test</code> rules)\n"
-        + "and test suites (<a href=\"#test_suite\">test_suite</a> rules)\n"
-        + "are <code>testonly</code> by default.</p>\n"
-        + "<p>By virtue of\n"
-        + "<a href=\"#package.default_testonly\"><code>default_testonly</code></a>,\n"
-        + "targets under <code>javatests</code> are <code>testonly</code> by default.</p>\n"
-        + "<p>This attribute is intended to mean that the target should not be\n"
-        + "contained in binaries that are released to production.</p>\n"
-        + "<p>Because testonly is enforced at build time, not run time, and propagates\n"
-        + "virally through the dependency tree, it should be applied judiciously. For\n"
-        + "example, stubs and fakes that\n"
-        + "are useful for unit tests may also be useful for integration tests\n"
-        + "involving the same binaries that will be released to production, and\n"
-        + "therefore should probably not be marked testonly. Conversely, rules that\n"
-        + "are dangerous to even link in, perhaps because they unconditionally\n"
-        + "override normal behavior, should definitely be marked testonly.</p>"))
-      .put("tags", RuleDocumentationAttribute.create("tags", DocgenConsts.COMMON_ATTRIBUTES,
-          "List of arbitrary text tags.  Tags may be any valid string; default is the\n"
-        + "empty list.<br/>\n"
-        + "<i>Tags</i> can be used on any rule; but <i>tags</i> are most useful\n"
-        + "on test and <code>test_suite</code> rules.  Tags on non-test rules\n"
-        + "are only useful to humans and/or external programs.\n"
-        + "<i>Tags</i> are generally used to annotate a test's role in your debug\n"
-        + "and release process.  Typically, tags are most useful for C++ and\n"
-        + "Python tests, which\n"
-        + "lack any runtime annotation ability.  The use of tags and size elements\n"
-        + "gives flexibility in assembling suites of tests based around codebase\n"
-        + "check-in policy.\n"
-        + "<p>\n"
-        + "A few tags have special meaning to the build tool, such as\n"
-        + "indicating that a particular test cannot be run remotely, for\n"
-        + "example. Consult\n"
-        + "the <a href='blaze-user-manual.html#tags_keywords'>Blaze\n"
-        + "documentation</a> for details.\n"
-        + "</p>"))
-      .put("visibility", RuleDocumentationAttribute.create("visibility",
-          DocgenConsts.COMMON_ATTRIBUTES,
-          "<i>(List of <a href=\"build-ref.html#labels\">"
-        + "labels</a>; optional; default private)</i><br/>\n"
-        + "<p>The <code>visibility</code> attribute on a rule controls whether\n"
-        + "the rule can be used by other packages. Rules are always visible to\n"
-        + "other rules declared in the same package.</p>\n"
-        + "<p>There are five forms (and one temporary form) a visibility label can take:\n"
-        + "<ul>\n"
-        + "<li><code>[\"//visibility:public\"]</code>: Anyone can use this rule.</li>\n"
-        + "<li><code>[\"//visibility:private\"]</code>: Only rules in this package\n"
-        + "can use this rule.  Rules in <code>javatests/foo/bar</code>\n"
-        + "can always use rules in <code>java/foo/bar</code>.\n"
-        + "</li>\n"
-        + "<li><code>[\"//some/package:__pkg__\", \"//other/package:__pkg__\"]</code>:\n"
-        + "Only rules in <code>some/package</code> and <code>other/package</code>\n"
-        + "(defined in <code>some/package/BUILD</code> and\n"
-        + "<code>other/package/BUILD</code>) have access to this rule. Note that\n"
-        + "sub-packages do not have access to the rule; for example,\n"
-        + "<code>//some/package/foo:bar</code> or\n"
-        + "<code>//other/package/testing:bla</code> wouldn't have access.\n"
-        + "<code>__pkg__</code> is a special target and must be used verbatim.\n"
-        + "It represents all of the rules in the package.\n"
-        + "</li>\n"
-        + "<li><code>[\"//project:__subpackages__\", \"//other:__subpackages__\"]</code>:\n"
-        + "Only rules in packages <code>project</code> or <code>other</code> or\n"
-        + "in one of their sub-packages have access to this rule. For example,\n"
-        + "<code>//project:rule</code>, <code>//project/library:lib</code> or\n"
-        + "<code>//other/testing/internal:munge</code> are allowed to depend on\n"
-        + "this rule (but not <code>//independent:evil</code>)\n"
-        + "</li>\n"
-        + "<li><code>[\"//some/package:my_package_group\"]</code>:\n"
-        + "A <a href=\"#package_group\">package group</a> is\n"
-        + "a named set of package names. Package groups can also grant access rights\n"
-        + "to entire subtrees, e.g.<code>//myproj/...</code>.\n"
-        + "</li>\n"
-        + "<li><code>[\"//visibility:legacy_public\"]</code>: Anyone can use this\n"
-        + "rule (for now). <i>Developer action is needed</i>.\n"
-        + "<p>This value has been used during the transition to the new\n"
-        + "<code>[\"//visibility:private\"]</code> default, on June 6, 2011.\n"
-        + "<i>We will eventually deprecate and then disallow this value.</i>\n"
-        + "</li>\n"
-        + "</ul>\n"
-        + "<p>The visibility specifications of <code>//visibility:public</code>,\n"
-        + "<code>//visibility:private</code> and\n"
-        + "<code>//visibility:legacy_public</code>\n"
-        + "can not be combined with any other visibility specifications.\n"
-        + "A visibility specification may contain a combination of package labels\n"
-        + "(i.e. //foo:__pkg__) and package_groups.</p>\n"
-        + "<p>If a rule does not specify the visibility attribute,\n"
-        + "the <code><a href=\"#package\">default_visibility</a></code>\n"
-        + "attribute of the <code><a href=\"#package\">package</a></code>\n"
-        + "statement in the BUILD file containing the rule is used\n"
-        + "(except <a href=\"#exports_files\">exports_files</a> and\n"
-        + "<a href=\"#cc_public_library\">cc_public_library</a>, which always default to\n"
-        + "public).</p>\n"
-        + "<p>If the default visibility for the package is not specified,\n"
-        + "the rule is private: on June 6, 2011, in order to prevent teams\n"
-        + "from reaching into private code, the default has been changed\n"
-        + "to <code>[\"//visibility:private\"]</code>.</p>\n"
-        + "<p><b>Example</b>:</p>\n"
-        + "<p>\n"
-        + "File <code>//frobber/bin/BUILD</code>:\n"
-        + "</p>\n"
-        + "<pre class=\"code\">\n"
-        + "# This rule is visible to everyone\n"
-        + "py_binary(\n"
-        + "    name = \"executable\",\n"
-        + "    visibility = [\"//visibility:public\"],\n"
-        + "    deps = [\":library\"],\n"
-        + ")\n"
-        + "\n"
-        + "# This rule is visible only to rules declared in the same package\n"
-        + "py_library(\n"
-        + "    name = \"library\",\n"
-        + "    visibility = [\"//visibility:private\"],\n"
-        + ")\n"
-        + "\n"
-        + "# This rule is visible to rules in package //object and //noun\n"
-        + "py_library(\n"
-        + "    name = \"subject\",\n"
-        + "    visibility = [\n"
-        + "        \"//noun:__pkg__\",\n"
-        + "        \"//object:__pkg__\",\n"
-        + "    ],\n"
-        + ")\n"
-        + "\n"
-        + "# See package group //frobber:friends (below) for who can access this rule.\n"
-        + "py_library(\n"
-        + "    name = \"thingy\",\n"
-        + "    visibility = [\"//frobber:friends\"],\n"
-        + ")\n"
-        + "</pre>\n"
-        + "<p>\n"
-        + "File <code>//frobber/BUILD</code>:\n"
-        + "</p>\n"
-        + "<pre class=\"code\">\n"
-        + "# This is the package group declaration to which rule //frobber/bin:thingy refers.\n"
-        + "#\n"
-        + "# Our friends are packages //frobber, //fribber and any subpackage of //fribber.\n"
-        + "package_group(\n"
-        + "    name = \"friends\",\n"
-        + "    packages = [\n"
-        + "        \"//fribber/...\",\n"
-        + "        \"//frobber\",\n"
-        + "    ],\n"
-        + ")\n"
-        + "</pre>"))
-      .build();
+  private static ImmutableMap<String, RuleDocumentationAttribute> generateAttributeMap(
+      String commonType, String... names) {
+    Builder<String, RuleDocumentationAttribute> builder =
+        ImmutableMap.<String, RuleDocumentationAttribute>builder();
+    for (String name : names) {
+      String filename = "templates/attributes/" + commonType + "/" + name + ".html";
+      try {
+        InputStream stream = PredefinedAttributes.class.getResourceAsStream(filename);
+        String content = new String(ByteStreams.toByteArray(stream), StandardCharsets.UTF_8);
+        builder.put(name, RuleDocumentationAttribute.create(name, commonType, content));
+      } catch (IOException e) {
+        System.err.println("Exception while reading " + filename + ", skipping!");
+        e.printStackTrace();
+      }
+    }
+    return builder.build();
+  }
 
-  public static final Map<String, RuleDocumentationAttribute> BINARY_ATTRIBUTES = ImmutableMap.of(
-      "args", RuleDocumentationAttribute.create("args", DocgenConsts.BINARY_ATTRIBUTES,
-          "Add these arguments to the target when executed by\n"
-        + "<code>blaze run</code>.\n"
-        + "<i>(List of strings; optional; subject to\n"
-        + "<a href=\"#make_variables\">\"Make variable\"</a> substitution and\n"
-        + "<a href=\"#sh-tokenization\">Bourne shell tokenization</a>)</i><br/>\n"
-        + "These arguments are passed to the target before the target options\n"
-        + "specified on the <code>blaze run</code> command line.\n"
-        + "<p>Most binary rules permit an <code>args</code> attribute, but where\n"
-        + "this attribute is not allowed, this fact is documented under the\n"
-        + "specific rule.</p>"),
-      "output_licenses", RuleDocumentationAttribute.create("output_licenses",
-          DocgenConsts.BINARY_ATTRIBUTES,
-          "The licenses of the output files that this binary generates.\n"
-        + "<i>(List of strings; optional)</i><br/>\n"
-        + "Describes the licenses of the output of the binary generated by\n"
-        + "the rule. When a binary is referenced in a host attribute (for\n"
-        + "example, the <code>tools</code> attribute of\n"
-        + "a <code>genrule</code>), this license declaration is used rather\n"
-        + "than the union of the licenses of its transitive closure. This\n"
-        + "argument is useful when a binary is used as a tool during the\n"
-        + "build of a rule, and it is not desirable for its license to leak\n"
-        + "into the license of that rule. If this attribute is missing, the\n"
-        + "license computation proceeds as if the host dependency was a\n"
-        + "regular dependency.\n"
-        + "<p>(For more about the distinction between host and target\n"
-        + "configurations,\n"
-        + "see <a href=\"blaze-user-manual.html#configurations\">"
-        + "Build configurations</a> in the Blaze manual.)\n"
-        + "<p><em class=\"harmful\">WARNING: in some cases (specifically, in\n"
-        + "genrules) the build tool cannot guarantee that the binary\n"
-        + "referenced by this attribute is actually used as a tool, and is\n"
-        + "not, for example, copied to the output. In these cases, it is the\n"
-        + "responsibility of the user to make sure that this is\n"
-        + "true.</em></p>"));
+  public static final Map<String, RuleDocumentationAttribute> COMMON_ATTRIBUTES =
+      generateAttributeMap(DocgenConsts.COMMON_ATTRIBUTES, "deps", "data", "licenses",
+          "distribs", "deprecation", "obsolete", "testonly", "tags", "visibility");
 
-  public static final Map<String, RuleDocumentationAttribute> TEST_ATTRIBUTES = ImmutableMap
-      .<String, RuleDocumentationAttribute>builder()
-      .put("args", RuleDocumentationAttribute.create("args", DocgenConsts.TEST_ATTRIBUTES,
-          "Add these arguments to the <code>--test_arg</code>\n"
-        + "when executed by <code>blaze test</code>.\n"
-        + "<i>(List of strings; optional; subject to\n"
-        + "<a href=\"#make_variables\">\"Make variable\"</a> substitution and\n"
-        + "<a href=\"#sh-tokenization\">Bourne shell tokenization</a>)</i><br/>\n"
-        + "These arguments are passed before the <code>--test_arg</code> values\n"
-        + "specified on the <code>blaze test</code> command line."))
-      .put("size", RuleDocumentationAttribute.create("size", DocgenConsts.TEST_ATTRIBUTES,
-          "How \"heavy\" the test is\n"
-        + "<i>(String \"enormous\", \"large\" \"medium\" or \"small\",\n"
-        + "default is \"medium\")</i><br/>\n"
-        + "A classification of the test's \"heaviness\": how much time/resources\n"
-        + "it needs to run."
-        + "Unittests are considered \"small\", integration tests \"medium\", "
-        + "and end-to-end tests \"large\" or \"enormous\". "
-        + "Blaze uses the size only to determine a default timeout."))
-      .put("timeout", RuleDocumentationAttribute.create("timeout", DocgenConsts.TEST_ATTRIBUTES,
-          "How long the test is\n"
-        + "normally expected to run before returning.\n"
-        + "<i>(String \"eternal\", \"long\", \"moderate\", or \"short\"\n"
-        + "with the default derived from a test's size attribute)</i><br/>\n"
-        + "While a test's size attribute controls resource estimation, a test's\n"
-        + "timeout may be set independently.  If not explicitly specified, the\n"
-        + "timeout is based on the test's size (with \"small\" &rArr; \"short\",\n"
-        + "\"medium\" &rArr; \"moderate\", etc...). "
-        + "\"short\" means 1 minute, \"moderate\" 5 minutes, and \"long\" 15 minutes."))
-      .put("flaky", RuleDocumentationAttribute.create("flaky", DocgenConsts.TEST_ATTRIBUTES,
-          "Marks test as flaky. <i>(Boolean; optional)</i><br/>\n"
-        + "If set, executes the test up to 3 times before being declared as failed.\n"
-        + "By default this attribute is set to 0 and test is considered to be stable.\n"
-        + "Note, that use of this attribute is generally discouraged - we do prefer\n"
-        + "all tests to be stable."))
-      .put("shard_count", RuleDocumentationAttribute.create("shard_count",
-          DocgenConsts.TEST_ATTRIBUTES,
-          "Specifies the number of parallel shards\n"
-        + "to use to run the test. <i>(Non-negative integer less than or equal to 50;\n"
-        + "optional)</i><br/>\n"
-        + "This value will override any heuristics used to determine the number of\n"
-        + "parallel shards with which to run the test. Note that for some test\n"
-        + "rules, this parameter may be required to enable sharding\n"
-        + "in the first place. Also see --test_sharding_strategy."))
-      .put("local", RuleDocumentationAttribute.create("local", DocgenConsts.TEST_ATTRIBUTES,
-          "Forces the test to be run locally. <i>(Boolean; optional)</i><br/>\n"
-        + "By default this attribute is set to 0 and the default testing strategy is\n"
-        + "used. This is equivalent to providing \"local\" as a tag\n"
-        + "(<code>tags=[\"local\"]</code>)."))
-      .build();
+  public static final Map<String, RuleDocumentationAttribute> BINARY_ATTRIBUTES =
+      generateAttributeMap(DocgenConsts.BINARY_ATTRIBUTES, "args", "output_licenses");
+
+  public static final Map<String, RuleDocumentationAttribute> TEST_ATTRIBUTES =
+      generateAttributeMap(DocgenConsts.TEST_ATTRIBUTES, "args", "size", "timeout", "flaky",
+          "shard_count", "local");
 }
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/args.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/args.html
new file mode 100644
index 0000000..9bc0a5c
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/args.html
@@ -0,0 +1,10 @@
+Add these arguments to the target when executed by
+<code>bazel run</code>.
+<i>(List of strings; optional; subject to
+<a href="#make_variables">"Make variable"</a> substitution and
+<a href="#sh-tokenization">Bourne shell tokenization</a>)</i><br/>
+These arguments are passed to the target before the target options
+specified on the <code>bazel run</code> command line.
+<p>Most binary rules permit an <code>args</code> attribute, but where
+this attribute is not allowed, this fact is documented under the
+specific rule.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/output_licenses.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/output_licenses.html
new file mode 100644
index 0000000..8716afa
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/binary/output_licenses.html
@@ -0,0 +1,22 @@
+The licenses of the output files that this binary generates.
+<i>(List of strings; optional)</i><br/>
+Describes the licenses of the output of the binary generated by
+the rule. When a binary is referenced in a host attribute (for
+example, the <code>tools</code> attribute of
+a <code>genrule</code>), this license declaration is used rather
+than the union of the licenses of its transitive closure. This
+argument is useful when a binary is used as a tool during the
+build of a rule, and it is not desirable for its license to leak
+into the license of that rule. If this attribute is missing, the
+license computation proceeds as if the host dependency was a
+regular dependency.
+<p>(For more about the distinction between host and target
+configurations,
+see <a href="bazel-user-manual.html#configurations">Build
+configurations</a> in the Bazel manual.)
+<p><em class="harmful">WARNING: in some cases (specifically, in
+genrules) the build tool cannot guarantee that the binary
+referenced by this attribute is actually used as a tool, and is
+not, for example, copied to the output. In these cases, it is the
+responsibility of the user to make sure that this is
+true.</em></p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/data.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/data.html
new file mode 100644
index 0000000..a0815ed
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/data.html
@@ -0,0 +1,11 @@
+The list of files needed by this rule at runtime.
+<i>(List of <a href="build-ref.html#labels">labels</a>; optional)</i><br/>
+Targets named in the <code>data</code> attribute will appear in
+the <code>*.runfiles</code> area of this rule, if it has one.  This
+may include data files needed by a binary or library, or other
+programs needed by it.  See the
+<a href="build-ref.html#data">data dependencies</a> section for more
+information about how to depend on and use data files.
+<p>Almost all rules permit a <code>data</code> attribute, but where
+this attribute is not allowed, this fact is documented under the
+specific rule.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deprecation.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deprecation.html
new file mode 100644
index 0000000..707fc07
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deprecation.html
@@ -0,0 +1,24 @@
+<i>(String; optional)</i><br/>
+An explanatory warning message associated with this rule.
+Typically this is used to notify users that a rule has become obsolete,
+or has become superseded by another rule, is private to a package, or is
+perhaps considered harmful for some reason. It is a good idea to include
+some reference (like a webpage, a bug number or example migration CLs) so
+that one can easily find out what changes are required to avoid the message.
+If there is a new target that can be used as a drop in replacement, it is a
+good idea to just migrate all users of the old target.
+<p>
+This attribute has no effect on the way things are built, but it
+may affect a build tool's diagnostic output.  The build tool issues a
+warning when a rule with a <code>deprecation</code> attribute is
+depended upon by another rule.</p>
+<p>
+Intra-package dependencies are exempt from this warning, so that,
+for example, building the tests of a deprecated rule does not
+encounter a warning.</p>
+<p>
+If a deprecated rule depends on another deprecated rule, no warning
+message is issued.</p>
+<p>
+Once people have stopped using it, the package can be removed or marked as
+<a href="#common.obsolete"><code>obsolete</code></a>.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deps.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deps.html
new file mode 100644
index 0000000..9b42a2b
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/deps.html
@@ -0,0 +1,20 @@
+A list of dependencies of this rule.
+<i>(List of <a href="build-ref.html#labels">labels</a>; optional)</i><br/>
+The precise semantics of what it means for this rule to depend on
+another using <code>deps</code> are specific to the kind of this rule,
+and the rule-specific documentation below goes into more detail.
+At a minimum, though, the targets named via <code>deps</code> will
+appear in the <code>*.runfiles</code> area of this rule, if it has
+one.
+<p>Most often, a <code>deps</code> dependency is used to allow one
+module to use symbols defined in another module written in the
+same programming language and separately compiled.  Cross-language
+dependencies are also permitted in many cases: for example,
+a <code>java_library</code> rule may depend on C++ code in
+a <code>cc_library</code> rule, by declaring the latter in
+the <code>deps</code> attribute.  See the definition
+of <a href="build-ref.html#deps">dependencies</a> for more
+information.</p>
+<p>Almost all rules permit a <code>deps</code> attribute, but where
+this attribute is not allowed, this fact is documented under the
+specific rule.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/distribs.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/distribs.html
new file mode 100644
index 0000000..4ce6078
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/distribs.html
@@ -0,0 +1,4 @@
+<i>(List of strings; optional)</i><br/>
+A list of distribution-method strings to be used for this particular build rule.
+Overrides the <code>BUILD</code>-file scope defaults defined by the
+<a href="#distribs"><code>distribs()</code></a> directive.
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/licenses.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/licenses.html
new file mode 100644
index 0000000..e0f831e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/licenses.html
@@ -0,0 +1,4 @@
+<i>(List of strings; optional)</i><br/>
+A list of license-type strings to be used for this particular build rule.
+Overrides the <code>BUILD</code>-file scope defaults defined by the
+<a href="#licenses"><code>licenses()</code></a> directive.
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/obsolete.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/obsolete.html
new file mode 100644
index 0000000..93363c5
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/obsolete.html
@@ -0,0 +1,9 @@
+<i>(Boolean; optional; default 0)</i><br/>
+If 1, only obsolete targets can depend on this target. It is an error when
+a non-obsolete target depends on an obsolete target.
+<p>
+As a transition, one can first mark a package as in
+<a href="#common.deprecation"><code>deprecation</code></a>.</p>
+<p>
+This attribute is useful when you want to prevent a target from
+being used but are yet not ready to delete the sources.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html
new file mode 100644
index 0000000..e26672c
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html
@@ -0,0 +1,18 @@
+List of arbitrary text tags.  Tags may be any valid string; default is the
+empty list.<br/>
+<i>Tags</i> can be used on any rule; but <i>tags</i> are most useful
+on test and <code>test_suite</code> rules.  Tags on non-test rules
+are only useful to humans and/or external programs.
+<i>Tags</i> are generally used to annotate a test's role in your debug
+and release process.  Typically, tags are most useful for C++ and
+Python tests, which
+lack any runtime annotation ability.  The use of tags and size elements
+gives flexibility in assembling suites of tests based around codebase
+check-in policy.
+<p>
+A few tags have special meaning to the build tool, such as
+indicating that a particular test cannot be run remotely, for
+example. Consult
+the <a href='bazel-user-manual.html#tags_keywords'>Bazel
+documentation</a> for details.
+</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html
new file mode 100644
index 0000000..0e9a80f
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html
@@ -0,0 +1,20 @@
+<i>(Boolean; optional; default 0 except as noted)</i><br />
+If 1, only testonly targets (such as tests) can depend on this target.
+<p>Equivalently, a rule that is not <code>testonly</code> is not allowed to
+depend on any rule that is <code>testonly</code>.</p>
+<p>Tests (<code>*_test</code> rules)
+and test suites (<a href="#test_suite">test_suite</a> rules)
+are <code>testonly</code> by default.</p>
+<p>By virtue of
+<a href="#package.default_testonly"><code>default_testonly</code></a>,
+targets under <code>javatests</code> are <code>testonly</code> by default.</p>
+<p>This attribute is intended to mean that the target should not be
+contained in binaries that are released to production.</p>
+<p>Because testonly is enforced at build time, not run time, and propagates
+virally through the dependency tree, it should be applied judiciously. For
+example, stubs and fakes that
+are useful for unit tests may also be useful for integration tests
+involving the same binaries that will be released to production, and
+therefore should probably not be marked testonly. Conversely, rules that
+are dangerous to even link in, perhaps because they unconditionally
+override normal behavior, should definitely be marked testonly.</p>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/visibility.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/visibility.html
new file mode 100644
index 0000000..65e6ce3
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/visibility.html
@@ -0,0 +1,99 @@
+<i>(List of <a href="build-ref.html#labels">labels</a>; optional;
+default private)</i><br/>
+<p>The <code>visibility</code> attribute on a rule controls whether
+the rule can be used by other packages. Rules are always visible to
+other rules declared in the same package.</p>
+<p>There are five forms (and one temporary form) a visibility label can take:
+<ul>
+<li><code>["//visibility:public"]</code>: Anyone can use this rule.</li>
+<li><code>["//visibility:private"]</code>: Only rules in this package
+can use this rule.  Rules in <code>javatests/foo/bar</code>
+can always use rules in <code>java/foo/bar</code>.
+</li>
+<li><code>["//some/package:__pkg__", "//other/package:__pkg__"]</code>:
+Only rules in <code>some/package</code> and <code>other/package</code>
+(defined in <code>some/package/BUILD</code> and
+<code>other/package/BUILD</code>) have access to this rule. Note that
+sub-packages do not have access to the rule; for example,
+<code>//some/package/foo:bar</code> or
+<code>//other/package/testing:bla</code> wouldn't have access.
+<code>__pkg__</code> is a special target and must be used verbatim.
+It represents all of the rules in the package.
+</li>
+<li><code>["//project:__subpackages__", "//other:__subpackages__"]</code>:
+Only rules in packages <code>project</code> or <code>other</code> or
+in one of their sub-packages have access to this rule. For example,
+<code>//project:rule</code>, <code>//project/library:lib</code> or
+<code>//other/testing/internal:munge</code> are allowed to depend on
+this rule (but not <code>//independent:evil</code>)
+</li>
+<li><code>["//some/package:my_package_group"]</code>:
+A <a href="#package_group">package group</a> is
+a named set of package names. Package groups can also grant access rights
+to entire subtrees, e.g.<code>//myproj/...</code>.
+</li>
+
+</ul>
+<p>The visibility specifications of
+
+<code>//visibility:public</code> and <code>//visibility:private</code>
+can not be combined with any other visibility specifications.
+A visibility specification may contain a combination of package labels
+(i.e. <code>//foo:__pkg__</code>) and <code>package_group</code>s.</p>
+<p>If a rule does not specify the visibility attribute,
+the <code><a href="#package">default_visibility</a></code>
+attribute of the <code><a href="#package">package</a></code>
+statement in the BUILD file containing the rule is used
+(except <a href="#exports_files">exports_files</a>
+
+).</p>
+<p>If the default visibility for the package is not specified,
+the rule is private.</p>
+<p><b>Example</b>:</p>
+<p>
+File <code>//frobber/bin/BUILD</code>:
+</p>
+<pre class="code">
+# This rule is visible to everyone
+cc_binary(
+    name = "executable",
+    visibility = ["//visibility:public"],
+    deps = [":library"],
+)
+
+# This rule is visible only to rules declared in the same package
+cc_library(
+    name = "library",
+    visibility = ["//visibility:private"],
+)
+
+# This rule is visible to rules in package //object and //noun
+cc_library(
+    name = "subject",
+    visibility = [
+        "//noun:__pkg__",
+        "//object:__pkg__",
+    ],
+)
+
+# See package group "//frobber:friends" (below) for who can access this rule.
+cc_library(
+    name = thingy,
+    visibility = ["//frobber:friends"],
+)
+</pre>
+<p>
+File <code>//frobber/BUILD</code>:
+</p>
+<pre class="code">
+# This is the package group declaration to which rule //frobber/bin:thingy refers.
+#
+# Our friends are packages //frobber, //fribber and any subpackage of //fribber.
+package_group(
+    name = "friends",
+    packages = [
+        "//fribber/...",
+        "//frobber",
+    ],
+)
+</pre>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/args.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/args.html
new file mode 100644
index 0000000..3991ac4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/args.html
@@ -0,0 +1,7 @@
+Add these arguments to the <code>--test_arg</code>
+when executed by <code>bazel test</code>.
+<i>(List of strings; optional; subject to
+<a href="#make_variables">"Make variable"</a> substitution and 
+<a href="#sh-tokenization">Bourne shell tokenization</a>)</i><br/>
+These arguments are passed before the <code>--test_arg</code> values
+specified on the <code>bazel test</code> command line.
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/flaky.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/flaky.html
new file mode 100644
index 0000000..be0eea7
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/flaky.html
@@ -0,0 +1,5 @@
+Marks test as flaky. <i>(Boolean; optional)</i><br/>
+If set, executes the test up to 3 times before being declared as failed.
+By default this attribute is set to 0 and test is considered to be stable.
+Note, that use of this attribute is generally discouraged - we do prefer
+all tests to be stable.
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/local.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/local.html
new file mode 100644
index 0000000..7c89b54
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/local.html
@@ -0,0 +1 @@
+<div></div>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/shard_count.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/shard_count.html
new file mode 100644
index 0000000..7c89b54
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/shard_count.html
@@ -0,0 +1 @@
+<div></div>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/size.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/size.html
new file mode 100644
index 0000000..5485345
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/size.html
@@ -0,0 +1,8 @@
+How "heavy" the test is
+<i>(String "enormous", "large" "medium" or "small",
+default is "medium")</i><br/>
+A classification of the test's "heaviness": how much time/resources
+it needs to run.
+Unittests are considered "small", integration tests "medium", and
+end-to-end tests "large" or "enormous". Bazel uses the size only
+to determine a default timeout.
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/timeout.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/timeout.html
new file mode 100644
index 0000000..a43e668
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/test/timeout.html
@@ -0,0 +1,9 @@
+How long the test is
+normally expected to run before returning.
+<i>(String "eternal", "long", "moderate", or "short"
+with the default derived from a test's size attribute)</i><br/>
+While a test's size attribute controls resource estimation, a test's
+timeout may be set independently.  If not explicitly specified, the
+timeout is based on the test's size (with "small" &rArr; "short",
+"medium" &rArr; "moderate", etc...). "short" means 1 minute, "moderate"
+5 minutes, and "long" 15 minutes.