diff --git a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionConfiguration.java b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionConfiguration.java index 9c5466ade7654..56c2da0507564 100644 --- a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionConfiguration.java +++ b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionConfiguration.java @@ -6,6 +6,7 @@ public class QuarkusExtensionConfiguration { + private boolean disableValidation; private String deploymentArtifact; private String deploymentModule; private List excludedArtifacts; @@ -21,6 +22,14 @@ public QuarkusExtensionConfiguration(Project project) { this.project = project; } + public void setDisableValidation(boolean disableValidation) { + this.disableValidation = disableValidation; + } + + public boolean isValidationDisabled() { + return disableValidation; + } + public String getDeploymentArtifact() { return deploymentArtifact; } diff --git a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionPlugin.java b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionPlugin.java index 88ee7bd84493b..17e96f45911d0 100644 --- a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionPlugin.java +++ b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionPlugin.java @@ -19,6 +19,7 @@ import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.extension.gradle.dependency.DeploymentClasspathBuilder; import io.quarkus.extension.gradle.tasks.ExtensionDescriptorTask; +import io.quarkus.extension.gradle.tasks.ValidateExtensionTask; import io.quarkus.gradle.tooling.ToolingUtils; import io.quarkus.runtime.LaunchMode; @@ -26,7 +27,9 @@ public class QuarkusExtensionPlugin implements Plugin { public static final String DEFAULT_DEPLOYMENT_PROJECT_NAME = "deployment"; public static final String EXTENSION_CONFIGURATION_NAME = "quarkusExtension"; + public static final String EXTENSION_DESCRIPTOR_TASK_NAME = "extensionDescriptor"; + public static final String VALIDATE_EXTENSION_TASK_NAME = "validateExtension"; public static final String QUARKUS_ANNOTATION_PROCESSOR = "io.quarkus:quarkus-extension-processor"; @@ -39,6 +42,9 @@ public void apply(Project project) { private void registerTasks(Project project, QuarkusExtensionConfiguration quarkusExt) { TaskContainer tasks = project.getTasks(); + Configuration runtimeModuleClasspath = project.getConfigurations() + .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); + TaskProvider extensionDescriptorTask = tasks.register(EXTENSION_DESCRIPTOR_TASK_NAME, ExtensionDescriptorTask.class, task -> { JavaPluginConvention convention = project.getConvention().getPlugin(JavaPluginConvention.class); @@ -46,9 +52,14 @@ private void registerTasks(Project project, QuarkusExtensionConfiguration quarku task.setOutputResourcesDir(mainSourceSet.getOutput().getResourcesDir()); task.setInputResourcesDir(mainSourceSet.getResources().getSourceDirectories().getAsPath()); task.setQuarkusExtensionConfiguration(quarkusExt); - Configuration classpath = project.getConfigurations() - .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); - task.setClasspath(classpath); + task.setClasspath(runtimeModuleClasspath); + }); + + TaskProvider validateExtensionTask = tasks.register(VALIDATE_EXTENSION_TASK_NAME, + ValidateExtensionTask.class, task -> { + task.setRuntimeModuleClasspath(runtimeModuleClasspath); + task.setQuarkusExtensionConfiguration(quarkusExt); + task.onlyIf(t -> !quarkusExt.isValidationDisabled()); }); project.getPlugins().withType( @@ -67,6 +78,13 @@ private void registerTasks(Project project, QuarkusExtensionConfiguration quarku deploymentProject.getPlugins().withType( JavaPlugin.class, javaPlugin -> addAnnotationProcessorDependency(deploymentProject)); + + validateExtensionTask.configure(task -> { + Configuration deploymentModuleClasspath = deploymentProject.getConfigurations() + .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); + task.setDeploymentModuleClasspath(deploymentModuleClasspath); + }); + deploymentProject.getTasks().withType(Test.class, test -> { test.useJUnitPlatform(); test.doFirst(task -> { @@ -117,10 +135,14 @@ private Project findDeploymentProject(Project project, QuarkusExtensionConfigura Project deploymentProject = project.getRootProject().findProject(deploymentProjectName); if (deploymentProject == null) { - project.getLogger().warn("Unable to find deployment project with name: " + deploymentProjectName - + ". You can configure the deployment project name by setting the 'deploymentArtifact' property in the plugin extension."); + if (project.getParent() != null) { + deploymentProject = project.getParent().findProject(deploymentProjectName); + } + if (deploymentProject == null) { + project.getLogger().warn("Unable to find deployment project with name: " + deploymentProjectName + + ". You can configure the deployment project name by setting the 'deploymentArtifact' property in the plugin extension."); + } } - return deploymentProject; } diff --git a/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTask.java b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTask.java new file mode 100644 index 0000000000000..1eb0f28d56d0d --- /dev/null +++ b/devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTask.java @@ -0,0 +1,130 @@ +package io.quarkus.extension.gradle.tasks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.gradle.api.DefaultTask; +import org.gradle.api.GradleException; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.ResolvedModuleVersion; +import org.gradle.api.logging.Logger; +import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.TaskAction; + +import io.quarkus.bootstrap.model.AppArtifactKey; +import io.quarkus.extension.gradle.QuarkusExtensionConfiguration; +import io.quarkus.gradle.tooling.dependency.DependencyUtils; +import io.quarkus.gradle.tooling.dependency.ExtensionDependency; + +public class ValidateExtensionTask extends DefaultTask { + + private QuarkusExtensionConfiguration extensionConfiguration; + private Configuration runtimeModuleClasspath; + private Configuration deploymentModuleClasspath; + + public ValidateExtensionTask() { + setDescription("Validate extension dependencies"); + setGroup("quarkus"); + } + + public void setQuarkusExtensionConfiguration(QuarkusExtensionConfiguration extensionConfiguration) { + this.extensionConfiguration = extensionConfiguration; + } + + @Internal + public Configuration getRuntimeModuleClasspath() { + return this.runtimeModuleClasspath; + } + + public void setRuntimeModuleClasspath(Configuration runtimeModuleClasspath) { + this.runtimeModuleClasspath = runtimeModuleClasspath; + } + + @Internal + public Configuration getDeploymentModuleClasspath() { + return this.deploymentModuleClasspath; + } + + public void setDeploymentModuleClasspath(Configuration deploymentModuleClasspath) { + this.deploymentModuleClasspath = deploymentModuleClasspath; + } + + @TaskAction + public void validateExtension() { + Set runtimeArtifacts = getRuntimeModuleClasspath().getResolvedConfiguration().getResolvedArtifacts(); + + List deploymentModuleKeys = collectRuntimeExtensionsDeploymentKeys(runtimeArtifacts); + List invalidRuntimeArtifacts = findExtensionInConfiguration(runtimeArtifacts, deploymentModuleKeys); + + Set deploymentArtifacts = getDeploymentModuleClasspath().getResolvedConfiguration() + .getResolvedArtifacts(); + List existingDeploymentModuleKeys = findExtensionInConfiguration(deploymentArtifacts, + deploymentModuleKeys); + deploymentModuleKeys.removeAll(existingDeploymentModuleKeys); + + boolean hasErrors = false; + if (!invalidRuntimeArtifacts.isEmpty()) { + hasErrors = true; + } + if (!deploymentModuleKeys.isEmpty()) { + hasErrors = true; + } + + if (hasErrors) { + printValidationErrors(invalidRuntimeArtifacts, deploymentModuleKeys); + } + } + + private List collectRuntimeExtensionsDeploymentKeys(Set runtimeArtifacts) { + List runtimeExtensions = new ArrayList<>(); + for (ResolvedArtifact resolvedArtifact : runtimeArtifacts) { + ExtensionDependency extension = DependencyUtils.getExtensionInfoOrNull(getProject(), resolvedArtifact); + if (extension != null) { + runtimeExtensions.add(new AppArtifactKey(extension.getDeploymentModule().getGroupId(), + extension.getDeploymentModule().getArtifactId())); + } + } + return runtimeExtensions; + } + + private List findExtensionInConfiguration(Set deploymentArtifacts, + List extensions) { + List foundExtensions = new ArrayList<>(); + + for (ResolvedArtifact deploymentArtifact : deploymentArtifacts) { + AppArtifactKey key = toAppArtifactKey(deploymentArtifact.getModuleVersion()); + if (extensions.contains(key)) { + foundExtensions.add(key); + } + } + return foundExtensions; + } + + private void printValidationErrors(List invalidRuntimeArtifacts, + List missingDeploymentArtifacts) { + Logger log = getLogger(); + log.error("Quarkus Extension Dependency Verification Error"); + + if (!invalidRuntimeArtifacts.isEmpty()) { + log.error("The following deployment artifact(s) appear on the runtime classpath: "); + for (AppArtifactKey invalidRuntimeArtifact : invalidRuntimeArtifacts) { + log.error("- " + invalidRuntimeArtifact); + } + } + + if (!missingDeploymentArtifacts.isEmpty()) { + log.error("The following deployment artifact(s) were found to be missing in the deployment module: "); + for (AppArtifactKey missingDeploymentArtifact : missingDeploymentArtifacts) { + log.error("- " + missingDeploymentArtifact); + } + } + + throw new GradleException("Quarkus Extension Dependency Verification Error. See logs below"); + } + + private static AppArtifactKey toAppArtifactKey(ResolvedModuleVersion artifactId) { + return new AppArtifactKey(artifactId.getId().getGroup(), artifactId.getId().getName()); + } +} diff --git a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/QuarkusExtensionPluginTest.java b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/QuarkusExtensionPluginTest.java index 4fb446d3d8472..c7c23768f5101 100644 --- a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/QuarkusExtensionPluginTest.java +++ b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/QuarkusExtensionPluginTest.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Path; +import java.util.Collections; import java.util.Properties; import org.assertj.core.api.Assertions; @@ -36,7 +37,7 @@ public void setupProject() throws IOException { @Test public void jarShouldContainsExtensionPropertiesFile() throws IOException { - TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent()); + TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList())); BuildResult jarResult = GradleRunner.create() .withPluginClasspath() @@ -65,7 +66,7 @@ public void jarShouldContainsExtensionPropertiesFile() throws IOException { @Test public void pluginShouldAddAnnotationProcessor() throws IOException { - TestUtils.createExtensionProject(testProjectDir); + TestUtils.createExtensionProject(testProjectDir, false, Collections.emptyList(), Collections.emptyList()); BuildResult dependencies = GradleRunner.create() .withPluginClasspath() .withProjectDir(testProjectDir) @@ -77,7 +78,7 @@ public void pluginShouldAddAnnotationProcessor() throws IOException { @Test public void pluginShouldAddAnnotationProcessorToDeploymentModule() throws IOException { - TestUtils.createExtensionProject(testProjectDir); + TestUtils.createExtensionProject(testProjectDir, false, Collections.emptyList(), Collections.emptyList()); BuildResult dependencies = GradleRunner.create() .withPluginClasspath() .withProjectDir(testProjectDir) diff --git a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/TestUtils.java b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/TestUtils.java index e6c4fbba4bf3d..aff88d4e038ea 100644 --- a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/TestUtils.java +++ b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/TestUtils.java @@ -11,6 +11,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import java.util.Properties; import org.gradle.testkit.runner.BuildResult; @@ -24,7 +25,12 @@ public class TestUtils { - public static String getDefaultGradleBuildFileContent() throws IOException { + public static String getDefaultGradleBuildFileContent(boolean disableValidation, List implementationDependencies) + throws IOException { + StringBuilder implementationBuilder = new StringBuilder(); + for (String implementationDependency : implementationDependencies) { + implementationBuilder.append("implementation(\"").append(implementationDependency).append("\")\n"); + } return "plugins {\n" + "id 'java'\n" + "id 'io.quarkus.extension'\n" + @@ -34,14 +40,25 @@ public static String getDefaultGradleBuildFileContent() throws IOException { "repositories { \n" + "mavenCentral()\n" + "mavenLocal()\n" + + "}\n" + + QuarkusExtensionPlugin.EXTENSION_CONFIGURATION_NAME + " { \n" + + "disableValidation = " + disableValidation + "\n" + + "}\n" + "dependencies { \n" + "implementation enforcedPlatform(\"io.quarkus:quarkus-bom:" + getCurrentQuarkusVersion() + "\")\n" + "implementation \"io.quarkus:quarkus-arc\" \n" + + implementationBuilder + "}\n"; } - public static String getDefaultDeploymentBuildFileContent() throws IOException { + public static String getDefaultDeploymentBuildFileContent(List implementationDependencies) throws IOException { + + StringBuilder implementationBuilder = new StringBuilder(); + for (String implementationDependency : implementationDependencies) { + implementationBuilder.append("implementation(\"").append(implementationDependency).append("\")\n"); + } + return "plugins {\n" + "id 'java'\n" + "}\n" + @@ -53,8 +70,9 @@ public static String getDefaultDeploymentBuildFileContent() throws IOException { "}\n" + "dependencies {\n" + "implementation enforcedPlatform(\"io.quarkus:quarkus-bom:" + getCurrentQuarkusVersion() + "\")\n" + - "implementation \"io.quarkus:quarkus-arc\" \n" + - "implementation project(\":runtime\")" + + "implementation \"io.quarkus:quarkus-arc-deployment\" \n" + + "implementation project(\":runtime\") \n" + + implementationBuilder + "}\n"; } @@ -70,17 +88,19 @@ public static BuildResult runExtensionDescriptorTask(File testProjectDir) { return extensionDescriptorResult; } - public static void createExtensionProject(File testProjectDir) throws IOException { + public static void createExtensionProject(File testProjectDir, boolean disableValidation, List runtimeDependencies, + List deploymentDependencies) throws IOException { File runtimeModule = new File(testProjectDir, "runtime"); runtimeModule.mkdir(); - writeFile(new File(runtimeModule, "build.gradle"), getDefaultGradleBuildFileContent()); + writeFile(new File(runtimeModule, "build.gradle"), + getDefaultGradleBuildFileContent(disableValidation, runtimeDependencies)); File runtimeTestFile = new File(runtimeModule, "src/main/java/runtime/Test.java"); runtimeTestFile.getParentFile().mkdirs(); writeFile(runtimeTestFile, "package runtime; public class Test {}"); File deploymentModule = new File(testProjectDir, "deployment"); deploymentModule.mkdir(); - writeFile(new File(deploymentModule, "build.gradle"), getDefaultDeploymentBuildFileContent()); + writeFile(new File(deploymentModule, "build.gradle"), getDefaultDeploymentBuildFileContent(deploymentDependencies)); File deploymentTestFile = new File(deploymentModule, "src/main/java/deployment/Test.java"); deploymentTestFile.getParentFile().mkdirs(); writeFile(deploymentTestFile, "package deployment; public class Test {}"); diff --git a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTaskTest.java b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTaskTest.java index 62d343e4ae995..a2f61a1bf1736 100644 --- a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTaskTest.java +++ b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTaskTest.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Properties; @@ -36,7 +37,7 @@ public void setupProject() throws IOException { @Test public void shouldCreateFilesWithDefaultValues() throws IOException { - TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent()); + TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList())); TestUtils.runExtensionDescriptorTask(testProjectDir); File extensionPropertiesFile = new File(testProjectDir, "build/resources/main/META-INF/quarkus-extension.properties"); @@ -74,7 +75,7 @@ public void shouldCreateFilesWithDefaultValues() throws IOException { @Test public void shouldUseCustomDeploymentArtifactName() throws IOException { - String buildFileContent = TestUtils.getDefaultGradleBuildFileContent() + String buildFileContent = TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList()) + QuarkusExtensionPlugin.EXTENSION_CONFIGURATION_NAME + " { " + "deploymentArtifact = 'custom.group:custom-deployment-artifact:0.1.0'" + "}"; @@ -90,7 +91,7 @@ public void shouldUseCustomDeploymentArtifactName() throws IOException { @Test public void shouldContainsConditionalDependencies() throws IOException { - String buildFileContent = TestUtils.getDefaultGradleBuildFileContent() + String buildFileContent = TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList()) + QuarkusExtensionPlugin.EXTENSION_CONFIGURATION_NAME + " { " + "conditionalDependencies= ['org.acme:ext-a:0.1.0', 'org.acme:ext-b:0.1.0']" + "}"; @@ -108,7 +109,7 @@ public void shouldContainsConditionalDependencies() throws IOException { @Test public void shouldContainsParentFirstArtifacts() throws IOException { - String buildFileContent = TestUtils.getDefaultGradleBuildFileContent() + String buildFileContent = TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList()) + QuarkusExtensionPlugin.EXTENSION_CONFIGURATION_NAME + " { " + "parentFirstArtifacts = ['org.acme:ext-a:0.1.0', 'org.acme:ext-b:0.1.0']" + "}"; @@ -125,7 +126,7 @@ public void shouldContainsParentFirstArtifacts() throws IOException { @Test public void shouldGenerateDescriptorBasedOnExistingFile() throws IOException { - TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent()); + TestUtils.writeFile(buildFile, TestUtils.getDefaultGradleBuildFileContent(true, Collections.emptyList())); File metaInfDir = new File(testProjectDir, "src/main/resources/META-INF"); metaInfDir.mkdirs(); String description = "name: extension-name\n" + diff --git a/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTaskTest.java b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTaskTest.java new file mode 100644 index 0000000000000..54dee849a0c35 --- /dev/null +++ b/devtools/gradle/gradle-extension-plugin/src/test/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTaskTest.java @@ -0,0 +1,89 @@ +package io.quarkus.extension.gradle.tasks; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.gradle.testkit.runner.TaskOutcome; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import io.quarkus.extension.gradle.QuarkusExtensionPlugin; +import io.quarkus.extension.gradle.TestUtils; + +public class ValidateExtensionTaskTest { + + @TempDir + File testProjectDir; + + @Test + public void shouldValidateExtensionDependencies() throws IOException { + TestUtils.createExtensionProject(testProjectDir, false, List.of("io.quarkus:quarkus-core"), + List.of("io.quarkus:quarkus-core-deployment")); + + BuildResult validationResult = GradleRunner.create() + .withPluginClasspath() + .withProjectDir(testProjectDir) + .withArguments(QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME) + .build(); + + assertThat(validationResult.task(":runtime:" + QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME).getOutcome()) + .isEqualTo(TaskOutcome.SUCCESS); + } + + @Test + public void shouldDetectMissionExtensionDependency() throws IOException { + TestUtils.createExtensionProject(testProjectDir, false, List.of("io.quarkus:quarkus-jdbc-h2"), List.of()); + + BuildResult validationResult = GradleRunner.create() + .withPluginClasspath() + .withProjectDir(testProjectDir) + .withArguments(QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME) + .buildAndFail(); + + assertThat(validationResult.task(":runtime:" + QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME).getOutcome()) + .isEqualTo(TaskOutcome.FAILED); + assertThat(validationResult.getOutput()).contains("Quarkus Extension Dependency Verification Error"); + assertThat(validationResult.getOutput()) + .contains("The following deployment artifact(s) were found to be missing in the deployment module:"); + assertThat(validationResult.getOutput()).contains("- io.quarkus:quarkus-jdbc-h2-deployment"); + } + + @Test + public void shouldDetectInvalidRuntimeDependency() throws IOException { + TestUtils.createExtensionProject(testProjectDir, false, + List.of("io.quarkus:quarkus-core", "io.quarkus:quarkus-core-deployment"), List.of()); + + BuildResult validationResult = GradleRunner.create() + .withPluginClasspath() + .withProjectDir(testProjectDir) + .withArguments(QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME) + .buildAndFail(); + + assertThat(validationResult.task(":runtime:" + QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME).getOutcome()) + .isEqualTo(TaskOutcome.FAILED); + assertThat(validationResult.getOutput()).contains("Quarkus Extension Dependency Verification Error"); + assertThat(validationResult.getOutput()) + .contains("The following deployment artifact(s) appear on the runtime classpath:"); + assertThat(validationResult.getOutput()).contains("- io.quarkus:quarkus-core-deployment"); + } + + @Test + public void shouldSkipValidationWhenDisabled() throws IOException { + TestUtils.createExtensionProject(testProjectDir, true, + List.of("io.quarkus:quarkus-core", "io.quarkus:quarkus-core-deployment"), List.of()); + + BuildResult validationResult = GradleRunner.create() + .withPluginClasspath() + .withProjectDir(testProjectDir) + .withArguments(QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME) + .build(); + + assertThat(validationResult.task(":runtime:" + QuarkusExtensionPlugin.VALIDATE_EXTENSION_TASK_NAME).getOutcome()) + .isEqualTo(TaskOutcome.SKIPPED); + } +} diff --git a/integration-tests/gradle/src/main/resources/conditional-dependencies/ext-a/deployment/build.gradle b/integration-tests/gradle/src/main/resources/conditional-dependencies/ext-a/deployment/build.gradle index 820932bef4a2a..bad52ad640978 100644 --- a/integration-tests/gradle/src/main/resources/conditional-dependencies/ext-a/deployment/build.gradle +++ b/integration-tests/gradle/src/main/resources/conditional-dependencies/ext-a/deployment/build.gradle @@ -8,6 +8,10 @@ dependencies { implementation 'io.quarkus:quarkus-core-deployment' implementation("org.acme:simple-dependency:1.0-SNAPSHOT") + implementation("io.quarkus:quarkus-hibernate-reactive-panache-deployment") + implementation("io.quarkus:quarkus-agroal-deployment") + implementation("io.quarkus:quarkus-narayana-jta-deployment") + implementation project(':ext-a:runtime') }