Skip to content

Commit

Permalink
Add build-items.adoc
Browse files Browse the repository at this point in the history
This file is generated by running the following command in the root:

```bash
find core/deployment core/test-extension extensions -name "*BuildItem.java" | jbang .github/quarkusbuilditemdoc.java > docs/src/main/asciidoc/build-items.adoc
```

Fixes #9945
  • Loading branch information
gastaldi committed Sep 18, 2020
1 parent f41fcc4 commit 3e5e591
Show file tree
Hide file tree
Showing 2 changed files with 1,553 additions and 0 deletions.
216 changes: 216 additions & 0 deletions .github/quarkusbuilditemdoc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
//usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS info.picocli:picocli:4.5.0
//DEPS org.jboss.forge.roaster:roaster-jdt:2.22.2.Final
//DEPS org.eclipse.collections:eclipse-collections:10.4.0
//DEPS org.yaml:snakeyaml:1.27
//DEPS io.fabric8:maven-model-helper:16

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Callable;

import io.fabric8.maven.Maven;
import org.eclipse.collections.api.multimap.Multimap;
import org.eclipse.collections.api.multimap.MutableMultimap;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.factory.Multimaps;
import org.eclipse.collections.impl.tuple.Tuples;
import org.jboss.forge.roaster.Roaster;
import org.jboss.forge.roaster.model.source.FieldSource;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.yaml.snakeyaml.Yaml;
import picocli.CommandLine;
import picocli.CommandLine.Command;

@Command(name = "builditemdoc", mixinStandardHelpOptions = true, version = "builditemdoc 0.1",
description = "builditemdoc made with jbang")
class quarkusbuilditemdoc implements Callable<Integer> {

public static void main(String... args) {
int exitCode = new CommandLine(new quarkusbuilditemdoc()).execute(args);
System.exit(exitCode);
}

// find extensions -name "*BuildItem.java" | jbang ~/workspace/quarkus-jbang-catalog/builditemdoc.java > docs/src/main/asciidoc/build-items.adoc
@Override
public Integer call() throws Exception {
final Multimap<String, Pair<Path, JavaClassSource>> multimap = collect();
Map<String, String> names = extractNames(Paths.get("."), multimap.keySet());
printDocumentHeader();
// Print Core first
{
printTableHeader(names.remove("Core"));
for (Pair<Path, JavaClassSource> source : multimap.get("Core")) {
printTableRow(source);
}
printTableFooter();
}
names.forEach((key, name) -> {
printTableHeader(name);
for (Pair<Path, JavaClassSource> source : multimap.get(key)) {
printTableRow(source);
}
printTableFooter();
});
return 0;
}

private String buildDescriptionFromJavaDoc(JavaClassSource source) {
if (!source.hasJavaDoc()) {
return "<i>No Javadoc found</i>";
}
return source.getJavaDoc().getText();
}

private Multimap<String, Pair<Path, JavaClassSource>> collect() throws IOException {
MutableMultimap<String, Pair<Path, JavaClassSource>> multimap = Multimaps.mutable.list.empty();
String line;
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
while ((line = br.readLine()) != null) {
Path path = Paths.get(line);
JavaClassSource source = Roaster.parse(JavaClassSource.class, path.toFile());
// Ignore deprecated annotations and non-public classes
if (!source.hasAnnotation(Deprecated.class) && source.isPublic()) {
String name;
Path pom = findPom(path);
if (pom != null) {
name = Maven.readModel(pom).getName();
} else {
String pathString = path.toString();
int spiIdx = pathString.indexOf("/spi/src");
int runtimeIdx = pathString.indexOf("/runtime/src");
int deploymentIdx = pathString.indexOf("/deployment/src");
int idx = Math.max(Math.max(spiIdx, runtimeIdx), deploymentIdx);
int extensionsIdx = pathString.indexOf("extensions/");
int startIdx = 0;
if (extensionsIdx != -1) {
startIdx = extensionsIdx + 11;
}
if (idx == -1) {
name = pathString.substring(startIdx, pathString.indexOf("/", startIdx + 1));
} else {
name = pathString.substring(startIdx, idx);
}
}
// sanitize name
name = name.replace("Quarkus - ", "")
.replace(" - Deployment", "");
Pair<Path, JavaClassSource> pair = Tuples.pair(path, source);
multimap.put(name, pair);
}
}
}
return multimap;
}

private Path findPom(Path path) {
Path pom = null;
Path parent = path;
while (pom == null && (parent = parent.getParent()) != null) {
Path resolve = parent.resolve("pom.xml");
if (Files.exists(resolve)) {
pom = resolve;
}
}
return pom;
}


private Map<String, String> extractNames(Path root, Iterable<String> extensionDirs) throws IOException {
Map<String, String> names = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Yaml yaml = new Yaml();
for (String extension : extensionDirs) {
Path yamlPath = root.resolve("extensions/" + extension + "/runtime/src/main/resources/META-INF/quarkus-extension.yaml");
if (Files.exists(yamlPath)) {
try (InputStream is = Files.newInputStream(yamlPath)) {
Map<String, String> map = yaml.load(is);
names.put(extension, map.get("name"));
}
} else {
names.put(extension, extension);
}
}
return names;
}

private void printDocumentHeader() {
System.out.println("////");
System.out.println("This guide is maintained in the main Quarkus repository");
System.out.println("and pull requests should be submitted there:");
System.out.println("https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc");
System.out.println("////");
System.out.println();
System.out.println("= Quarkus - Build Items");
System.out.println();
System.out.println("Here you can find a list of Build Items and the extension that provides them:");
System.out.println();
}

private void printTableHeader(String title) {
System.out.println("== " + title);
System.out.println("[%header,cols=2*]");
System.out.println("|===");
System.out.println("|Class Name |Attributes ");
}

private void printTableRow(Pair<Path, JavaClassSource> pair) {
//TODO: Use tagged version?
String link = "https://github.com/quarkusio/quarkus/blob/master/" + pair.getOne();
JavaClassSource source = pair.getTwo();
String className = source.getQualifiedName();
String attributes = buildAttributes(source);
String description = buildDescriptionFromJavaDoc(source);

System.out.println("a| " + link + "[`" + className + "`, window=\"_blank\"] :: +++" +
javadocToHTML(description) + "+++");
System.out.println("a| " + attributes);
}

private String buildAttributes(JavaClassSource source) {
StringBuilder sb = new StringBuilder();
for (FieldSource<JavaClassSource> field : source.getFields()) {
if (field.isStatic()) {
continue;
}
sb.append("`" + field.getType().getName() + " " + field.getName() + "` :: ");
if (field.hasJavaDoc()) {
sb.append("+++" + javadocToHTML(field.getJavaDoc().getText()) + "+++");
}
sb.append("\n");
}
return sb.length() == 0 ? "None" : sb.toString();
}

private void printTableFooter() {
System.out.println("|===");
}

private String javadocToHTML(String content) {
return content
.replaceAll("\\{?@see ", "<pre>")
.replaceAll("\\{?@code ", "<pre>")
.replaceAll("\\{?@link ", "<pre>")
.replaceAll(" ?}", "</pre>");
}

private String javadocToAsciidoc(String content) {
return content
.replaceAll("<p>", "\n")
.replaceAll("</p>", "\n")
.replaceAll("\\{?@see ", "```")
.replaceAll("\\{?@code ", "```")
.replaceAll("\\{?@link ", "```")
.replaceAll("<pre>", "```\n")
.replaceAll("</pre>", "\n```")
.replaceAll(" ?}", "```");
}


}
Loading

0 comments on commit 3e5e591

Please sign in to comment.