Skip to content

Commit

Permalink
Sort documentable entities (including rule attributes) in markdown ou…
Browse files Browse the repository at this point in the history
…tput

starlark_doc_extract, unlike the legacy documentation extractor, produces a
proto with documentable entities in the same order as encountered in the
source. Thus, to be compatible with both the legacy and the new extractor,
the markdown renderer needs to sort rules/providers/functions/aspects, and
the fields in a given rule, before emitting output.

Since we are messing with the sort order, take the opportunity to sort rule
attributes in the same order as in the documentation for native rules in
Bazel docs. (Legacy Stardoc behavior was to sort everything except "name"
in simple alphabetical order. This means some golden tests will need to be
updated.)

PiperOrigin-RevId: 546966417
Change-Id: I69484168b1584aca662fd285652b3fbb3c1fef09
  • Loading branch information
tetromino authored and copybara-github committed Jul 10, 2023
1 parent 1b58cae commit 0877738
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ java_library(
"//src/main/java/com/google/devtools/build/skydoc/rendering",
"//src/main/java/com/google/devtools/build/skydoc/rendering/proto:stardoc_output_java_proto",
"//src/main/java/com/google/devtools/common/options",
"//third_party:guava",
"//third_party/protobuf:protobuf_java",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@

package com.google.devtools.build.skydoc.renderer;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.comparing;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.skydoc.rendering.MarkdownRenderer;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ModuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
Expand All @@ -28,6 +33,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.List;

/**
Expand Down Expand Up @@ -93,10 +99,56 @@ public void println() {
}
}

// A copy of com.google.devtools.build.docgen.DocgenConsts.ATTRIBUTE_ORDERING - we duplicate the
// ordering here because we intend to move this file from the Bazel tree to the Stardoc repo.
private static final ImmutableMap<String, Integer> ATTRIBUTE_ORDERING =
ImmutableMap.<String, Integer>builder()
.put("name", -99)
.put("deps", -98)
.put("src", -97)
.put("srcs", -96)
.put("data", -95)
.put("resource", -94)
.put("resources", -93)
.put("out", -92)
.put("outs", -91)
.put("hdrs", -90)
.buildOrThrow();

private static final Comparator<String> ATTRIBUTE_NAME_COMPARATOR =
(a, b) -> {
int aOrdering = ATTRIBUTE_ORDERING.getOrDefault(a, 0);
int bOrdering = ATTRIBUTE_ORDERING.getOrDefault(b, 0);
if (aOrdering > bOrdering) {
return 1;
} else if (aOrdering < bOrdering) {
return -1;
} else {
return Comparator.<String>naturalOrder().compare(a, b);
}
};

private static RuleInfo withSortedRuleAttributes(RuleInfo ruleInfo) {
return ruleInfo.toBuilder()
.clearAttribute()
.addAllAttribute(
ImmutableList.sortedCopyOf(
comparing(AttributeInfo::getName, ATTRIBUTE_NAME_COMPARATOR),
ruleInfo.getAttributeList()))
.build();
}

private static void printRuleInfos(
PrintWriter printWriter, MarkdownRenderer renderer, List<RuleInfo> ruleInfos)
throws IOException {
for (RuleInfo ruleProto : ruleInfos) {
// rules are printed sorted by their qualified name, and their attributes are sorted by name,
// with ATTRIBUTE_ORDERING specifying a fixed sort order for some standard attributes.
ImmutableList<RuleInfo> sortedRuleInfos =
ruleInfos.stream()
.map(RendererMain::withSortedRuleAttributes)
.sorted(comparing(RuleInfo::getRuleName))
.collect(toImmutableList());
for (RuleInfo ruleProto : sortedRuleInfos) {
printWriter.println(renderer.render(ruleProto.getRuleName(), ruleProto));
printWriter.println();
}
Expand All @@ -105,7 +157,10 @@ private static void printRuleInfos(
private static void printProviderInfos(
PrintWriter printWriter, MarkdownRenderer renderer, List<ProviderInfo> providerInfos)
throws IOException {
for (ProviderInfo providerProto : providerInfos) {
// providers are printed sorted by their qualified name.
ImmutableList<ProviderInfo> sortedProviderInfos =
ImmutableList.sortedCopyOf(comparing(ProviderInfo::getProviderName), providerInfos);
for (ProviderInfo providerProto : sortedProviderInfos) {
printWriter.println(renderer.render(providerProto.getProviderName(), providerProto));
printWriter.println();
}
Expand All @@ -114,9 +169,13 @@ private static void printProviderInfos(
private static void printStarlarkFunctions(
PrintWriter printWriter,
MarkdownRenderer renderer,
List<StarlarkFunctionInfo> userDefinedFunctions)
List<StarlarkFunctionInfo> starlarkFunctions)
throws IOException {
for (StarlarkFunctionInfo funcProto : userDefinedFunctions) {
// functions are printed sorted by their qualified name.
ImmutableList<StarlarkFunctionInfo> sortedStarlarkFunctions =
ImmutableList.sortedCopyOf(
comparing(StarlarkFunctionInfo::getFunctionName), starlarkFunctions);
for (StarlarkFunctionInfo funcProto : sortedStarlarkFunctions) {
printWriter.println(renderer.render(funcProto));
printWriter.println();
}
Expand All @@ -125,7 +184,10 @@ private static void printStarlarkFunctions(
private static void printAspectInfos(
PrintWriter printWriter, MarkdownRenderer renderer, List<AspectInfo> aspectInfos)
throws IOException {
for (AspectInfo aspectProto : aspectInfos) {
// aspects are printed sorted by their qualified name.
ImmutableList<AspectInfo> sortedAspectInfos =
ImmutableList.sortedCopyOf(comparing(AspectInfo::getAspectName), aspectInfos);
for (AspectInfo aspectProto : sortedAspectInfos) {
printWriter.println(renderer.render(aspectProto.getAspectName(), aspectProto));
printWriter.println();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
## antlr

<pre>
antlr(<a href="#antlr-name">name</a>, <a href="#antlr-Xconversiontimeout">Xconversiontimeout</a>, <a href="#antlr-Xdbgconversion">Xdbgconversion</a>, <a href="#antlr-Xdbgst">Xdbgst</a>, <a href="#antlr-Xdfa">Xdfa</a>, <a href="#antlr-Xdfaverbose">Xdfaverbose</a>, <a href="#antlr-Xgrtree">Xgrtree</a>, <a href="#antlr-Xm">Xm</a>,
antlr(<a href="#antlr-name">name</a>, <a href="#antlr-deps">deps</a>, <a href="#antlr-srcs">srcs</a>, <a href="#antlr-Xconversiontimeout">Xconversiontimeout</a>, <a href="#antlr-Xdbgconversion">Xdbgconversion</a>, <a href="#antlr-Xdbgst">Xdbgst</a>, <a href="#antlr-Xdfa">Xdfa</a>, <a href="#antlr-Xdfaverbose">Xdfaverbose</a>, <a href="#antlr-Xgrtree">Xgrtree</a>, <a href="#antlr-Xm">Xm</a>,
<a href="#antlr-Xmaxdfaedges">Xmaxdfaedges</a>, <a href="#antlr-Xmaxinlinedfastates">Xmaxinlinedfastates</a>, <a href="#antlr-Xminswitchalts">Xminswitchalts</a>, <a href="#antlr-Xmultithreaded">Xmultithreaded</a>, <a href="#antlr-Xnfastates">Xnfastates</a>, <a href="#antlr-Xnocollapse">Xnocollapse</a>,
<a href="#antlr-Xnomergestopstates">Xnomergestopstates</a>, <a href="#antlr-Xnoprune">Xnoprune</a>, <a href="#antlr-XsaveLexer">XsaveLexer</a>, <a href="#antlr-Xwatchconversion">Xwatchconversion</a>, <a href="#antlr-debug">debug</a>, <a href="#antlr-depend">depend</a>, <a href="#antlr-deps">deps</a>, <a href="#antlr-dfa">dfa</a>, <a href="#antlr-dump">dump</a>,
<a href="#antlr-imports">imports</a>, <a href="#antlr-language">language</a>, <a href="#antlr-message_format">message_format</a>, <a href="#antlr-nfa">nfa</a>, <a href="#antlr-package">package</a>, <a href="#antlr-profile">profile</a>, <a href="#antlr-report">report</a>, <a href="#antlr-srcs">srcs</a>, <a href="#antlr-trace">trace</a>)
<a href="#antlr-Xnomergestopstates">Xnomergestopstates</a>, <a href="#antlr-Xnoprune">Xnoprune</a>, <a href="#antlr-XsaveLexer">XsaveLexer</a>, <a href="#antlr-Xwatchconversion">Xwatchconversion</a>, <a href="#antlr-debug">debug</a>, <a href="#antlr-depend">depend</a>, <a href="#antlr-dfa">dfa</a>, <a href="#antlr-dump">dump</a>, <a href="#antlr-imports">imports</a>,
<a href="#antlr-language">language</a>, <a href="#antlr-message_format">message_format</a>, <a href="#antlr-nfa">nfa</a>, <a href="#antlr-package">package</a>, <a href="#antlr-profile">profile</a>, <a href="#antlr-report">report</a>, <a href="#antlr-trace">trace</a>)
</pre>

Runs [ANTLR 3](https://www.antlr3.org//) on a set of grammars.
Expand All @@ -30,6 +30,26 @@ Runs [ANTLR 3](https://www.antlr3.org//) on a set of grammars.
</p>
</td>
</tr>
<tr id="antlr-deps">
<td><code>deps</code></td>
<td>
<a href="https://bazel.build/concepts/labels">List of labels</a>; optional
<p>
The dependencies to use. Defaults to the most recent ANTLR 3 release,
but if you need to use a different version, you can specify the
dependencies here.
</p>
</td>
</tr>
<tr id="antlr-srcs">
<td><code>srcs</code></td>
<td>
<a href="https://bazel.build/concepts/labels">List of labels</a>; required
<p>
The grammar files to process.
</p>
</td>
</tr>
<tr id="antlr-Xconversiontimeout">
<td><code>Xconversiontimeout</code></td>
<td>
Expand Down Expand Up @@ -201,17 +221,6 @@ Runs [ANTLR 3](https://www.antlr3.org//) on a set of grammars.
</p>
</td>
</tr>
<tr id="antlr-deps">
<td><code>deps</code></td>
<td>
<a href="https://bazel.build/concepts/labels">List of labels</a>; optional
<p>
The dependencies to use. Defaults to the most recent ANTLR 3 release,
but if you need to use a different version, you can specify the
dependencies here.
</p>
</td>
</tr>
<tr id="antlr-dfa">
<td><code>dfa</code></td>
<td>
Expand Down Expand Up @@ -293,15 +302,6 @@ dependencies here.
</p>
</td>
</tr>
<tr id="antlr-srcs">
<td><code>srcs</code></td>
<td>
<a href="https://bazel.build/concepts/labels">List of labels</a>; required
<p>
The grammar files to process.
</p>
</td>
</tr>
<tr id="antlr-trace">
<td><code>trace</code></td>
<td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## my_rule

<pre>
my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-deps">deps</a>, <a href="#my_rule-extra_arguments">extra_arguments</a>, <a href="#my_rule-out">out</a>, <a href="#my_rule-src">src</a>, <a href="#my_rule-tool">tool</a>)
my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-deps">deps</a>, <a href="#my_rule-src">src</a>, <a href="#my_rule-out">out</a>, <a href="#my_rule-extra_arguments">extra_arguments</a>, <a href="#my_rule-tool">tool</a>)
</pre>

This rule exercises some of the build API.
Expand Down Expand Up @@ -39,10 +39,13 @@ This rule exercises some of the build API.
</p>
</td>
</tr>
<tr id="my_rule-extra_arguments">
<td><code>extra_arguments</code></td>
<tr id="my_rule-src">
<td><code>src</code></td>
<td>
List of strings; optional
<a href="https://bazel.build/concepts/labels">Label</a>; optional
<p>
The source file.
</p>
</td>
</tr>
<tr id="my_rule-out">
Expand All @@ -54,13 +57,10 @@ This rule exercises some of the build API.
</p>
</td>
</tr>
<tr id="my_rule-src">
<td><code>src</code></td>
<tr id="my_rule-extra_arguments">
<td><code>extra_arguments</code></td>
<td>
<a href="https://bazel.build/concepts/labels">Label</a>; optional
<p>
The source file.
</p>
List of strings; optional
</td>
</tr>
<tr id="my_rule-tool">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->

<a name="#my_namespace.min"></a>
<a name="#my_namespace.foo.bar.baz"></a>

## my_namespace.min
## my_namespace.foo.bar.baz

<pre>
my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
my_namespace.foo.bar.baz()
</pre>

This function does nothing.



<a name="#my_namespace.math.min"></a>

## my_namespace.math.min

<pre>
my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
</pre>

Returns the minimum of given elements.
Expand All @@ -22,7 +34,7 @@ The minimum integer in the given list.
<col class="col-description" />
</colgroup>
<tbody>
<tr id="my_namespace.min-integers">
<tr id="my_namespace.math.min-integers">
<td><code>integers</code></td>
<td>
required.
Expand All @@ -35,12 +47,12 @@ The minimum integer in the given list.
</table>


<a name="#my_namespace.math.min"></a>
<a name="#my_namespace.min"></a>

## my_namespace.math.min
## my_namespace.min

<pre>
my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
</pre>

Returns the minimum of given elements.
Expand All @@ -57,7 +69,7 @@ The minimum integer in the given list.
<col class="col-description" />
</colgroup>
<tbody>
<tr id="my_namespace.math.min-integers">
<tr id="my_namespace.min-integers">
<td><code>integers</code></td>
<td>
required.
Expand All @@ -70,12 +82,12 @@ The minimum integer in the given list.
</table>


<a name="#my_namespace.foo.bar.baz"></a>
<a name="#my_namespace.one.three.does_nothing"></a>

## my_namespace.foo.bar.baz
## my_namespace.one.three.does_nothing

<pre>
my_namespace.foo.bar.baz()
my_namespace.one.three.does_nothing()
</pre>

This function does nothing.
Expand Down Expand Up @@ -117,15 +129,3 @@ The minimum integer in the given list.
</table>


<a name="#my_namespace.one.three.does_nothing"></a>

## my_namespace.one.three.does_nothing

<pre>
my_namespace.one.three.does_nothing()
</pre>

This function does nothing.



Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->

<a name="#my_namespace.min"></a>
<a name="#my_namespace.math.min"></a>

## my_namespace.min
## my_namespace.math.min

<pre>
my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
</pre>

Returns the minimum of given elements.
Expand All @@ -18,7 +18,7 @@ Returns the minimum of given elements.
<col class="col-description" />
</colgroup>
<tbody>
<tr id="my_namespace.min-integers">
<tr id="my_namespace.math.min-integers">
<td><code>integers</code></td>
<td>
required.
Expand All @@ -28,12 +28,12 @@ Returns the minimum of given elements.
</table>


<a name="#my_namespace.math.min"></a>
<a name="#my_namespace.min"></a>

## my_namespace.math.min
## my_namespace.min

<pre>
my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
</pre>

Returns the minimum of given elements.
Expand All @@ -46,7 +46,7 @@ Returns the minimum of given elements.
<col class="col-description" />
</colgroup>
<tbody>
<tr id="my_namespace.math.min-integers">
<tr id="my_namespace.min-integers">
<td><code>integers</code></td>
<td>
required.
Expand Down
Loading

0 comments on commit 0877738

Please sign in to comment.