Fix linter errors and switch from Apache Velocity to Google Escapevelocity for templating (#163)
Internal tooling complains about any new Velocity usage
diff --git a/WORKSPACE b/WORKSPACE
index f2a36f7..3ac9188 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -31,9 +31,9 @@
maven_install(
artifacts = [
"com.beust:jcommander:1.82",
+ "com.google.escapevelocity:escapevelocity:1.1",
"com.google.guava:guava:31.1-jre",
"com.google.truth:truth:1.1.3",
- "org.apache.velocity:velocity:1.7",
"junit:junit:4.13.2",
# Artifacts below this line are only needed for building @io_bazel for
# stardoc_binary.jar integration tests. They should be removed once we
@@ -61,6 +61,7 @@
"commons-collections:commons-collections:3.2.2",
"commons-lang:commons-lang:2.6",
"org.apache.tomcat:tomcat-annotations-api:8.0.5",
+ "org.apache.velocity:velocity:1.7",
"org.checkerframework:checker-qual:3.19.0",
],
fail_if_repin_required = True,
diff --git a/maven_install.json b/maven_install.json
index 0ed8554..015c173 100644
--- a/maven_install.json
+++ b/maven_install.json
@@ -1,8 +1,8 @@
{
"dependency_tree": {
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
- "__INPUT_ARTIFACTS_HASH": -568257785,
- "__RESOLVED_ARTIFACTS_HASH": -1924638958,
+ "__INPUT_ARTIFACTS_HASH": -2046468587,
+ "__RESOLVED_ARTIFACTS_HASH": 1700352167,
"conflict_resolution": {},
"dependencies": [
{
@@ -238,6 +238,30 @@
"url": "https://repo1.maven.org/maven2/com/google/errorprone/error_prone_type_annotations/2.18.0/error_prone_type_annotations-2.18.0.jar"
},
{
+ "coord": "com.google.escapevelocity:escapevelocity:1.1",
+ "dependencies": [
+ "com.google.code.findbugs:jsr305:3.0.2",
+ "com.google.errorprone:error_prone_annotations:2.18.0",
+ "com.google.guava:failureaccess:1.0.1",
+ "com.google.guava:guava:31.1-jre",
+ "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava",
+ "com.google.j2objc:j2objc-annotations:1.3",
+ "org.checkerframework:checker-qual:3.19.0"
+ ],
+ "directDependencies": [
+ "com.google.guava:guava:31.1-jre"
+ ],
+ "file": "v1/https/repo1.maven.org/maven2/com/google/escapevelocity/escapevelocity/1.1/escapevelocity-1.1.jar",
+ "mirror_urls": [
+ "https://repo1.maven.org/maven2/com/google/escapevelocity/escapevelocity/1.1/escapevelocity-1.1.jar"
+ ],
+ "packages": [
+ "com.google.escapevelocity"
+ ],
+ "sha256": "37e76e4466836dedb864fb82355cd01c3bd21325ab642d89a0f759291b171231",
+ "url": "https://repo1.maven.org/maven2/com/google/escapevelocity/escapevelocity/1.1/escapevelocity-1.1.jar"
+ },
+ {
"coord": "com.google.flogger:flogger-system-backend:0.5.1",
"dependencies": [
"com.google.flogger:flogger:0.5.1",
diff --git a/src/main/java/com/google/devtools/build/skydoc/renderer/RendererMain.java b/src/main/java/com/google/devtools/build/skydoc/renderer/RendererMain.java
index 55cdd84..29ceb92 100644
--- a/src/main/java/com/google/devtools/build/skydoc/renderer/RendererMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/renderer/RendererMain.java
@@ -28,6 +28,7 @@
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.StarlarkFunctionInfo;
+import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.FileInputStream;
import java.io.IOException;
@@ -40,13 +41,12 @@
*
* <p>This Renderer takes in raw stardoc_proto protos as input and produces rich markdown output.
*/
-public class RendererMain {
+public final class RendererMain {
public static void main(String[] args) throws IOException {
RendererOptions rendererOptions = new RendererOptions();
- JCommander jcommander =
- JCommander.newBuilder().addObject(rendererOptions).build();
+ JCommander jcommander = JCommander.newBuilder().addObject(rendererOptions).build();
jcommander.setProgramName("renderer");
jcommander.parse(args);
if (rendererOptions.printHelp) {
@@ -77,7 +77,9 @@
write("\n");
}
}) {
- ModuleInfo moduleInfo = ModuleInfo.parseFrom(new FileInputStream(inputPath));
+ ModuleInfo moduleInfo =
+ ModuleInfo.parseFrom(
+ new FileInputStream(inputPath), ExtensionRegistry.getEmptyRegistry());
printWriter.println(renderer.renderMarkdownHeader(moduleInfo));
printRuleInfos(printWriter, renderer, moduleInfo.getRuleInfoList());
printProviderInfos(printWriter, renderer, moduleInfo.getProviderInfoList());
@@ -181,4 +183,6 @@
printWriter.println();
}
}
+
+ private RendererMain() {}
}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD b/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
index 92c9021..0153417 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/BUILD
@@ -21,7 +21,7 @@
),
deps = [
"//stardoc/proto:stardoc_output_java_proto",
+ "@maven//:com_google_escapevelocity_escapevelocity",
"@maven//:com_google_guava_guava",
- "@maven//:org_apache_velocity_velocity",
],
)
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
index 3a2085c..7f6abeb 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
@@ -16,27 +16,23 @@
import static java.nio.charset.StandardCharsets.UTF_8;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
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;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.StarlarkFunctionInfo;
+import com.google.escapevelocity.EvaluationException;
+import com.google.escapevelocity.ParseException;
+import com.google.escapevelocity.Template;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.VelocityEngine;
-import org.apache.velocity.exception.MethodInvocationException;
-import org.apache.velocity.exception.ParseErrorException;
-import org.apache.velocity.exception.ResourceNotFoundException;
-import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
-import org.apache.velocity.runtime.resource.loader.JarResourceLoader;
/** Produces skydoc output in markdown form. */
public class MarkdownRenderer {
@@ -47,8 +43,6 @@
private final String functionTemplateFilename;
private final String aspectTemplateFilename;
- private final VelocityEngine velocityEngine;
-
public MarkdownRenderer(
String headerTemplate,
String ruleTemplate,
@@ -60,18 +54,6 @@
this.providerTemplateFilename = providerTemplate;
this.functionTemplateFilename = functionTemplate;
this.aspectTemplateFilename = aspectTemplate;
-
- this.velocityEngine = new VelocityEngine();
- velocityEngine.setProperty("resource.loader", "classpath, jar");
- velocityEngine.setProperty(
- "classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
- velocityEngine.setProperty("jar.resource.loader.class", JarResourceLoader.class.getName());
- velocityEngine.setProperty("input.encoding", "UTF-8");
- velocityEngine.setProperty("output.encoding", "UTF-8");
- velocityEngine.setProperty("runtime.references.strict", true);
-
- // Ensure formatting is the same on Velocity 1.7 and 2.x.
- velocityEngine.setProperty("parser.space_gobbling", "bc");
}
/**
@@ -79,18 +61,15 @@
* summary for the input Starlark module.
*/
public String renderMarkdownHeader(ModuleInfo moduleInfo) throws IOException {
- VelocityContext context = new VelocityContext();
- context.put("util", new MarkdownUtil());
- context.put("moduleDocstring", moduleInfo.getModuleDocstring());
-
- StringWriter stringWriter = new StringWriter();
+ ImmutableMap<String, Object> vars =
+ ImmutableMap.of(
+ "util", new MarkdownUtil(), "moduleDocstring", moduleInfo.getModuleDocstring());
Reader reader = readerFromPath(headerTemplateFilename);
try {
- velocityEngine.evaluate(context, stringWriter, headerTemplateFilename, reader);
- } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ return Template.parseFrom(reader).evaluate(vars);
+ } catch (ParseException | EvaluationException e) {
throw new IOException(e);
}
- return stringWriter.toString();
}
/**
@@ -98,19 +77,14 @@
* the given rule name.
*/
public String render(String ruleName, RuleInfo ruleInfo) throws IOException {
- VelocityContext context = new VelocityContext();
- context.put("util", new MarkdownUtil());
- context.put("ruleName", ruleName);
- context.put("ruleInfo", ruleInfo);
-
- StringWriter stringWriter = new StringWriter();
+ ImmutableMap<String, Object> vars =
+ ImmutableMap.of("util", new MarkdownUtil(), "ruleName", ruleName, "ruleInfo", ruleInfo);
Reader reader = readerFromPath(ruleTemplateFilename);
try {
- velocityEngine.evaluate(context, stringWriter, ruleTemplateFilename, reader);
- } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ return Template.parseFrom(reader).evaluate(vars);
+ } catch (ParseException | EvaluationException e) {
throw new IOException(e);
}
- return stringWriter.toString();
}
/**
@@ -118,19 +92,15 @@
* object with the given name.
*/
public String render(String providerName, ProviderInfo providerInfo) throws IOException {
- VelocityContext context = new VelocityContext();
- context.put("util", new MarkdownUtil());
- context.put("providerName", providerName);
- context.put("providerInfo", providerInfo);
-
- StringWriter stringWriter = new StringWriter();
+ ImmutableMap<String, Object> vars =
+ ImmutableMap.of(
+ "util", new MarkdownUtil(), "providerName", providerName, "providerInfo", providerInfo);
Reader reader = readerFromPath(providerTemplateFilename);
try {
- velocityEngine.evaluate(context, stringWriter, providerTemplateFilename, reader);
- } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ return Template.parseFrom(reader).evaluate(vars);
+ } catch (ParseException | EvaluationException e) {
throw new IOException(e);
}
- return stringWriter.toString();
}
/**
@@ -138,18 +108,14 @@
* object.
*/
public String render(StarlarkFunctionInfo functionInfo) throws IOException {
- VelocityContext context = new VelocityContext();
- context.put("util", new MarkdownUtil());
- context.put("funcInfo", functionInfo);
-
- StringWriter stringWriter = new StringWriter();
+ ImmutableMap<String, Object> vars =
+ ImmutableMap.of("util", new MarkdownUtil(), "funcInfo", functionInfo);
Reader reader = readerFromPath(functionTemplateFilename);
try {
- velocityEngine.evaluate(context, stringWriter, functionTemplateFilename, reader);
- } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ return Template.parseFrom(reader).evaluate(vars);
+ } catch (ParseException | EvaluationException e) {
throw new IOException(e);
}
- return stringWriter.toString();
}
/**
@@ -157,20 +123,17 @@
* with the given aspect name.
*/
public String render(String aspectName, AspectInfo aspectInfo) throws IOException {
- VelocityContext context = new VelocityContext();
- context.put("util", new MarkdownUtil());
- context.put("aspectName", aspectName);
- context.put("aspectInfo", aspectInfo);
-
- StringWriter stringWriter = new StringWriter();
+ ImmutableMap<String, Object> vars =
+ ImmutableMap.of(
+ "util", new MarkdownUtil(), "aspectName", aspectName, "aspectInfo", aspectInfo);
Reader reader = readerFromPath(aspectTemplateFilename);
try {
- velocityEngine.evaluate(context, stringWriter, aspectTemplateFilename, reader);
- } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
+ return Template.parseFrom(reader).evaluate(vars);
+ } catch (ParseException | EvaluationException e) {
throw new IOException(e);
}
- return stringWriter.toString();
}
+
/**
* Returns a reader from the given path.
*
@@ -179,7 +142,7 @@
private static Reader readerFromPath(String filePath) throws IOException {
if (Files.exists(Paths.get(filePath))) {
Path path = Paths.get(filePath);
- return Files.newBufferedReader(path);
+ return Files.newBufferedReader(path, UTF_8);
}
InputStream inputStream = MarkdownRenderer.class.getClassLoader().getResourceAsStream(filePath);
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
index 4dd6310..69c6e9f 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownUtil.java
@@ -14,7 +14,9 @@
package com.google.devtools.build.skydoc.rendering;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Comparator.naturalOrder;
+import static java.util.stream.Collectors.joining;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
@@ -29,7 +31,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
/** Contains a number of utility methods for markdown rendering. */
public final class MarkdownUtil {
@@ -116,30 +117,26 @@
/**
* Return a string representing the rule summary for the given rule with the given name.
*
- * For example: 'my_rule(foo, bar)'.
- * The summary will contain hyperlinks for each attribute.
+ * <p>For example: 'my_rule(foo, bar)'. The summary will contain hyperlinks for each attribute.
*/
@SuppressWarnings("unused") // Used by markdown template.
public String ruleSummary(String ruleName, RuleInfo ruleInfo) {
List<String> attributeNames =
- ruleInfo.getAttributeList().stream()
- .map(AttributeInfo::getName)
- .collect(Collectors.toList());
+ ruleInfo.getAttributeList().stream().map(AttributeInfo::getName).collect(toImmutableList());
return summary(ruleName, attributeNames);
}
/**
* Return a string representing the summary for the given provider with the given name.
*
- * For example: 'MyInfo(foo, bar)'.
- * The summary will contain hyperlinks for each field.
+ * <p>For example: 'MyInfo(foo, bar)'. The summary will contain hyperlinks for each field.
*/
@SuppressWarnings("unused") // Used by markdown template.
public String providerSummary(String providerName, ProviderInfo providerInfo) {
List<String> fieldNames =
providerInfo.getFieldInfoList().stream()
.map(field -> field.getName())
- .collect(Collectors.toList());
+ .collect(toImmutableList());
return summary(providerName, fieldNames);
}
@@ -153,7 +150,7 @@
List<String> attributeNames =
aspectInfo.getAttributeList().stream()
.map(AttributeInfo::getName)
- .collect(Collectors.toList());
+ .collect(toImmutableList());
return summary(aspectName, attributeNames);
}
@@ -167,7 +164,7 @@
List<String> paramNames =
funcInfo.getParameterList().stream()
.map(FunctionParamInfo::getName)
- .collect(Collectors.toList());
+ .collect(toImmutableList());
return summary(funcInfo.getFunctionName(), paramNames);
}
@@ -178,7 +175,7 @@
String paramLinksLine =
params.stream()
.map(param -> String.format("<a href=\"#%s-%s\">%s</a>", functionName, param, param))
- .collect(Collectors.joining(", "));
+ .collect(joining(", "));
paramLinksLines.add(paramLinksLine);
}
String paramList =