Skip to content

Commit

Permalink
Supplement rule doc from BuildDocCollector
Browse files Browse the repository at this point in the history
  • Loading branch information
hauserx committed Jan 13, 2025
1 parent 60a6dab commit 44df2e1
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 4 deletions.
24 changes: 23 additions & 1 deletion src/main/java/com/google/devtools/build/docgen/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ java_library(
srcs = glob(["**/*.java"]),
resources = [":template_files"],
runtime_deps = [
"//src/main/java/com/google/devtools/build/lib/bazel:main",
# TODO: Commented out for now to avoid cyclic deps for rule_src_doc_exporter.
# "//src/main/java/com/google/devtools/build/lib/bazel:main",
],
deps = [
"//src/main/java/com/google/devtools/build/docgen/annot",
Expand All @@ -72,6 +73,7 @@ java_library(
"//src/main/java/net/starlark/java/annot",
"//src/main/java/net/starlark/java/eval",
"//src/main/protobuf:builtin_java_proto",
"//src/main/protobuf:rule_src_doc_java_proto",
"//src/main/protobuf:stardoc_output_java_proto",
"//third_party:apache_velocity",
"//third_party:auto_value",
Expand Down Expand Up @@ -123,6 +125,26 @@ java_binary(
],
)

java_binary(
name = "rule_src_doc_exporter",
srcs = ["RuleSrcDocExporter.java"],
main_class = "com.google.devtools.build.docgen.RuleSrcDocExporter",
runtime_deps = [
"//src/main/java/com/google/devtools/build/lib/bazel/repository",
"//src/main/java/com/google/devtools/build/lib/bazel/rules",
"//src/main/java/net/starlark/java/syntax",
],
deps = [
":docgen_javalib",
"//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
"//src/main/java/com/google/devtools/common/options",
"//src/main/java/net/starlark/java/annot",
"//src/main/java/net/starlark/java/eval",
"//src/main/protobuf:rule_src_doc_java_proto",
"//third_party:guava",
],
)

filegroup(
name = "template_files",
srcs = glob([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ public boolean isMandatory() {
return mandatory;
}

/** Returns string representation of default value, if any. */
public @Nullable String getDefaultValue() {
return this.defaultValue;
}

/** Returns a string containing the synopsis for this attribute. */
public String getSynopsis() throws BuildEncyclopediaDocException {
if (type == null) {
Expand Down
135 changes: 135 additions & 0 deletions src/main/java/com/google/devtools/build/docgen/RuleSrcDocExporter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2025 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.docgen;

import com.google.devtools.build.docgen.starlark.*;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.build.docgen.rulesrcdoc.RuleSrcDoc.RuleSrcDocs;
import com.google.devtools.build.docgen.rulesrcdoc.RuleSrcDoc.RuleDocumentationProto;
import com.google.devtools.build.docgen.rulesrcdoc.RuleSrcDoc.RuleDocumentationAttributeProto;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/** The main class for exporting rule docs collected from source files. */
public class RuleSrcDocExporter {

private static void printUsage(OptionsParser parser) {
// System.err.println(
// "Usage: api_exporter_bin -m link_map_path -p rule_class_provider\n"
// + " [-r input_root] (-i input_dir)+ (--input_stardoc_proto binproto)+\n"
// + " -f outputFile [-b denylist] [-h]\n\n"
// + "Exports all Starlark builtins to a file including the embedded native rules.\n"
// + "The link map path (-m), rule class provider (-p), output file (-f), and at least\n"
// + " one input_dir (-i) or binproto (--input_stardoc_proto) must be specified.\n");
// System.err.println(
// parser.describeOptionsWithDeprecatedCategories(
// Collections.<String, String>emptyMap(), OptionsParser.HelpVerbosity.LONG));
}

private static void fail(Throwable e, boolean printStackTrace) {
System.err.println("ERROR: " + e.getMessage());
if (printStackTrace) {
e.printStackTrace();
}
Runtime.getRuntime().exit(1);
}

private static ConfiguredRuleClassProvider createRuleClassProvider(String classProvider)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
ClassNotFoundException {
Class<?> providerClass = Class.forName(classProvider);
Method createMethod = providerClass.getMethod("create");
return (ConfiguredRuleClassProvider) createMethod.invoke(null);
}

private static RuleSrcDocs ruleDocsToProto(Collection<RuleDocumentation> ruleDocs) throws BuildEncyclopediaDocException {
RuleSrcDocs.Builder builder = RuleSrcDocs.newBuilder();

for (RuleDocumentation ruleDoc : ruleDocs.stream().sorted().toList()) {
RuleDocumentationProto.Builder ruleProto = builder.addRuleBuilder();
ruleProto.setRuleName(ruleDoc.getRuleName());
ruleProto.setHtmlDocumentation(ruleDoc.getHtmlDocumentation());

for (RuleDocumentationAttribute ruleAttr : ruleDoc.getAttributes()) {
RuleDocumentationAttributeProto.Builder attrProto = ruleProto.addAttributeBuilder();
attrProto.setAttributeName(ruleAttr.getAttributeName());
attrProto.setHtmlDocumentation(ruleAttr.getHtmlDocumentation());
String defaultValue = ruleAttr.getDefaultValue();
if (defaultValue != null) {
attrProto.setDefaultValue(defaultValue);
}
attrProto.setIsMandatory(ruleAttr.isMandatory());
attrProto.setIsDeprecated(ruleAttr.isDeprecated());
}
}
return builder.build();
}


private static void writeSrcDocs(String filename, RuleSrcDocs ruleSrcDocs) throws IOException {
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename))) {
ruleSrcDocs.writeTo(out);
}
}

public static void main(String[] args) {
OptionsParser parser =
OptionsParser.builder()
.optionsClasses(BuildEncyclopediaOptions.class)
.allowResidue(false)
.build();
parser.parseAndExitUponError(args);
BuildEncyclopediaOptions options = parser.getOptions(BuildEncyclopediaOptions.class);

if (options.help) {
printUsage(parser);
Runtime.getRuntime().exit(0);
}

if (options.linkMapPath.isEmpty()
|| (options.inputJavaDirs.isEmpty() && options.inputStardocProtos.isEmpty())
|| options.provider.isEmpty()) {
printUsage(parser);
Runtime.getRuntime().exit(1);
}

try {
DocLinkMap linkMap = DocLinkMap.createFromFile(options.linkMapPath);
RuleLinkExpander linkExpander = new RuleLinkExpander(
/* singlePage */ false, linkMap);
SourceUrlMapper urlMapper = new SourceUrlMapper(linkMap, options.inputRoot);
// TODO: Describe why RuleClassProvider is needed even when getting docs from source files.
ConfiguredRuleClassProvider ruleClassProvider = createRuleClassProvider(options.provider);

BuildDocCollector collector = new BuildDocCollector(linkExpander, urlMapper, ruleClassProvider);
Map<String, RuleDocumentation> ruleDocEntries =
collector.collect(options.inputJavaDirs, options.inputStardocProtos, options.denylist);

RuleSrcDocs rulesProto = ruleDocsToProto(ruleDocEntries.values());
writeSrcDocs(options.outputFile, rulesProto);

} catch (BuildEncyclopediaDocException e) {
fail(e, false);
} catch (Throwable e) {
fail(e, true);
}
}

}
32 changes: 32 additions & 0 deletions src/main/java/com/google/devtools/build/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -714,3 +714,35 @@ genrule(
"//src/main/java/com/google/devtools/build/docgen:api_exporter",
],
)

genrule(
name = "gen_rule_src_doc_proto",
srcs = [
"//src/main/java/com/google/devtools/build/docgen:bazel_link_map",
"//src/main/starlark/docgen:gen_be_proto_stardoc_proto", # TODO: Neeeded?
"//src/main/starlark/docgen:gen_be_java_stardoc_proto",
"//src/main/starlark/docgen:gen_be_cpp_stardoc_proto",
"//src/main/starlark/docgen:gen_be_objc_stardoc_proto",
"//src/main/starlark/docgen:gen_be_python_stardoc_proto",
"//src/main/starlark/docgen:gen_be_shell_stardoc_proto",
":docs_embedded_in_sources",
],
outs = ["rule_src_doc.pb"],
cmd = (
"$(location //src/main/java/com/google/devtools/build/docgen:rule_src_doc_exporter)" +
" --output_file=$@" +
" --link_map_path=$(location //src/main/java/com/google/devtools/build/docgen:bazel_link_map) " +
" --provider=com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider" +
" --input_root=$$PWD" +
" --input_dir=$$PWD/src/main/java/com/google/devtools/build/lib" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_proto_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_java_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_cpp_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_objc_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_python_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_shell_stardoc_proto)"
),
tools = [
"//src/main/java/com/google/devtools/build/docgen:rule_src_doc_exporter",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ filegroup(
java_library(
name = "info",
srcs = glob(["*.java"]),
resources = [
":gen_rule_src_doc_proto",
],
deps = [
"//src/main/java/com/google/devtools/build/docgen:visible_to_info",
"//src/main/java/com/google/devtools/build/lib:runtime",
Expand Down Expand Up @@ -49,7 +52,40 @@ java_library(
"//src/main/protobuf:build_java_proto",
"//src/main/protobuf:builtin_java_proto",
"//src/main/protobuf:failure_details_java_proto",
"//src/main/protobuf:rule_src_doc_java_proto",
"//third_party:flogger",
"//third_party:guava",
],
)

genrule(
name = "gen_rule_src_doc_proto",
srcs = [
"//src/main/java/com/google/devtools/build/docgen:bazel_link_map",
"//src/main/starlark/docgen:gen_be_proto_stardoc_proto",
"//src/main/starlark/docgen:gen_be_java_stardoc_proto",
"//src/main/starlark/docgen:gen_be_cpp_stardoc_proto",
"//src/main/starlark/docgen:gen_be_objc_stardoc_proto",
"//src/main/starlark/docgen:gen_be_python_stardoc_proto",
"//src/main/starlark/docgen:gen_be_shell_stardoc_proto",
"//src/main/java/com/google/devtools/build/lib:docs_embedded_in_sources",
],
outs = ["rule_src_doc.pb"],
cmd = (
"$(location //src/main/java/com/google/devtools/build/docgen:rule_src_doc_exporter)" +
" --output_file=$@" +
" --link_map_path=$(location //src/main/java/com/google/devtools/build/docgen:bazel_link_map) " +
" --provider=com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider" +
" --input_root=$$PWD" +
" --input_dir=$$PWD/src/main/java/com/google/devtools/build/lib" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_proto_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_java_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_cpp_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_objc_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_python_stardoc_proto)" +
" --input_stardoc_proto=$(location //src/main/starlark/docgen:gen_be_shell_stardoc_proto)"
),
tools = [
"//src/main/java/com/google/devtools/build/docgen:rule_src_doc_exporter",
],
)
Loading

0 comments on commit 44df2e1

Please sign in to comment.