From 07fd5cc473f97dbd1b3b9f351fccd434c7e862e5 Mon Sep 17 00:00:00 2001 From: Alexey Loubyansky Date: Mon, 21 Feb 2022 16:52:16 +0100 Subject: [PATCH] Do not report Quarkus BOM imports as 'unnecessary' in the parent POMs of multimodule projects quarkus:info and quarkus:update basic docs Co-authored-by: Guillaume Smet --- docs/src/main/asciidoc/maven-tooling.adoc | 141 ++++++++++++++++++ .../workspace/DefaultWorkspaceModule.java | 6 +- .../commands/handlers/InfoCommandHandler.java | 11 +- 3 files changed, 153 insertions(+), 5 deletions(-) diff --git a/docs/src/main/asciidoc/maven-tooling.adoc b/docs/src/main/asciidoc/maven-tooling.adoc index d6a451df4c20c..eb4a451fb9f00 100644 --- a/docs/src/main/asciidoc/maven-tooling.adoc +++ b/docs/src/main/asciidoc/maven-tooling.adoc @@ -952,3 +952,144 @@ the `${maven.multiModuleProjectDirectory}` will be pointing to the directory fro The `${session.topLevelProject.basedir.absolutePath}` will be pointing either to the directory from which the `mvn` command was launched or to the directory targeted with the `-f` argument, if it was specified. + +[[project-info]] +== Quarkus project info + +The Quarkus Maven plugin includes a goal called `info` (currently marked as 'experimental') that logs Quarkus-specific information about the project, such as: the imported Quarkus platform BOMs and the Quarkus extensions found among the project dependencies. +In a multi-module project `quarkus:info` will assume that the current module, in which it is executed, is the main module of the application. + +NOTE: The report generated by `quarkus:info` is not currently including the Quarkus Maven plugin information, however it's planned to be added in the future releases. + +Here is an example `info` output for a simple project: +[source,text,subs=attributes+] +---- +[aloubyansky@localhost code-with-quarkus]$ mvn quarkus:info +[INFO] Scanning for projects... +[INFO] +[INFO] ---------------------< org.acme:code-with-quarkus >--------------------- +[INFO] Building code-with-quarkus 1.0.0-SNAPSHOT +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- quarkus-maven-plugin:{quarkus-version}:info (default-cli) @ code-with-quarkus --- +[WARNING] quarkus:info goal is experimental, its options and output may change in future versions +[INFO] Quarkus platform BOMs: <1> +[INFO] io.quarkus.platform:quarkus-bom:pom:{quarkus-version} +[INFO] io.quarkus.platform:quarkus-kogito-bom:pom:{quarkus-version} +[INFO] io.quarkus.platform:quarkus-camel-bom:pom:{quarkus-version} +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-bom: <2> +[INFO] io.quarkus:quarkus-resteasy-reactive +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-kogito-bom: <3> +[INFO] org.kie.kogito:kogito-quarkus-decisions +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-camel-bom: <4> +[INFO] org.apache.camel.quarkus:camel-quarkus-rabbitmq +[INFO] +[INFO] Extensions from registry.quarkus.io: <5> +[INFO] io.quarkiverse.prettytime:quarkus-prettytime:0.2.1 +---- + +<1> Quarkus platform BOMs imported in the project (BOMs imported by parent POMs will also be reported) +<2> Direct Quarkus extension dependencies managed by the `quarkus-bom` +<3> Direct Quarkus extension dependencies managed by the `quarkus-kogito-bom` +<4> Direct Quarkus extension dependencies managed by the `quarkus-camel-bom` +<5> Direct Quarkus extensions dependencies that aren't managed by Quarkus BOMs but found in the Quarkus extension registry + +NOTE: `quarkus:info` will also report Quarkus extensions that aren't found in the Quarkus extension registries if those are present among the project dependencies, indicating they have an 'unknown origin'. + +[[project-info-misaligned]] +=== Highlighing misaligned versions + +`quarkus:info` will also highlight basic Quarkus dependency version misalignments, in case they are detected. For example, if we modify the project mentioned above by removing the `kogito-quarkus-decisions` extension from the dependencies and adding a `2.6.3.Final` `` element to the `quarkus-resteasy-reactive` dependency that is managed by the `quarkus-bom` and then run `quarkus:info` again, we'll see something like: + +[source,text,subs=attributes+] +---- +[INFO] --- quarkus-maven-plugin:{quarkus-version}:info (default-cli) @ code-with-quarkus --- +[WARNING] quarkus:info goal is experimental, its options and output may change in future versions +[INFO] Quarkus platform BOMs: +[INFO] io.quarkus.platform:quarkus-bom:pom:{quarkus-version} +[INFO] io.quarkus.platform:quarkus-kogito-bom:pom:{quarkus-version} | unnecessary <1> +[INFO] io.quarkus.platform:quarkus-camel-bom:pom:{quarkus-version} +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-bom: +[INFO] io.quarkus:quarkus-resteasy-reactive:2.6.3.Final | misaligned <2> +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-camel-bom: +[INFO] org.apache.camel.quarkus:camel-quarkus-rabbitmq +[INFO] +[INFO] Extensions from registry.quarkus.io: +[INFO] io.quarkiverse.prettytime:quarkus-prettytime:0.2.1 +[INFO] +[WARNING] Non-recommended Quarkus platform BOM and/or extension versions were found. For more details, please, execute 'mvn quarkus:update -Drectify' +---- + +<1> The `quarkus-kogito-bom` import is now reported as 'unnecessary' since none of the Quarkus extensions it includes are found among the project dependencies +<2> The version `2.6.3.Final` of the `quarkus-resteasy-reactive` is now reported as being misaligned with the version managed by the Quarkus platform BOM imported in the project, which is {quarkus-version} + +[[project-update]] +== Quarkus project update + +The `quarkus:update` goal (currently marked as 'experimental') provided by the Quarkus Maven plugin can be used to check whether there are Quarkus-related updates available for a project, such as: new releases of the relevant Quarkus platform BOMs and non-platform Quarkus extensions present in the project. In a multi-module project the `update` goal is meant to be executed from the main Quarkus application module. + +IMPORTANT: At this point, the `quarkus:update` goal does not actually apply the recommended updates but simply reports what they are and how to apply them manually. + +NOTE: The Quarkus Maven plugin version isn't currently included in the update report, however it's planned to be added in the future releases. + +The way `quarkus:update` works, first, all the direct Quarkus extension dependencies of the project are collected (those that are managed by the Quarkus platform BOMs and those that aren't but found in the Quarkus extension registries). Then the configured Quarkus extension registries (typically the `registry.quarkus.io`) will be queried for the latest recommended/supported Quarkus platform versions and non-platform Quarkus extensions compatible with them. The algorithm will then select the latest compatible combination of all the extensions found in the project, assuming such a combination actually exists. Otherwise, no updates will be suggested. + +Assuming we have a project including Kogito, Camel and core Quarkus extensions available in the Quarkus platform based on Quarkus `2.7.1.Final`, the output of the `quarkus:update` would look like: +[source,text,subs=attributes+] +---- +[aloubyansky@localhost code-with-quarkus]$ mvn quarkus:update +[INFO] Scanning for projects... +[INFO] +[INFO] ---------------------< org.acme:code-with-quarkus >--------------------- +[INFO] Building code-with-quarkus 1.0.0-SNAPSHOT +[INFO] --------------------------------[ jar ]--------------------------------- +[INFO] +[INFO] --- quarkus-maven-plugin:{quarkus-version}:update (default-cli) @ code-with-quarkus --- +[WARNING] quarkus:update goal is experimental, its options and output might change in future versions +[INFO] +[INFO] Recommended Quarkus platform BOM updates: <1> +[INFO] Update: io.quarkus.platform:quarkus-bom:pom:2.7.1.Final -> {quarkus-version} +[INFO] Update: io.quarkus.platform:quarkus-kogito-bom:pom:2.7.1.Final -> {quarkus-version} +[INFO] Update: io.quarkus.platform:quarkus-camel-bom:pom:2.7.1.Final -> {quarkus-version} +---- + +<1> A list of currently recommended Quarkus platform BOM updates + +NOTE: Typically, a single project property will be used to manage all the Quarkus platform BOMs but the implementation isn't currently smart enough to point that out and will report updates for each BOM individually. + +If we modify the project to remove all the Kogito extensions from the project, change the version of the `quarkus-resteasy-reactive` extension to `2.6.3.Final` and downgrade `quarkus-prettytime` which is not included in the Quarkus platform BOMs to `0.2.0`, `quarkus:update` will report something like: + +[source,text,subs=attributes+] +---- +[INFO] Recommended Quarkus platform BOM updates: <1> +[INFO] Update: io.quarkus.platform:quarkus-bom:pom:2.7.1.Final -> {quarkus-version} +[INFO] Update: io.quarkus.platform:quarkus-camel-bom:pom:2.7.1.Final -> {quarkus-version} +[INFO] Remove: io.quarkus.platform:quarkus-kogito-bom:pom:2.7.1.Final <2> +[INFO] +[INFO] Extensions from io.quarkus.platform:quarkus-bom: +[INFO] Update: io.quarkus:quarkus-resteasy-reactive:2.6.3.Final -> remove version (managed) <3> +[INFO] +[INFO] Extensions from registry.quarkus.io: +[INFO] Update: io.quarkiverse.prettytime:quarkus-prettytime:0.2.0 -> 0.2.1 <4> +---- + +<1> A list of the currently recommended Quarkus platform BOM updates for the project +<2> Given that the project does not include any Kogito extensions, the BOM import is recommended to be removed +<3> An outdated version of the `quarkus-resteasy-reactive` is recommended to be removed in favor of the one managed by the `quarkus-bom` +<4> The latest compatible version of the `quarkus-prettytime` extension + +=== Quarkus project rectify + +As was mentioned above, `quarkus:info`, besides reporting Quarkus platform and extension versions, performs a quick version alignment check, to make sure the extension versions used in the project are compatible with the imported Quarkus platform BOMs. If misalignments are detected, the following warning message will be logged: + +[source,text,subs=attributes+] +---- +[WARNING] Non-recommended Quarkus platform BOM and/or extension versions were found. For more details, please, execute 'mvn quarkus:update -Drectify' +---- + +When the `rectify` option is enabled, `quarkus:update`, instead of suggesting the latest recommended Quarkus version updates, will log update instructions to simply align the extension dependency versions found in the project with the currently imported Quarkus platform BOMs. diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java index 5a530b56126af..853eba5134974 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/workspace/DefaultWorkspaceModule.java @@ -232,7 +232,7 @@ public PathCollection getBuildFiles() { @Override public Collection getDirectDependencyConstraints() { - return directDepConstraints; + return directDepConstraints == null ? Collections.emptyList() : directDepConstraints; } public void setDirectDependencyConstraints(List directDepConstraints) { @@ -241,7 +241,7 @@ public void setDirectDependencyConstraints(List directDepConstraints @Override public Collection getDirectDependencies() { - return directDeps; + return directDeps == null ? Collections.emptyList() : directDeps; } public void setDirectDependencies(List directDeps) { @@ -249,7 +249,7 @@ public void setDirectDependencies(List directDeps) { } public void addDirectDependency(Dependency directDep) { - if (directDeps.isEmpty()) { + if (directDeps == null || directDeps.isEmpty()) { directDeps = new ArrayList<>(); } this.directDeps.add(directDep); diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/InfoCommandHandler.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/InfoCommandHandler.java index e240c5f0ec16d..7d50d0f2dad3b 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/InfoCommandHandler.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/InfoCommandHandler.java @@ -80,11 +80,17 @@ protected static boolean logState(ProjectState projectState, boolean perModule, if (rectify) { sb.append(String.format(UpdateCommandHandler.PLATFORM_RECTIFY_FORMAT, UpdateCommandHandler.REMOVE, platform.imported.toCompactCoords())); + recommendationsAvailable = true; } else { sb.append(" "); - sb.append(platform.imported.toCompactCoords()).append(" | unnecessary"); + sb.append(platform.imported.toCompactCoords()); + if (!projectState.getExtensions().isEmpty()) { + // The extension check is for modules that are aggregating modules (e.g. parent POMs) + // that import common BOMs. It's however not how it should be done. + sb.append(" | unnecessary"); + recommendationsAvailable = true; + } } - recommendationsAvailable = true; } else if (platform.isVersionUpdateRecommended()) { if (rectify) { sb.append(String.format(UpdateCommandHandler.PLATFORM_RECTIFY_FORMAT, @@ -118,6 +124,7 @@ protected static boolean logState(ProjectState projectState, boolean perModule, } if (projectState.getExtensions().isEmpty()) { + log.info(""); log.info("No Quarkus extensions found among the project dependencies"); return recommendationsAvailable; }