Skip to content

Commit

Permalink
Introduce requires-quarkus-core extension metadata
Browse files Browse the repository at this point in the history
This introduces a `requires-quarkus-core` metadata declaring the required Quarkus Core version range in the extension YAML descriptor.
  • Loading branch information
gastaldi committed Jul 16, 2024
1 parent 75b4ed4 commit 8de00bd
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 38 deletions.
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 @@ metadata:
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,17 +102,18 @@ metadata:
- "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 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.

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

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/extension-metadata.adoc", "range": {"start": {"line": 115, "column": 96}}}, "severity": "INFO"}
<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"}
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

0 comments on commit 8de00bd

Please sign in to comment.