Skip to content

Commit

Permalink
Fix propagation of native category
Browse files Browse the repository at this point in the history
- Add native category to related tutorials
- Fix preamble spacing / doc attribute detection in native reference
- Add a few missing id values
- Fix summary/preamble for maven & gradle tooling guides

Fixes quarkusio#32953
  • Loading branch information
ebullient committed May 19, 2023
1 parent f7a6c85 commit 7bf7232
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 60 deletions.
3 changes: 2 additions & 1 deletion docs/src/main/asciidoc/deploying-to-kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="deploy-kubernetes"]
= Kubernetes extension
include::_attributes.adoc[]
:categories: cloud
:categories: cloud, native
:summary: This guide covers how to deploy a native application on Kubernetes.

Quarkus offers the ability to automatically generate Kubernetes resources based on sane defaults and user-supplied configuration using https://github.com/dekorateio/dekorate/[dekorate].
Expand Down
3 changes: 2 additions & 1 deletion docs/src/main/asciidoc/deploying-to-openshift.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="deploy-openshift"]
= Deploying on OpenShift
include::_attributes.adoc[]
:categories: cloud
:categories: cloud, native
:summary: This guide covers how to deploy a native application on OpenShift.

This guide covers generating and deploying OpenShift resources based on sane default and user supplied configuration.
Expand Down
3 changes: 2 additions & 1 deletion docs/src/main/asciidoc/getting-started-testing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="testing"]
= Testing Your Application
include::_attributes.adoc[]
:categories: core
:categories: core, native, tooling
:summary: This guide covers testing in JVM mode, native mode, and injection of resources into tests
:numbered:
:sectnums:
Expand Down
9 changes: 6 additions & 3 deletions docs/src/main/asciidoc/gradle-tooling.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Building Quarkus apps with Gradle
[id="gradle-tooling"]
= Quarkus and Gradle
include::_attributes.adoc[]
:categories: tooling
:summary: This guide covers: Gradle configuration, creating a new project, dealing with extensions, development mode, debugging, import in your IDE, building a native image, and build a container friendly executable
:categories: tooling, native
:summary: Develop and build your Quarkus application with Gradle
:devtools-no-maven:

Use Gradle to create a new project, add or remove extensions, launch development mode, debug your application, and build your application into a jar, native executable, or container-friendly executable. Import your project into your favorite IDE using Gradle project metadata.

[[project-creation]]
== Creating a new project

Expand Down
9 changes: 6 additions & 3 deletions docs/src/main/asciidoc/maven-tooling.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Building applications with Maven
[id="maven-tooling"]
= Quarkus and Maven
include::_attributes.adoc[]
:categories: tooling
:summary: This guide covers: Maven configuration, creating a new project, dealing with extensions, development mode, debugging, import in your IDE, building a native image, and build a container friendly executable
:categories: tooling, native
:summary: Develop and build your Quarkus application with Maven
:devtools-no-gradle:

Use Maven to create a new project, add or remove extensions, launch development mode, debug your application, and build your application into a jar, native executable, or container-friendly executable. Import your project into your favorite IDE using Maven project metadata.

[[project-creation]]
== Creating a new project

Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/native-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
[id="native-reference"]
= Native Reference Guide

include::_attributes.adoc[]
:categories: native

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* </ul>
*/
public class YamlMetadataGenerator {
private static Errors errors = new Errors();
private static Messages messages = new Messages();

final static String INCL_ATTRIBUTES = "include::_attributes.adoc[]\n";
final static String YAML_FRONTMATTER = "---\n";
Expand Down Expand Up @@ -117,8 +117,8 @@ public void writeYamlFiles() throws StreamWriteException, DatabindException, IOE
om.writeValue(targetDir.resolve("indexByType.yaml").toFile(), index);
om.writeValue(targetDir.resolve("indexByFile.yaml").toFile(), metadata);

om.writeValue(targetDir.resolve("errorsByType.yaml").toFile(), errors);
om.writeValue(targetDir.resolve("errorsByFile.yaml").toFile(), errors.messagesByFile);
om.writeValue(targetDir.resolve("errorsByType.yaml").toFile(), messages);
om.writeValue(targetDir.resolve("errorsByFile.yaml").toFile(), messages.allByFile());
}

