Use xref for documentation links

Closes gh-33745
This commit is contained in:
Moritz Halbritter
2024-03-26 10:11:47 +01:00
parent 9c87d71d07
commit 2d9b1ad592
11 changed files with 31 additions and 155 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.util.TreeSet;
*
* @author Brian Clozel
* @author Phillip Webb
* @author Moritz Halbritter
*/
class CompoundRow extends Row {
@@ -45,9 +46,9 @@ class CompoundRow extends Row {
void write(Asciidoc asciidoc) {
asciidoc.append("|");
asciidoc.append("[[" + getAnchor() + "]]");
asciidoc.append("<<" + getAnchor() + ",");
asciidoc.append("xref:#" + getAnchor() + "[");
this.propertyNames.forEach(asciidoc::appendWithHardLineBreaks);
asciidoc.appendln(">>");
asciidoc.appendln("]");
asciidoc.appendln("|+++", this.description, "+++");
asciidoc.appendln("|");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
*
* @author Brian Clozel
* @author Phillip Webb
* @author Moritz Halbritter
*/
class SingleRow extends Row {
@@ -56,7 +57,7 @@ class SingleRow extends Row {
void write(Asciidoc asciidoc) {
asciidoc.append("|");
asciidoc.append("[[" + getAnchor() + "]]");
asciidoc.appendln("<<" + getAnchor() + ",`+", this.displayName, "+`>>");
asciidoc.appendln("xref:#" + getAnchor() + "[`+", this.displayName, "+`]");
writeDescription(asciidoc);
writeDefaultValue(asciidoc);
}

View File

@@ -158,7 +158,7 @@ public class DocumentPluginGoals extends DefaultTask {
writer.println();
for (Parameter parameter : parameters) {
String name = parameter.getName();
writer.printf("| <<%s.%s,%s>>%n", detailsSectionId, parameterId(name), name);
writer.printf("| xref:#%s.%s[%s]%n", detailsSectionId, parameterId(name), name);
writer.printf("| `%s`%n", typeNameToJavadocLink(shortTypeName(parameter.getType()), parameter.getType()));
String defaultValue = parameter.getDefaultValue();
if (defaultValue != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,7 +128,7 @@ public class DocumentStarters extends DefaultTask {
}
private String addStarterCrossLinks(String input) {
return input.replaceAll("(spring-boot-starter[A-Za-z-]*)", "<<$1,`$1`>>");
return input.replaceAll("(spring-boot-starter[A-Za-z-]*)", "xref:#$1[`$1`]");
}
private static final class Starter implements Comparable<Starter> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link CompoundRow}.
*
* @author Brian Clozel
* @author Moritz Halbritter
*/
class CompoundRowTests {
@@ -39,8 +40,8 @@ class CompoundRowTests {
row.addProperty(new ConfigurationProperty("spring.test.third", "java.lang.String"));
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test]]<<my.spring.test,`+spring.test.first+` +" + NEWLINE
+ "`+spring.test.second+` +" + NEWLINE + "`+spring.test.third+` +" + NEWLINE + ">>" + NEWLINE
assertThat(asciidoc).hasToString("|[[my.spring.test]]xref:#my.spring.test[`+spring.test.first+` +" + NEWLINE
+ "`+spring.test.second+` +" + NEWLINE + "`+spring.test.third+` +" + NEWLINE + "]" + NEWLINE
+ "|+++This is a description.+++" + NEWLINE + "|" + NEWLINE);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link SingleRow}.
*
* @author Brian Clozel
* @author Moritz Halbritter
*/
class SingleRowTests {
@@ -38,7 +39,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|`+something+`" + NEWLINE);
}
@@ -49,7 +50,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|" + NEWLINE);
}
@@ -60,7 +61,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|`+first\\|second+`" + NEWLINE);
}
@@ -71,7 +72,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|`+first\\\\second+`" + NEWLINE);
}
@@ -82,7 +83,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description with a \\| pipe.+++" + NEWLINE + "|" + NEWLINE);
}
@@ -93,7 +94,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop.*+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop.*+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|" + NEWLINE);
}
@@ -105,7 +106,7 @@ class SingleRowTests {
SingleRow row = new SingleRow(SNIPPET, property);
Asciidoc asciidoc = new Asciidoc();
row.write(asciidoc);
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>"
assertThat(asciidoc).hasToString("|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]"
+ NEWLINE + "|+++This is a description.+++" + NEWLINE + "|`+first," + NEWLINE + "second," + NEWLINE
+ "third+`" + NEWLINE);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link Table}.
*
* @author Brian Clozel
* @author Moritz Halbritter
*/
class TableTests {
@@ -44,10 +45,10 @@ class TableTests {
assertThat(asciidoc).hasToString("[cols=\"4,3,3\", options=\"header\"]" + NEWLINE +
"|===" + NEWLINE +
"|Name|Description|Default Value" + NEWLINE + NEWLINE +
"|[[my.spring.test.other]]<<my.spring.test.other,`+spring.test.other+`>>" + NEWLINE +
"|[[my.spring.test.other]]xref:#my.spring.test.other[`+spring.test.other+`]" + NEWLINE +
"|+++This is another description.+++" + NEWLINE +
"|`+other value+`" + NEWLINE + NEWLINE +
"|[[my.spring.test.prop]]<<my.spring.test.prop,`+spring.test.prop+`>>" + NEWLINE +
"|[[my.spring.test.prop]]xref:#my.spring.test.prop[`+spring.test.prop+`]" + NEWLINE +
"|+++This is a description.+++" + NEWLINE +
"|`+something+`" + NEWLINE + NEWLINE +
"|===" + NEWLINE);

View File

@@ -6,8 +6,8 @@ This API documentation describes Spring Boot Actuators web endpoints.
Before you proceed, you should read the following topics:
* <<overview.endpoint-urls>>
* <<overview.timestamps>>
* xref:#overview.endpoint-urls[]
* xref:#overview.timestamps[]
NOTE: In order to get the correct JSON responses documented below, Jackson must be available.

View File

@@ -217,7 +217,7 @@ include::example$packaging/custom-layout-pom.xml[tags=custom-layout]
The layout factory is provided as an implementation of `LayoutFactory` (from `spring-boot-loader-tools`) explicitly specified in the pom.
If there is only one custom `LayoutFactory` on the plugin classpath and it is listed in `META-INF/spring.factories` then it is unnecessary to explicitly set it in the plugin configuration.
Layout factories are always ignored if an explicit <<packaging.repackage-goal.parameter-details.layout-factory,layout>> is set.
Layout factories are always ignored if an explicit xref:#packaging.repackage-goal.parameter-details.layout-factory[layout] is set.

View File

@@ -9,7 +9,7 @@ The parent project provides the following features:
* Compilation with `-parameters`.
* A dependency management section, inherited from the `spring-boot-dependencies` POM, that manages the versions of common dependencies.
This dependency management lets you omit `<version>` tags for those dependencies when used in your own POM.
* An execution of the <<goals.adoc#packaging.repackage-goal, `repackage` goal>> with a `repackage` execution id.
* An execution of the xref:maven-plugin:packaging.adoc#packaging.repackage-goal[`repackage` goal] with a `repackage` execution id.
* A `native` profile that configures the build to be able to generate a Native image.
* Sensible https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html[resource filtering].
* Sensible plugin configuration (https://github.com/ktoso/maven-git-commit-id-plugin[Git commit ID], and https://maven.apache.org/plugins/maven-shade-plugin/[shade]).

View File

@@ -1,129 +0,0 @@
import groovy.util.XmlSlurper
private String format(String input) {
input.replace("<code>", "`")
.replace("</code>", "`")
.replace("&lt;", "<")
.replace("&gt;", ">")
.replace("<br>", " ")
.replace("\n", " ")
.replace("&quot;", '"')
.replaceAll('\\{@code (.*?)\\}', '`$1`')
.replaceAll('\\{@link (.*?)\\}', '`$1`')
.replaceAll('\\{@literal (.*?)\\}', '`$1`')
.replaceAll('<a href=."(.*?)".>(.*?)</a>', '\$1[\$2]')
}
private writeParametersTable(PrintWriter writer, def goal, def parameters, def configuration) {
writer.println '[cols="3,2,3"]'
writer.println '|==='
writer.println '| Name | Type | Default'
writer.println()
parameters.each { parameter ->
def name = parameter.name.text()
writer.println("| <<goals-$goal-parameters-details-$name,$name>>")
def type = parameter.type.text()
if (type.lastIndexOf('.') >= 0) {
type = type.substring(type.lastIndexOf('.') + 1)
}
writer.println("| `$type`")
def defaultValue = "${configuration[name].@'default-value'}"
if (defaultValue) {
writer.println("| `$defaultValue`")
}
else {
writer.println("|")
}
writer.println()
}
writer.println '|==='
}
private writeParameterDetails(PrintWriter writer, def parameters, def configuration, def sectionId) {
parameters.each { parameter ->
def name = parameter.name.text()
writer.println "[[$sectionId-$name]]"
writer.println "==== `$name`"
writer.println(format(parameter.description.text()))
writer.println()
writer.println '[cols="10h,90"]'
writer.println '|==='
writer.println()
writer.println '| Name'
writer.println "| `$name`"
writer.println '| Type'
def type = parameter.type.text()
if (type.lastIndexOf('.') >= 0) {
type = type.substring(type.lastIndexOf('.') + 1)
}
writer.println("| `$type`")
def defaultValue = "${configuration[name].@'default-value'}"
if (defaultValue) {
writer.println '| Default value'
writer.println("| `$defaultValue`")
}
def userProperty = "${configuration[name].text().replace('${', '`').replace('}', '`')}"
writer.println '| User property'
userProperty ? writer.println("| ${userProperty}") : writer.println("|")
writer.println '| Since'
def since = parameter.since.text()
since ? writer.println("| `${since}`") : writer.println("|")
writer.println '| Required'
writer.println "| ${parameter.required.text()}"
writer.println()
writer.println '|==='
}
}
def plugin = new XmlSlurper().parse("${project.build.outputDirectory}/META-INF/maven/plugin.xml" as File)
String goalPrefix = plugin.goalPrefix.text()
File goalsDir = new File(project.build.directory, "generated-resources/goals/")
goalsDir.mkdirs()
new File(goalsDir, "overview.adoc").withPrintWriter { writer ->
writer.println '[cols="1,3"]'
writer.println '|==='
writer.println '| Goal | Description'
writer.println()
plugin.mojos.mojo.each { mojo ->
def goal = mojo.goal.text()
writer.println "| <<goals-$goal,${goalPrefix}:${mojo.goal.text()}>>"
writer.println "| ${format(mojo.description.text())}"
writer.println()
}
writer.println '|==='
}
plugin.mojos.mojo.each { mojo ->
String goal = mojo.goal.text()
new File(goalsDir, "${goal}.adoc").withPrintWriter { writer ->
def sectionId = "goals-$goal"
writer.println()
writer.println("[[$sectionId]]")
writer.println("== `$goalPrefix:$goal`")
writer.println("`${plugin.groupId.text()}:${plugin.artifactId.text()}:${plugin.version.text()}:${mojo.goal.text()}`")
writer.println()
writer.println(format(mojo.description.text()))
writer.println()
def parameters = mojo.parameters.parameter.findAll { it.editable.text() == 'true' }
def requiredParameters = parameters.findAll { it.required.text() == 'true' }
if (requiredParameters.size()) {
writer.println("[[$sectionId-parameters-required]]")
writer.println("=== Required parameters")
writeParametersTable(writer, goal, requiredParameters, mojo.configuration)
writer.println()
}
def optionalParameters = parameters.findAll { it.required.text() == 'false' }
if (optionalParameters.size()) {
writer.println("[[$sectionId-parameters-optional]]")
writer.println("=== Optional parameters")
writeParametersTable(writer, goal, optionalParameters, mojo.configuration)
writer.println()
}
def detailsSectionId = "$sectionId-parameters-details"
writer.println("[[$detailsSectionId]]")
writer.println("=== Parameter details")
writeParameterDetails(writer, parameters, mojo.configuration, detailsSectionId)
writer.println()
}
}