Small docs updates for the extra action rule.

Add the product name to the ConfiguredRuleClassProvider so that the doc
generator can generate the proper links to the user manual.

--
MOS_MIGRATED_REVID=137505460
diff --git a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java
index 69bad6c..31133cc 100644
--- a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java
+++ b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java
@@ -160,7 +160,8 @@
    */
   public Map<String, RuleDocumentation> collect(List<String> inputDirs, String blackList)
       throws BuildEncyclopediaDocException, IOException {
-    RuleLinkExpander expander = new RuleLinkExpander(/* singlePage */ false);
+    RuleLinkExpander expander = new RuleLinkExpander(
+        ruleClassProvider.getProductName(), /* singlePage */ false);
     return collect(inputDirs, blackList, expander);
   }
 
diff --git a/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java
index 9c3a951..8ba8721 100644
--- a/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java
+++ b/src/main/java/com/google/devtools/build/docgen/MultiPageBuildEncyclopediaProcessor.java
@@ -40,7 +40,7 @@
   public void generateDocumentation(List<String> inputDirs, String outputDir, String blackList)
       throws BuildEncyclopediaDocException, IOException {
     BuildDocCollector collector = new BuildDocCollector(ruleClassProvider, false);
-    RuleLinkExpander expander = new RuleLinkExpander(false);
+    RuleLinkExpander expander = new RuleLinkExpander(ruleClassProvider.getProductName(), false);
     Map<String, RuleDocumentation> ruleDocEntries = collector.collect(
         inputDirs, blackList, expander);
     warnAboutUndocumentedRules(
diff --git a/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java
index 4f74054..e521c50 100644
--- a/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java
+++ b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java
@@ -16,6 +16,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -51,16 +52,19 @@
       .put("workspace", FUNCTIONS_PAGE)
       .build();
 
+  private final String productName;
   private final Map<String, String> ruleIndex = new HashMap<>();
   private final boolean singlePage;
 
-  RuleLinkExpander(Map<String, String> ruleIndex, boolean singlePage) {
+  RuleLinkExpander(String productName, Map<String, String> ruleIndex, boolean singlePage) {
+    this.productName = productName;
     this.ruleIndex.putAll(ruleIndex);
     this.ruleIndex.putAll(FUNCTIONS);
     this.singlePage = singlePage;
   }
 
-  RuleLinkExpander(boolean singlePage) {
+  RuleLinkExpander(String productName, boolean singlePage) {
+    this.productName = productName;
     this.ruleIndex.putAll(FUNCTIONS);
     this.singlePage = singlePage;
   }
@@ -182,6 +186,13 @@
         continue;
       }
 
+      // Links to the user manual are handled specially. Meh.
+      if ("user-manual".equals(name)) {
+        String link = productName.toLowerCase(Locale.US) + "-" + name + ".html#" + heading;
+        matcher.appendReplacement(sb, Matcher.quoteReplacement(link));
+        continue;
+      }
+
       // If the reference does not match any rule or static page, throw an exception.
       throw new IllegalArgumentException(
           "Rule family " + name + " in link tag does not match any rule or BE page: "
diff --git a/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java
index ccacd2f..56f7d29 100644
--- a/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java
+++ b/src/main/java/com/google/devtools/build/docgen/SinglePageBuildEncyclopediaProcessor.java
@@ -40,7 +40,7 @@
   public void generateDocumentation(List<String> inputDirs, String outputDir, String blackList)
       throws BuildEncyclopediaDocException, IOException {
     BuildDocCollector collector = new BuildDocCollector(ruleClassProvider, false);
-    RuleLinkExpander expander = new RuleLinkExpander(true);
+    RuleLinkExpander expander = new RuleLinkExpander(ruleClassProvider.getProductName(), true);
     Map<String, RuleDocumentation> ruleDocEntries = collector.collect(
         inputDirs, blackList, expander);
     warnAboutUndocumentedRules(
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index 076c5a8..56c815f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -193,6 +193,7 @@
 
   /** Builder for {@link ConfiguredRuleClassProvider}. */
   public static class Builder implements RuleDefinitionEnvironment {
+    private String productName;
     private final StringBuilder defaultWorkspaceFilePrefix = new StringBuilder();
     private final StringBuilder defaultWorkspaceFileSuffix = new StringBuilder();
     private Label preludeLabel;
@@ -221,6 +222,11 @@
         registeredSkylarkProviders = ImmutableBiMap.builder();
     private Map<String, String> platformRegexps = new TreeMap<>();
 
+    public Builder setProductName(String productName) {
+      this.productName = productName;
+      return this;
+    }
+
     public void addWorkspaceFilePrefix(String contents) {
       defaultWorkspaceFilePrefix.append(contents);
     }
@@ -418,6 +424,7 @@
       }
 
       return new ConfiguredRuleClassProvider(
+          productName,
           preludeLabel,
           runfilesPrefix,
           toolsRepository,
@@ -474,6 +481,8 @@
     }
   });
 
+  private final String productName;
+
   /**
    * Default content that should be added at the beginning of the WORKSPACE file.
    */
@@ -544,6 +553,7 @@
       registeredSkylarkProviders;
 
   private ConfiguredRuleClassProvider(
+      String productName,
       Label preludeLabel,
       String runfilesPrefix,
       String toolsRepository,
@@ -561,6 +571,7 @@
       ImmutableMap<String, Object> skylarkAccessibleJavaClasses,
       ImmutableList<Class<?>> skylarkModules,
       ImmutableBiMap<String, Class<? extends TransitiveInfoProvider>> registeredSkylarkProviders) {
+    this.productName = productName;
     this.preludeLabel = preludeLabel;
     this.runfilesPrefix = runfilesPrefix;
     this.toolsRepository = toolsRepository;
@@ -579,6 +590,10 @@
     this.registeredSkylarkProviders = registeredSkylarkProviders;
   }
 
+  public String getProductName() {
+    return productName;
+  }
+
   public PrerequisiteValidator getPrerequisiteValidator() {
     return prerequisiteValidator;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index fafaf57..f1eb576 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -276,6 +276,7 @@
         @Override
         public void init(Builder builder) {
           builder
+              .setProductName("bazel")
               .setConfigurationCollectionFactory(new BazelConfigurationCollection())
               .setPrelude("//tools/build_rules:prelude_bazel")
               .setRunfilesPrefix(Label.DEFAULT_REPOSITORY_DIRECTORY)
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/common/BazelExtraActionRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/common/BazelExtraActionRule.java
index 6849f6d..3db02af 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/common/BazelExtraActionRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/common/BazelExtraActionRule.java
@@ -47,7 +47,7 @@
         <p>
           The build system ensures these prerequisites are built before running the
           <code>extra_action</code> command; they are built using the
-          <a href='../bazel-user-manual.html#configurations'><code>host</code>configuration</a>,
+          <a href='${link user-manual#configurations}'><code>host</code>configuration</a>,
           since they must run as a tool during the build itself. The path of an individual
           <code>tools</code> target <code>//x:y</code> can be obtained using
           <code>$(location //x:y)</code>.
@@ -137,7 +137,7 @@
 
 <p>
   See <a href="${link action_listener}"><code>action_listener</code></a> for details
-  on how to enable <code>extra_action</code>s in Bazel.
+  on how to enable <code>extra_action</code>s.
 </p>
 
 <p>
@@ -145,6 +145,13 @@
   access to a file containing a protocol buffer as $(EXTRA_ACTION_FILE)
   with detailed information on the original action it is shadowing.
   It also has access to all the input files the original action has access to.
+  See <tt>extra_actions.proto</tt>
+  for details on the data stored inside the protocol buffer. Each proto file
+  contains an ExtraActionInfo message.
+</p>
+
+<p>
+  Just like all other actions, extra actions are sandboxed, and should be designed to handle that.
 </p>
 
 <!-- #END_BLAZE_RULE -->*/
diff --git a/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java b/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java
index fbacd0c..cea22da 100644
--- a/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java
@@ -36,8 +36,8 @@
         .put("Fileset", "fileset")
         .put("proto_library", "protocol-buffer")
         .build();
-    multiPageExpander = new RuleLinkExpander(index, false);
-    singlePageExpander = new RuleLinkExpander(index, true);
+    multiPageExpander = new RuleLinkExpander("product-name", index, false);
+    singlePageExpander = new RuleLinkExpander("product-name", index, true);
   }
 
   private void checkExpandSingle(String docs, String expected) {
@@ -111,6 +111,15 @@
         "<a href=\"#common-definitions\">Common Definitions</a>");
   }
 
+  @Test public void testUserManualRefIncludesProductName() {
+    checkExpandMulti(
+        "<a href=\"${link user-manual#overview}\">Link</a>",
+        "<a href=\"product-name-user-manual.html#overview\">Link</a>");
+    checkExpandSingle(
+        "<a href=\"${link user-manual#overview}\">Link</a>",
+        "<a href=\"product-name-user-manual.html#overview\">Link</a>");
+  }
+
   @Test(expected = IllegalArgumentException.class)
   public void testRefNotFound() {
     String docs = "<a href=\"${link foo.bar}\">bar</a>";