public Index generateIndex() throws IOException {
Expand All @@ -130,7 +130,7 @@ public Index generateIndex() throws IOException {
throw new IllegalStateException(
String.format("Target directory (%s) does not exist. Exiting.%n", targetDir.toAbsolutePath()));
}
errors.setRoot(srcDir);
messages.setRoot(srcDir);

Options options = Options.builder()
.docType("book")
Expand All @@ -147,7 +147,7 @@ public Index generateIndex() throws IOException {
try {
str = Files.readString(path);
} catch (IOException e) {
errors.record("ioexception", path);
messages.record("ioexception", path);
return;
}

Expand All @@ -162,19 +162,19 @@ public Index generateIndex() throws IOException {
// it should be part of the document header
int includeAttr = str.indexOf(INCL_ATTRIBUTES);
if (includeAttr < 0) {
errors.record("missing-attributes", path);
messages.record("missing-attributes", path);
} else {
String prefix = str.substring(0, includeAttr);
if (prefix.contains("\n\n")) {
errors.record("detached-attributes", path);
messages.record("detached-attributes", path);
}
}

int titlePos = str.indexOf("\n= ");
int documentHeaderEnd = str.indexOf("\n\n", titlePos);
String documentHeader = str.substring(0, documentHeaderEnd);
if (documentHeader.contains(":toc:")) {
errors.record("toc", path);
messages.record("toc", path);
}

String title = doc.getDoctitle();
Expand All @@ -200,18 +200,18 @@ public Index generateIndex() throws IOException {
if (content.isPresent()) {
index.add(new DocMetadata(title, path, summaryString, categories, keywords, id));
} else {
errors.record("empty-preamble", path);
messages.record("empty-preamble", path);
index.add(new DocMetadata(title, path, summaryString, categories, keywords, id));
}
} else {
errors.record("missing-preamble", path);
messages.record("missing-preamble", path);
summaryString = getSummary(summary, Optional.empty());
index.add(new DocMetadata(title, path, summaryString, categories, keywords, id));
}

long spaceCount = summaryString.chars().filter(c -> c == (int) ' ').count();
if (spaceCount > 26) {
errors.record("summary-too-long", path);
messages.record("summary-too-long", path);
}
});
}
Expand Down Expand Up @@ -297,11 +297,14 @@ public static void addAll(Set<Category> set, Object source, Path path) {
return;
}
for (String c : source.toString().split("\\s*,\\s*")) {
try {
Category cat = Category.valueOf(c.toLowerCase().replace("-", "_"));
set.add(cat);
} catch (IllegalArgumentException ex) {
errors.record("unknown-category", path, "Unknown category: " + c);
String lower = c.toLowerCase();
Optional<Category> match = Stream.of(Category.values())
.filter(cat -> cat.id.equals(lower))
.findFirst();
if (match.isEmpty()) {
messages.record("unknown-category", path, "Unknown category: " + c);
} else {
set.add(match.get());
}
}
}
Expand Down Expand Up @@ -329,15 +332,17 @@ enum Type {
}
}

