Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce requires-quarkus-core extension metadata #41908

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions docs/src/main/asciidoc/extension-metadata.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@
artifact: "io.quarkus:quarkus-project-core-extension-codestarts::jar:999-SNAPSHOT"
config:
- "quarkus.rest."
built-with-quarkus-core: "999-SNAPSHOT" <1>
capabilities: <2>
built-with-quarkus-core: "3.8.5" <1>
requires-quarkus-core: "[3.8,)" <2>
capabilities: <3>
provides:
- "io.quarkus.rest"
- "io.quarkus.resteasy.reactive"
extension-dependencies: <3>
extension-dependencies: <4>
- "io.quarkus:quarkus-rest-common"
- "io.quarkus:quarkus-mutiny"
- "io.quarkus:quarkus-smallrye-context-propagation"
Expand All @@ -101,20 +102,21 @@
- "io.quarkus:quarkus-jsonp"
description: "A Jakarta REST implementation utilizing build time processing and Vert.x.\
\ This extension is not compatible with the quarkus-resteasy extension, or any of\
\ the extensions that depend on it." <4>
scm-url: "https://github.com/quarkusio/quarkus" <5>
sponsor: A Sponsoring Organisation <6>
\ the extensions that depend on it." <5>
scm-url: "https://github.com/quarkusio/quarkus" <6>
sponsor: A Sponsoring Organisation <7>
----

<1> Quarkus version the extension was built with
<2> https://quarkus.io/guides/capabilities[Capabilities] this extension provides
<3> Direct dependencies on other extensions
<4> Description that can be displayed to users. In this case, the description was copied from the `pom.xml` of the extension module but it could also be provided in the template file.
<5> The source code repository of this extension. Optional, and will often be set automatically using the `<scm>` information in the pom. In GitHub Actions builds, it will be inferred from the CI environment. For other GitHub repositories, it can be controlled by setting a `GITHUB_REPOSITORY` environment variable.
<6> The sponsor(s) of this extension. Optional, and will sometimes be determined automatically from commit history.
<2> The Quarkus version range this extension requires. Optional, and will be set automatically by using the `built-with-quarkus-core` as the minimum range.
<3> https://quarkus.io/guides/capabilities[Capabilities] this extension provides
<4> Direct dependencies on other extensions
<5> Description that can be displayed to users. In this case, the description was copied from the `pom.xml` of the extension module but it could also be provided in the template file.
<6> The source code repository of this extension. Optional, and will often be set automatically by using the `<scm>` information in the pom. In GitHub Actions builds, it will be inferred from the CI environment. For other GitHub repositories, it can be controlled by setting a `GITHUB_REPOSITORY` environment variable.
<7> The sponsor(s) of this extension. Optional, and will sometimes be determined automatically from commit history.

[[quarkus-extension-properties]]
== META-INF/quarkus-extension.properties

Check warning on line 119 in docs/src/main/asciidoc/extension-metadata.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'META-INF/quarkus-extension.properties'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'META-INF/quarkus-extension.properties'.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 119, "column": 4}}}, "severity": "INFO"}

Every **runtime** extension artifact **must** include this file. This file is read by the Quarkus bootstrap mechanism and is meant to contain only the information that is relevant for **building or bootstrapping** an applications. This file is typically generated by the corresponding Quarkus Maven or Gradle plugin when the extension project is built and shouldn't be edited manually.
The following properties may appear in this file:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.concurrent.atomic.AtomicReference;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Scm;
import org.apache.maven.plugin.AbstractMojo;
Expand Down Expand Up @@ -243,6 +244,12 @@ public static class RemovedResources {
@Parameter(defaultValue = "${maven.compiler.release}", readonly = true)
String minimumJavaVersion;

/**
* The Quarkus core version range that this extension requires
*/
@Parameter(property = "requiresQuarkusCore")
String requiresQuarkusCore;

ArtifactCoords deploymentCoords;
CollectResult collectedDeploymentDeps;
DependencyResult runtimeDeps;
Expand Down Expand Up @@ -290,6 +297,9 @@ public void execute() throws MojoExecutionException {
}
}

String quarkusCoreVersion = findQuarkusCoreVersion();
String quarkusCoreVersionRange = requiresQuarkusCore == null ? toVersionRange(quarkusCoreVersion) : requiresQuarkusCore;

final Properties props = new Properties();
props.setProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT, deployment);

Expand Down Expand Up @@ -386,6 +396,9 @@ public void execute() throws MojoExecutionException {
props.put(ApplicationModelBuilder.LESSER_PRIORITY_ARTIFACTS, val);
}

if (quarkusCoreVersionRange != null) {
props.put("requires-quarkus-version", quarkusCoreVersionRange);
}
final Path output = outputDirectory.toPath().resolve(BootstrapConstants.META_INF);
try {
Files.createDirectories(output);
Expand Down Expand Up @@ -457,7 +470,8 @@ public void execute() throws MojoExecutionException {
extObject.put("description", project.getDescription());
}

setBuiltWithQuarkusCoreVersion(extObject);
setBuiltWithQuarkusCoreVersion(quarkusCoreVersion, extObject);
setRequiresQuarkusCoreVersion(quarkusCoreVersionRange, extObject);
addJavaVersion(extObject);
addCapabilities(extObject);
addSource(extObject);
Expand All @@ -477,6 +491,21 @@ public void execute() throws MojoExecutionException {
}
}