private static class Errors {
private static class Messages {
String root;
Map<String, Collection<String>> messagesByFile = new TreeMap<>();
Map<String, Collection<String>> errorsByFile = new TreeMap<>();
Map<String, Collection<String>> warningsByFile = new TreeMap<>();
public final Map<String, Collection<String>> errors = new TreeMap<>();

void setRoot(Path root) {
this.root = root.toString();
errors.clear();
messagesByFile.clear();
errorsByFile.clear();
warningsByFile.clear();
}

void record(String errorKey, Path path) {
Expand All @@ -349,10 +354,24 @@ void record(String errorKey, Path path, String message) {
if (message == null) {
message = getMessageforKey(errorKey);
}
messagesByFile.computeIfAbsent(filename, k -> new ArrayList<>()).add(message);

if (isWarning(errorKey)) {
warningsByFile.computeIfAbsent(filename, k -> new ArrayList<>()).add(message);
} else {
errorsByFile.computeIfAbsent(filename, k -> new ArrayList<>()).add(message);
}
errors.computeIfAbsent(errorKey, k -> new HashSet<>()).add(filename);
}

private boolean isWarning(String errorKey) {
switch (errorKey) {
case "missing-id":
case "not-diataxis-type":
return true;
}
return false;
}

private String getMessageforKey(String errorKey) {
switch (errorKey) {
case "missing-attributes":
Expand All @@ -377,8 +396,26 @@ private String getMessageforKey(String errorKey) {
return errorKey;
}

public Map<String, FileMessages> allByFile() {
Map<String, FileMessages> result = new TreeMap<>();
errorsByFile.forEach((k, v) -> {
FileMessages mr = result.computeIfAbsent(k, x -> new FileMessages());
mr.errors = v;
});
warningsByFile.forEach((k, v) -> {
FileMessages mr = result.computeIfAbsent(k, x -> new FileMessages());
mr.warnings = v;
});

return result;
}

Map<String, Collection<String>> errorsByFile() {
return messagesByFile;
return errorsByFile;
}

Map<String, Collection<String>> warningsByFile() {
return warningsByFile;
}
}

Expand Down Expand Up @@ -407,8 +444,8 @@ public Map<String, DocMetadata> metadataByFile() {
}

// convenience
public Map<String, Collection<String>> errorsByFile() {
return errors.errorsByFile();
public Map<String, FileMessages> messagesByFile() {
return messages.allByFile();
}
}

Expand Down Expand Up @@ -464,20 +501,20 @@ static class DocMetadata implements Comparable<DocMetadata> {
this.type = Type.reference;
} else {
this.type = Type.other;
errors.record("not-diataxis-type", path);
messages.record("not-diataxis-type", path);
}

if (id == null) {
errors.record("missing-id", path);
messages.record("missing-id", path);
} else if (type != Type.other && !id.endsWith(type.suffix)) {
errors.record("incorrect-id", path,
messages.record("incorrect-id", path,
String.format(
"The document id (%s) does not end with the correct suffix, should end with '-%s'%n",
id, type.suffix));
}

if (this.categories.isEmpty()) {
errors.record("missing-categories", path);
messages.record("missing-categories", path);
}
}

Expand Down Expand Up @@ -520,4 +557,25 @@ public int compareTo(DocMetadata that) {
return this.title.compareTo(that.title);
}
}

@JsonInclude(value = Include.NON_EMPTY)
public static class FileMessages {
Collection<String> errors;
Collection<String> warnings;

Collection<String> warnings() {
return warnings == null ? List.of() : warnings;
}

Collection<String> errors() {
return errors == null ? List.of() : errors;
}

public boolean listAll(StringBuilder sb) {
errors().forEach(e -> sb.append(" [ ERR] ").append(e).append("\n"));
warnings().forEach(e -> sb.append(" [WARN] ").append(e).append("\n"));
sb.append("\n");
return !errors().isEmpty();
}
}
}
23 changes: 12 additions & 11 deletions docs/src/test/java/io/quarkus/docs/YamlMetadataGeneratorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;

import io.quarkus.docs.generation.YamlMetadataGenerator;
import io.quarkus.docs.generation.YamlMetadataGenerator.FileMessages;
import io.quarkus.docs.generation.YamlMetadataGenerator.Index;

public class YamlMetadataGeneratorTest {
Expand Down Expand Up @@ -39,21 +39,22 @@ public void testAsciidocFiles() throws Exception {

// Generate YAML: doc requirements
Index index = metadataGenerator.generateIndex();
Map<String, Collection<String>> metadataErrors = index.errorsByFile();
Map<String, FileMessages> messages = index.messagesByFile();

boolean hasErrors = false;
StringBuilder sb = new StringBuilder("\n");
for (String fileName : metadataErrors.keySet()) {
sb.append(fileName).append(": ").append("\n");

Collection<String> mErrors = metadataErrors.getOrDefault(fileName, List.of());
mErrors.forEach(e -> sb.append(" ").append(e).append("\n"));
sb.append("\n");
for (String fileName : messages.keySet()) {
FileMessages fm = messages.get(fileName);
if (fm != null) {
sb.append(fileName).append(": ").append("\n");
hasErrors |= fm.listAll(sb);
}
}

String result = sb.toString().trim();
if (result.length() > 0) {
System.err.println(result);
// throw new LintException("target/errorsByFile.yaml");
System.err.println(result);
if (hasErrors) {
throw new LintException("target/errorsByFile.yaml");
} else {
System.out.println("🥳 OK");
}
Expand Down
Loading

0 comments on commit 7bf7232

Please sign in to comment.