private void setRequiresQuarkusCoreVersion(String compatibilityRange, ObjectNode extObject) {
ObjectNode metadata = getMetadataNode(extObject);
if (!metadata.has("requires-quarkus-core") && compatibilityRange != null) {
metadata.put("requires-quarkus-core", compatibilityRange);
}
}

private static String toVersionRange(String version) {
if (version == null) {
return null;
}
DefaultArtifactVersion dav = new DefaultArtifactVersion(version);
return "[" + dav.getMajorVersion() + "." + dav.getMinorVersion() + ",)";
}

private void ensureArtifactCoords(ObjectNode extObject) {
String groupId = null;
String artifactId = null;
Expand Down Expand Up @@ -606,7 +635,16 @@ private static void appendCapability(CapabilityConfig capability, StringBuilder
}
}

private void setBuiltWithQuarkusCoreVersion(ObjectNode extObject) throws MojoExecutionException {
private void setBuiltWithQuarkusCoreVersion(String coreVersion, ObjectNode extObject) throws MojoExecutionException {
if (coreVersion != null) {
ObjectNode metadata = getMetadataNode(extObject);
metadata.put("built-with-quarkus-core", coreVersion);
} else if (!ignoreNotDetectedQuarkusCoreVersion) {
throw new MojoExecutionException("Failed to determine the Quarkus core version used to build the extension");
}
}

private String findQuarkusCoreVersion() throws MojoExecutionException {
final QuarkusCoreDeploymentVersionLocator coreVersionLocator = new QuarkusCoreDeploymentVersionLocator();
final DependencyNode root;
try {
Expand All @@ -617,13 +655,7 @@ private void setBuiltWithQuarkusCoreVersion(ObjectNode extObject) throws MojoExe
throw new MojoExecutionException("Failed to collect runtime dependencies of " + project.getArtifact(), e);
}
root.accept(coreVersionLocator);
if (coreVersionLocator.coreVersion != null) {
ObjectNode metadata = getMetadataNode(extObject);
metadata.put("built-with-quarkus-core", coreVersionLocator.coreVersion);
} else if (!ignoreNotDetectedQuarkusCoreVersion) {
throw new MojoExecutionException("Failed to determine the Quarkus core version used to build the extension");
}

return coreVersionLocator.coreVersion;
}

private void addExtensionDependencies(ObjectNode extObject) throws MojoExecutionException {
Expand Down Expand Up @@ -845,9 +877,9 @@ private void validateExtensionDeps() throws MojoExecutionException {
if (buf.length() > 0) {
buf.append(System.lineSeparator());
}
buf.append("The deployment artifact " + rootDeploymentGact
+ " depends on the following Quarkus extension runtime artifacts that weren't found among the dependencies of "
+ project.getArtifact() + ":");
buf.append("The deployment artifact ").append(rootDeploymentGact).append(
" depends on the following Quarkus extension runtime artifacts that weren't found among the dependencies of ")
.append(project.getArtifact()).append(":");
for (ArtifactKey a : unexpectedRtDeps) {
buf.append(' ').append(a);
}
Expand All @@ -861,9 +893,9 @@ private void validateExtensionDeps() throws MojoExecutionException {
if (buf.length() > 0) {
buf.append(System.lineSeparator());
}
buf.append("The deployment artifact " + rootDeploymentGact
+ " depends on the following Quarkus extension deployment artifacts whose corresponding runtime artifacts were not found among the dependencies of "
+ project.getArtifact() + ":");
buf.append("The deployment artifact ").append(rootDeploymentGact).append(
" depends on the following Quarkus extension deployment artifacts whose corresponding runtime artifacts were not found among the dependencies of ")
.append(project.getArtifact()).append(":");
for (ArtifactKey a : unexpectedDeploymentDeps) {
buf.append(' ').append(a);
}
Expand Down Expand Up @@ -908,9 +940,7 @@ private void highlightInTree(int depth, DependencyNode node, Collection<Artifact
} else {
buf.append(' ');
}
for (int i = 0; i < depth; ++i) {
buf.append(" ");
}
buf.append(" ".repeat(Math.max(0, depth)));
buf.append(node.getArtifact());
branch.add(buf.toString());
if (!highlighted) {
Expand Down Expand Up @@ -1192,12 +1222,12 @@ public boolean visitEnter(DependencyNode dep) {
skipTheRest = true;
}
}
return skipTheRest ? false : true;
return !skipTheRest;
}

@Override
public boolean visitLeave(DependencyNode node) {
return skipTheRest ? false : true;
return !skipTheRest;
}
}

Expand Down Expand Up @@ -1253,9 +1283,7 @@ List<ArtifactKey> collectMissingDeploymentDeps(Log log) {
collected.add(n.gact);
}
buf.append(' ');
for (int i = 0; i < depth; ++i) {
buf.append(" ");
}
buf.append(" ".repeat(Math.max(0, depth)));
buf.append(n.gact);
log1.error(buf.toString());
});
Expand All @@ -1276,9 +1304,7 @@ List<ArtifactKey> collectDeploymentsOnRtCp(Log log) {
collected.add(n.gact);
}
buf.append(' ');
for (int i = 0; i < depth; ++i) {
buf.append(" ");
}
buf.append(" ".repeat(Math.max(0, depth)));
buf.append(n.gact);
log1.error(buf.toString());
});
Expand All @@ -1297,7 +1323,7 @@ private void handleChildren(Log log, int depth, List<ArtifactKey> collected, Nod
}
}

private static interface NodeHandler {
private interface NodeHandler {
void handle(Log log, int depth, Node n, List<ArtifactKey> collected);
}

Expand Down
Loading