From 379fa10cfbd2befc8e2c0a62953ca070c3557af7 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 13 Sep 2024 10:45:16 +0200 Subject: [PATCH] Revert "Configuration cache compatibility for QuarkusGenerateCode and partial QuarkusBuildTask" This reverts commit b542785c9125a85d64e5ef75c95f6d198c896a7c. (cherry picked from commit 1710bbd67274df95fef384368da3a757973c0140) --- .../build.gradle.kts | 2 +- .../java/io/quarkus/gradle/QuarkusPlugin.java | 133 +--- .../extension/QuarkusPluginExtension.java | 9 - .../tasks/AbstractQuarkusExtension.java | 6 +- .../java/io/quarkus/gradle/tasks/Deploy.java | 2 +- .../io/quarkus/gradle/tasks/ImageTask.java | 2 +- .../tasks/QuarkusApplicationModelTask.java | 614 ------------------ .../io/quarkus/gradle/tasks/QuarkusBuild.java | 12 +- .../tasks/QuarkusBuildCacheableAppParts.java | 2 +- .../tasks/QuarkusBuildDependencies.java | 5 +- .../gradle/tasks/QuarkusBuildTask.java | 84 +-- .../gradle/tasks/QuarkusGenerateCode.java | 44 +- .../tasks/QuarkusPluginExtensionView.java | 312 --------- .../io/quarkus/gradle/tasks/QuarkusRun.java | 2 +- .../tasks/QuarkusShowEffectiveConfig.java | 10 +- .../io/quarkus/gradle/tasks/QuarkusTask.java | 13 +- .../descriptors/DefaultProjectDescriptor.java | 97 --- .../descriptors/ProjectDescriptor.java | 27 - .../descriptors/ProjectDescriptorBuilder.java | 143 ---- .../descriptors/QuarkusTaskDescriptor.java | 49 -- ...ksConfigurationCacheCompatibilityTest.java | 149 ----- .../configurationcache/main/build.gradle.kts | 31 - .../main/settings.gradle.kts | 1 - .../main/src/main/java/org/acme/Foo.java | 4 - ...ApplicationDeploymentClasspathBuilder.java | 32 +- .../GradleApplicationModelBuilder.java | 4 +- .../quarkus/gradle/tooling/ToolingUtils.java | 16 - docs/src/main/asciidoc/gradle-tooling.adoc | 30 +- .../application-files/build.gradle | 4 +- .../nativeimage/BasicJavaNativeBuildIT.java | 3 - 30 files changed, 95 insertions(+), 1747 deletions(-) delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusApplicationModelTask.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPluginExtensionView.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/DefaultProjectDescriptor.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptor.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptorBuilder.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/QuarkusTaskDescriptor.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/TasksConfigurationCacheCompatibilityTest.java delete mode 100644 devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/build.gradle.kts delete mode 100644 devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/settings.gradle.kts delete mode 100644 devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/src/main/java/org/acme/Foo.java diff --git a/devtools/gradle/gradle-application-plugin/build.gradle.kts b/devtools/gradle/gradle-application-plugin/build.gradle.kts index ba31d1989f3c3..3b14b942c8e01 100644 --- a/devtools/gradle/gradle-application-plugin/build.gradle.kts +++ b/devtools/gradle/gradle-application-plugin/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { implementation(libs.smallrye.config.yaml) implementation("io.quarkus:quarkus-analytics-common") - compileOnly(libs.kotlin.gradle.plugin.api) + testImplementation(libs.quarkus.project.core.extension.codestarts) } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java index fa3a5ba77b67b..b7fd4dcbf3802 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java @@ -1,10 +1,7 @@ package io.quarkus.gradle; -import static io.quarkus.gradle.tasks.QuarkusGradleUtils.getSourceSet; - import java.io.File; import java.nio.file.Path; -import java.util.Collections; import java.util.HashSet; import java.util.Optional; import java.util.Set; @@ -27,7 +24,6 @@ import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.Property; -import org.gradle.api.provider.Provider; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; @@ -45,14 +41,13 @@ import io.quarkus.gradle.tasks.ImageBuild; import io.quarkus.gradle.tasks.ImagePush; import io.quarkus.gradle.tasks.QuarkusAddExtension; -import io.quarkus.gradle.tasks.QuarkusApplicationModelTask; import io.quarkus.gradle.tasks.QuarkusBuild; import io.quarkus.gradle.tasks.QuarkusBuildCacheableAppParts; import io.quarkus.gradle.tasks.QuarkusBuildDependencies; -import io.quarkus.gradle.tasks.QuarkusBuildTask; import io.quarkus.gradle.tasks.QuarkusDev; import io.quarkus.gradle.tasks.QuarkusGenerateCode; import io.quarkus.gradle.tasks.QuarkusGoOffline; +import io.quarkus.gradle.tasks.QuarkusGradleUtils; import io.quarkus.gradle.tasks.QuarkusInfo; import io.quarkus.gradle.tasks.QuarkusListCategories; import io.quarkus.gradle.tasks.QuarkusListExtensions; @@ -69,8 +64,6 @@ import io.quarkus.gradle.tooling.dependency.DependencyUtils; import io.quarkus.gradle.tooling.dependency.ExtensionDependency; import io.quarkus.gradle.tooling.dependency.ProjectExtensionDependency; -import io.quarkus.gradle.workspace.descriptors.DefaultProjectDescriptor; -import io.quarkus.gradle.workspace.descriptors.ProjectDescriptorBuilder; import io.quarkus.runtime.LaunchMode; public class QuarkusPlugin implements Plugin { @@ -170,86 +163,39 @@ private void registerTasks(Project project, QuarkusPluginExtension quarkusExt) { .getByName(ApplicationDeploymentClasspathBuilder.getBaseRuntimeConfigName(LaunchMode.DEVELOPMENT))); }); - Provider projectDescriptor = ProjectDescriptorBuilder.buildForApp(project); - ApplicationDeploymentClasspathBuilder normalClasspath = new ApplicationDeploymentClasspathBuilder(project, - LaunchMode.NORMAL); - ApplicationDeploymentClasspathBuilder testClasspath = new ApplicationDeploymentClasspathBuilder(project, - LaunchMode.TEST); - ApplicationDeploymentClasspathBuilder devClasspath = new ApplicationDeploymentClasspathBuilder(project, - LaunchMode.DEVELOPMENT); - - TaskProvider quarkusGenerateTestAppModelTask = tasks.register( - "quarkusGenerateTestAppModel", - QuarkusApplicationModelTask.class, task -> { - configureApplicationModelTask(project, task, projectDescriptor, testClasspath, LaunchMode.TEST, - "quarkus/application-model/quarkus-app-test-model.dat"); - }); - TaskProvider quarkusGenerateDevAppModelTask = tasks.register("quarkusGenerateDevAppModel", - QuarkusApplicationModelTask.class, task -> { - configureApplicationModelTask(project, task, projectDescriptor, devClasspath, LaunchMode.DEVELOPMENT, - "quarkus/application-model/quarkus-app-dev-model.dat"); - }); - - TaskProvider quarkusGenerateAppModelTask = tasks.register("quarkusGenerateAppModel", - QuarkusApplicationModelTask.class, task -> { - configureApplicationModelTask(project, task, projectDescriptor - .map(d -> d.withSourceSetView(Collections.singleton(SourceSet.MAIN_SOURCE_SET_NAME))), - normalClasspath, LaunchMode.NORMAL, - "quarkus/application-model/quarkus-app-model.dat"); - }); - // quarkusGenerateCode TaskProvider quarkusGenerateCode = tasks.register(QUARKUS_GENERATE_CODE_TASK_NAME, QuarkusGenerateCode.class, LaunchMode.NORMAL, SourceSet.MAIN_SOURCE_SET_NAME); - quarkusGenerateCode.configure(task -> configureGenerateCodeTask(task, quarkusGenerateAppModelTask, - QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES)); + quarkusGenerateCode.configure(task -> configureGenerateCodeTask(task, QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES)); // quarkusGenerateCodeDev TaskProvider quarkusGenerateCodeDev = tasks.register(QUARKUS_GENERATE_CODE_DEV_TASK_NAME, QuarkusGenerateCode.class, LaunchMode.DEVELOPMENT, SourceSet.MAIN_SOURCE_SET_NAME); quarkusGenerateCodeDev.configure(task -> { task.dependsOn(quarkusGenerateCode); - configureGenerateCodeTask(task, quarkusGenerateDevAppModelTask, QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES); + configureGenerateCodeTask(task, QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES); }); // quarkusGenerateCodeTests TaskProvider quarkusGenerateCodeTests = tasks.register(QUARKUS_GENERATE_CODE_TESTS_TASK_NAME, QuarkusGenerateCode.class, LaunchMode.TEST, SourceSet.TEST_SOURCE_SET_NAME); quarkusGenerateCodeTests.configure(task -> { task.dependsOn("compileQuarkusTestGeneratedSourcesJava"); - configureGenerateCodeTask(task, quarkusGenerateTestAppModelTask, - QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES); + configureGenerateCodeTask(task, QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES); }); - TaskProvider quarkusBuildAppModelTask = tasks.register("quarkusBuildAppModel", - QuarkusApplicationModelTask.class, task -> { - task.dependsOn(tasks.named(JavaPlugin.CLASSES_TASK_NAME)); - configureApplicationModelTask(project, task, projectDescriptor - .map(d -> d.withSourceSetView(Collections.singleton(SourceSet.MAIN_SOURCE_SET_NAME))), - normalClasspath, LaunchMode.NORMAL, - "quarkus/application-model/quarkus-app-model-build.dat"); - }); tasks.register(QUARKUS_SHOW_EFFECTIVE_CONFIG_TASK_NAME, QuarkusShowEffectiveConfig.class, task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); task.setDescription("Show effective Quarkus build configuration."); }); TaskProvider quarkusBuildDependencies = tasks.register(QUARKUS_BUILD_DEP_TASK_NAME, QuarkusBuildDependencies.class, - task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); - - task.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true); - task.getApplicationModel() - .set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - - }); + task -> task.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true)); Property cacheLargeArtifacts = quarkusExt.getCacheLargeArtifacts(); TaskProvider quarkusBuildCacheableAppParts = tasks.register( QUARKUS_BUILD_APP_PARTS_TASK_NAME, QuarkusBuildCacheableAppParts.class, task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); task.dependsOn(quarkusGenerateCode); task.getOutputs().doNotCacheIf( "Not adding uber-jars, native binaries and mutable-jar package type to Gradle " + @@ -265,7 +211,6 @@ public boolean isSatisfiedBy(Task t) { }); TaskProvider quarkusBuild = tasks.register(QUARKUS_BUILD_TASK_NAME, QuarkusBuild.class, build -> { - configureQuarkusBuildTask(project, quarkusExt, build, quarkusBuildAppModelTask); build.dependsOn(quarkusBuildDependencies, quarkusBuildCacheableAppParts); build.getOutputs().doNotCacheIf( "Only collects and combines the outputs of " + QUARKUS_BUILD_APP_PARTS_TASK_NAME + " and " @@ -279,41 +224,16 @@ public boolean isSatisfiedBy(Task t) { }); }); - tasks.register(IMAGE_BUILD_TASK_NAME, ImageBuild.class, task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); - task.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true); - task.getApplicationModel() - .set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - task.finalizedBy(quarkusBuild); - }); + tasks.register(IMAGE_BUILD_TASK_NAME, ImageBuild.class, task -> task.finalizedBy(quarkusBuild)); - tasks.register(IMAGE_PUSH_TASK_NAME, ImagePush.class, task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); - task.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true); - task.getApplicationModel() - .set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - task.finalizedBy(quarkusBuild); - }); + tasks.register(IMAGE_PUSH_TASK_NAME, ImagePush.class, task -> task.finalizedBy(quarkusBuild)); - tasks.register(DEPLOY_TASK_NAME, Deploy.class, task -> { - configureQuarkusBuildTask(project, quarkusExt, task, quarkusBuildAppModelTask); - task.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true); - task.getApplicationModel() - .set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - task.finalizedBy(quarkusBuild); - }); + tasks.register(DEPLOY_TASK_NAME, Deploy.class, task -> task.finalizedBy(quarkusBuild)); TaskProvider quarkusDev = tasks.register(QUARKUS_DEV_TASK_NAME, QuarkusDev.class, devRuntimeDependencies, quarkusExt); TaskProvider quarkusRun = tasks.register(QUARKUS_RUN_TASK_NAME, QuarkusRun.class, - build -> { - configureQuarkusBuildTask(project, quarkusExt, build, quarkusBuildAppModelTask); - build.getOutputs().doNotCacheIf("Dependencies are never cached", t -> true); - build.getApplicationModel() - .set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - build.dependsOn(quarkusBuild); - - }); + build -> build.dependsOn(quarkusBuild)); TaskProvider quarkusRemoteDev = tasks.register(QUARKUS_REMOTE_DEV_TASK_NAME, QuarkusRemoteDev.class, devRuntimeDependencies, quarkusExt); TaskProvider quarkusTest = tasks.register(QUARKUS_TEST_TASK_NAME, QuarkusTest.class, @@ -493,43 +413,14 @@ public void execute(Task task) { }); } - private static void configureApplicationModelTask(Project project, QuarkusApplicationModelTask task, - Provider projectDescriptor, - ApplicationDeploymentClasspathBuilder classpath, - LaunchMode launchMode, String quarkusModelFile) { - task.getProjectDescriptor().set(projectDescriptor); - task.getLaunchMode().set(launchMode); - task.getOriginalClasspath().setFrom(classpath.getOriginalRuntimeClasspathAsInput()); - task.getAppClasspath().configureFrom(classpath.getRuntimeConfiguration()); - task.getPlatformConfiguration().configureFrom(classpath.getPlatformConfiguration()); - task.getDeploymentClasspath().configureFrom(classpath.getDeploymentConfiguration()); - task.getPlatformImportProperties().set(classpath.getPlatformImports().getPlatformProperties()); - task.getApplicationModel().set( - project.getLayout().getBuildDirectory() - .file(quarkusModelFile)); - - } - - private static void configureQuarkusBuildTask(Project project, QuarkusPluginExtension quarkusExt, QuarkusBuildTask task, - TaskProvider quarkusGenerateAppModelTask) { - task.getApplicationModel().set(quarkusGenerateAppModelTask.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - SourceSet mainSourceSet = getSourceSet(project, SourceSet.MAIN_SOURCE_SET_NAME); - task.setCompileClasspath(mainSourceSet.getCompileClasspath().plus(mainSourceSet.getRuntimeClasspath()) - .plus(mainSourceSet.getAnnotationProcessorPath()) - .plus(mainSourceSet.getResources())); - } - - private static void configureGenerateCodeTask(QuarkusGenerateCode task, - TaskProvider applicationModelTaskTaskProvider, String generateSourcesDir) { - SourceSet generatedSources = getSourceSet(task.getProject(), generateSourcesDir); + private static void configureGenerateCodeTask(QuarkusGenerateCode task, String generateSourcesDir) { + SourceSet generatedSources = QuarkusGradleUtils.getSourceSet(task.getProject(), generateSourcesDir); Set sourceSetOutput = generatedSources.getOutput().filter(f -> f.getName().equals(generateSourcesDir)).getFiles(); if (sourceSetOutput.isEmpty()) { throw new GradleException("Failed to configure " + task.getPath() + ": sourceSet " + generateSourcesDir + " has no output"); } - task.getApplicationModel() - .set(applicationModelTaskTaskProvider.flatMap(QuarkusApplicationModelTask::getApplicationModel)); - task.getGeneratedOutputDirectory().set(generatedSources.getJava().getClassesDirectory()); + task.getGeneratedOutputDirectory().set(generatedSources.getJava().getClassesDirectory().get().getAsFile()); } private void createSourceSets(Project project) { diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java index 7e45c652dbcf4..c4c543fee145b 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/extension/QuarkusPluginExtension.java @@ -16,7 +16,6 @@ import org.gradle.api.Action; import org.gradle.api.Project; -import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; import org.gradle.api.file.RegularFile; import org.gradle.api.plugins.JavaPlugin; @@ -166,14 +165,6 @@ public Set resourcesDir() { return getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getResources().getSrcDirs(); } - public static FileCollection combinedOutputSourceDirs(Project project) { - ConfigurableFileCollection classesDirs = project.files(); - SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class); - classesDirs.from(sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput().getClassesDirs()); - classesDirs.from(sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME).getOutput().getClassesDirs()); - return classesDirs; - } - public Set combinedOutputSourceDirs() { Set sourcesDirs = new LinkedHashSet<>(); SourceSetContainer sourceSets = getSourceSets(); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/AbstractQuarkusExtension.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/AbstractQuarkusExtension.java index 58976d97f65a9..47cd0e461a9b8 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/AbstractQuarkusExtension.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/AbstractQuarkusExtension.java @@ -39,7 +39,7 @@ public abstract class AbstractQuarkusExtension { private static final String MANIFEST_SECTIONS_PROPERTY_PREFIX = "quarkus.package.jar.manifest.sections"; private static final String MANIFEST_ATTRIBUTES_PROPERTY_PREFIX = "quarkus.package.jar.manifest.attributes"; - protected static final String QUARKUS_PROFILE = "quarkus.profile"; + private static final String QUARKUS_PROFILE = "quarkus.profile"; protected final Project project; protected final File projectDir; protected final Property finalName; @@ -249,14 +249,14 @@ private void exportCustomManifestProperties(Map properties) { } } - protected static String toManifestAttributeKey(String key) { + private String toManifestAttributeKey(String key) { if (key.contains("\"")) { throw new GradleException("Manifest entry name " + key + " is invalid. \" characters are not allowed."); } return String.format("%s.\"%s\"", MANIFEST_ATTRIBUTES_PROPERTY_PREFIX, key); } - protected static String toManifestSectionAttributeKey(String section, String key) { + private String toManifestSectionAttributeKey(String section, String key) { if (section.contains("\"")) { throw new GradleException("Manifest section name " + section + " is invalid. \" characters are not allowed."); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/Deploy.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/Deploy.java index 4833c5be53da2..d5b13e65e4a06 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/Deploy.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/Deploy.java @@ -84,7 +84,7 @@ public void setImageBuilder(String imageBuilder) { @Inject public Deploy() { - super("Deploy", false); + super("Deploy"); } @TaskAction diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/ImageTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/ImageTask.java index f4b44c8f9e8dc..e946fad553f3e 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/ImageTask.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/ImageTask.java @@ -39,7 +39,7 @@ enum Builder { } public ImageTask(String description) { - super(description, false); + super(description); } public Builder builder() { diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusApplicationModelTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusApplicationModelTask.java deleted file mode 100644 index 3fc1afa5533e1..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusApplicationModelTask.java +++ /dev/null @@ -1,614 +0,0 @@ -package io.quarkus.gradle.tasks; - -import static io.quarkus.gradle.tooling.GradleApplicationModelBuilder.clearFlag; -import static io.quarkus.gradle.tooling.GradleApplicationModelBuilder.isFlagOn; -import static io.quarkus.maven.dependency.ArtifactCoords.DEFAULT_CLASSIFIER; -import static java.util.stream.Collectors.toList; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.io.UncheckedIOException; -import java.nio.file.FileSystem; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import javax.inject.Inject; - -import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; -import org.gradle.api.artifacts.ArtifactCollection; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ModuleVersionIdentifier; -import org.gradle.api.artifacts.ResolvableDependencies; -import org.gradle.api.artifacts.component.ComponentArtifactIdentifier; -import org.gradle.api.artifacts.component.ComponentIdentifier; -import org.gradle.api.artifacts.component.ProjectComponentIdentifier; -import org.gradle.api.artifacts.result.DependencyResult; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; -import org.gradle.api.artifacts.result.ResolvedComponentResult; -import org.gradle.api.artifacts.result.ResolvedDependencyResult; -import org.gradle.api.artifacts.type.ArtifactTypeDefinition; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.file.FileCollection; -import org.gradle.api.file.ProjectLayout; -import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.provider.MapProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.tasks.CompileClasspath; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.Internal; -import org.gradle.api.tasks.Nested; -import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.TaskAction; - -import com.google.common.base.Preconditions; - -import io.quarkus.bootstrap.BootstrapConstants; -import io.quarkus.bootstrap.model.ApplicationModelBuilder; -import io.quarkus.bootstrap.model.CapabilityContract; -import io.quarkus.bootstrap.model.PlatformImportsImpl; -import io.quarkus.bootstrap.resolver.AppModelResolverException; -import io.quarkus.bootstrap.workspace.ArtifactSources; -import io.quarkus.bootstrap.workspace.DefaultArtifactSources; -import io.quarkus.bootstrap.workspace.DefaultSourceDir; -import io.quarkus.bootstrap.workspace.SourceDir; -import io.quarkus.bootstrap.workspace.WorkspaceModule; -import io.quarkus.fs.util.ZipUtils; -import io.quarkus.gradle.tooling.ToolingUtils; -import io.quarkus.gradle.workspace.descriptors.DefaultProjectDescriptor; -import io.quarkus.gradle.workspace.descriptors.ProjectDescriptor; -import io.quarkus.gradle.workspace.descriptors.ProjectDescriptor.TaskType; -import io.quarkus.maven.dependency.ArtifactCoords; -import io.quarkus.maven.dependency.ArtifactDependency; -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.maven.dependency.DependencyFlags; -import io.quarkus.maven.dependency.GACT; -import io.quarkus.maven.dependency.GACTV; -import io.quarkus.maven.dependency.GAV; -import io.quarkus.maven.dependency.ResolvedDependencyBuilder; -import io.quarkus.paths.PathCollection; -import io.quarkus.paths.PathList; -import io.quarkus.runtime.LaunchMode; -import io.quarkus.runtime.util.HashUtil; - -public abstract class QuarkusApplicationModelTask extends DefaultTask { - - /* @formatter:off */ - private static final byte COLLECT_TOP_EXTENSION_RUNTIME_NODES = 0b001; - private static final byte COLLECT_DIRECT_DEPS = 0b010; - private static final byte COLLECT_RELOADABLE_MODULES = 0b100; - /* @formatter:on */ - - public static final String QUARKUS_PROJECT_DESCRIPTOR_ARTIFACT_TYPE = "quarkus-project-descriptor"; - - @Internal - public abstract RegularFileProperty getProjectBuildFile(); - - @Inject - public abstract ProjectLayout getLayout(); - - /** - * Used just to track original classpath as an input, since resolving quarkus classpath is kinda expensive, - * and we don't want to do that if task is up-to-date - */ - @CompileClasspath - public abstract ConfigurableFileCollection getOriginalClasspath(); - - @Nested - public abstract QuarkusResolvedClasspath getPlatformConfiguration(); - - @Nested - public abstract QuarkusResolvedClasspath getAppClasspath(); - - @Nested - public abstract QuarkusResolvedClasspath getDeploymentClasspath(); - - @Input - public abstract Property getLaunchMode(); - - @Input - public abstract MapProperty getPlatformImportProperties(); - - /** - * If any project task changes, we will invalidate this task anyway - */ - @Input - public abstract Property getProjectDescriptor(); - - @OutputFile - public abstract RegularFileProperty getApplicationModel(); - - public QuarkusApplicationModelTask() { - getProjectBuildFile().set(getProject().getBuildFile()); - } - - private void collectPlatforms(ResolvedDependencyResult resolvedDependency, - Map> artifactsByCapability, - PlatformImportsImpl platformImports) { - List artifacts = findArtifacts(resolvedDependency, artifactsByCapability); - ModuleVersionIdentifier moduleVersionIdentifier = resolvedDependency.getSelected().getModuleVersion(); - for (QuarkusResolvedArtifact artifact : artifacts) { - if (artifact != null && artifact.file.getName().endsWith(".properties")) { - try { - platformImports.addPlatformProperties(moduleVersionIdentifier.getGroup(), moduleVersionIdentifier.getName(), - null, "properties", moduleVersionIdentifier.getVersion(), artifact.file.toPath()); - } catch (AppModelResolverException e) { - throw new GradleException("Failed to import platform properties " + artifact.file, e); - } - } else if (artifact != null && artifact.file.getName().endsWith(".json")) { - platformImports.addPlatformDescriptor(moduleVersionIdentifier.getGroup(), moduleVersionIdentifier.getName(), - moduleVersionIdentifier.getVersion(), "json", moduleVersionIdentifier.getVersion()); - } - } - } - - @TaskAction - public void execute() throws IOException { - final ResolvedDependencyBuilder appArtifact = getProjectArtifact(); - PlatformImportsImpl platformImports = new PlatformImportsImpl(); - platformImports.setPlatformProperties(getPlatformImportProperties().get()); - Map> artifactsByCapability = getPlatformConfiguration() - .resolvedArtifactsByComponentIdentifier(); - getPlatformConfiguration().getRoot().get().getDependencies().forEach(d -> { - if (d instanceof ResolvedDependencyResult) { - collectPlatforms((ResolvedDependencyResult) d, artifactsByCapability, platformImports); - } - }); - final ApplicationModelBuilder modelBuilder = new ApplicationModelBuilder() - .setAppArtifact(appArtifact) - .setPlatformImports(platformImports) - .addReloadableWorkspaceModule(appArtifact.getKey()); - - collectDependencies(getAppClasspath(), modelBuilder, appArtifact.getWorkspaceModule().mutable()); - collectExtensionDependencies(getDeploymentClasspath(), modelBuilder); - ToolingUtils.serializeAppModel(modelBuilder.build(), getApplicationModel().get().getAsFile().toPath()); - } - - private ResolvedDependencyBuilder getProjectArtifact() { - ModuleVersionIdentifier moduleVersion = getAppClasspath().getRoot().get().getModuleVersion(); - ResolvedDependencyBuilder appArtifact = ResolvedDependencyBuilder.newInstance() - .setGroupId(moduleVersion.getGroup()) - .setArtifactId(moduleVersion.getName()) - .setVersion(moduleVersion.getVersion()); - - WorkspaceModule.Mutable mainModule = WorkspaceModule.builder() - .setModuleId(new GAV(appArtifact.getGroupId(), appArtifact.getArtifactId(), appArtifact.getVersion())) - .setModuleDir(getLayout().getProjectDirectory().getAsFile().toPath()) - .setBuildDir(getLayout().getBuildDirectory().getAsFile().get().toPath()) - .setBuildFile(getProjectBuildFile().getAsFile().get().toPath()); - - ProjectDescriptor projectDescriptor = getProjectDescriptor().get(); - initProjectModule(projectDescriptor, mainModule, ArtifactSources.MAIN, DEFAULT_CLASSIFIER); - if (getLaunchMode().get().isDevOrTest()) { - initProjectModule(projectDescriptor, mainModule, ArtifactSources.TEST, "tests"); - } - final PathList.Builder paths = PathList.builder(); - collectDestinationDirs(mainModule.getMainSources().getSourceDirs(), paths); - collectDestinationDirs(mainModule.getMainSources().getResourceDirs(), paths); - - return appArtifact.setWorkspaceModule(mainModule).setResolvedPaths(paths.build()); - } - - private static void initProjectModule(ProjectDescriptor projectDescriptor, WorkspaceModule.Mutable module, - String sourceSetName, String classifier) { - List sourceDirs = new ArrayList<>(); - List resources = new ArrayList<>(); - Set tasks = projectDescriptor.getTasksForSourceSet(sourceSetName.isEmpty() - ? SourceSet.MAIN_SOURCE_SET_NAME - : sourceSetName.equals("tests") ? SourceSet.TEST_SOURCE_SET_NAME : sourceSetName); - for (String task : tasks) { - TaskType type = projectDescriptor.getTaskType(task); - Path source = Path.of(projectDescriptor.getTaskSource(task)); - Path destDir = Path.of(projectDescriptor.getTaskDestinationDir(task)); - if (type == TaskType.COMPILE) { - sourceDirs.add(new DefaultSourceDir(source, destDir, null, Map.of("compiler", task))); - } else if (type == TaskType.RESOURCES) { - resources.add(new DefaultSourceDir(source, destDir, null)); - } - } - module.addArtifactSources(new DefaultArtifactSources(classifier, sourceDirs, resources)); - } - - private static void collectDestinationDirs(Collection sources, final PathList.Builder paths) { - for (SourceDir src : sources) { - final Path path = src.getOutputDir(); - if (paths.contains(path) || !Files.exists(path)) { - continue; - } - paths.add(path); - } - } - - private static void collectDependencies(QuarkusResolvedClasspath classpath, ApplicationModelBuilder modelBuilder, - WorkspaceModule.Mutable wsModule) { - Map> artifacts = classpath.resolvedArtifactsByComponentIdentifier(); - - Set alreadyCollectedFiles = new HashSet<>(artifacts.size()); - classpath.getRoot().get().getDependencies().forEach(d -> { - if (d instanceof ResolvedDependencyResult) { - byte flags = (byte) (COLLECT_TOP_EXTENSION_RUNTIME_NODES | COLLECT_DIRECT_DEPS | COLLECT_RELOADABLE_MODULES); - collectDependencies((ResolvedDependencyResult) d, modelBuilder, artifacts, wsModule, alreadyCollectedFiles, - new HashSet<>(), flags); - } - }); - Set fileDependencies = new HashSet<>(classpath.getAllResolvedFiles().getFiles()); - - fileDependencies.removeAll(alreadyCollectedFiles); - fileDependenciesExtractor(modelBuilder, fileDependencies); - } - - private static void fileDependenciesExtractor(ApplicationModelBuilder modelBuilder, Set fileDependencies) { - // detect FS paths that are direct file dependencies and are not part of resolution graph - for (File f : fileDependencies) { - if (!f.exists()) { - continue; - } - // here we are trying to represent a direct FS path dependency - // as an artifact dependency - // SHA1 hash is used to avoid long file names in the lib dir - final String parentPath = f.getParent(); - final String group = HashUtil.sha1(parentPath == null ? f.getName() : parentPath); - String name = f.getName(); - String type = ArtifactCoords.TYPE_JAR; - if (!f.isDirectory()) { - final int dot = f.getName().lastIndexOf('.'); - if (dot > 0) { - name = f.getName().substring(0, dot); - type = f.getName().substring(dot + 1); - } - } - // hash could be a better way to represent the version - final String version = String.valueOf(f.lastModified()); - final ResolvedDependencyBuilder artifactBuilder = ResolvedDependencyBuilder.newInstance() - .setGroupId(group) - .setArtifactId(name) - .setType(type) - .setVersion(version) - .setResolvedPath(f.toPath()) - .setDirect(true) - .setRuntimeCp() - .setDeploymentCp(); - Utils.processQuarkusDependency(artifactBuilder, modelBuilder); - modelBuilder.addDependency(artifactBuilder); - } - } - - private static void collectDependencies( - ResolvedDependencyResult resolvedDependency, - ApplicationModelBuilder modelBuilder, - Map> resolvedArtifacts, - WorkspaceModule.Mutable parentModule, - Set collectedArtifactFiles, - Set processedModules, - byte flags) { - WorkspaceModule.Mutable projectModule = null; - List artifacts = findArtifacts(resolvedDependency, resolvedArtifacts); - if (artifacts.isEmpty()) { - byte finalFlags = flags; - resolvedDependency.getSelected().getDependencies().forEach((Consumer) dependencyResult -> { - if (dependencyResult instanceof ResolvedDependencyResult) { - ModuleVersionIdentifier dependencyId = Preconditions - .checkNotNull(((ResolvedDependencyResult) dependencyResult).getSelected().getModuleVersion()); - if (!processedModules.contains(new GACT(dependencyId.getGroup(), dependencyId.getName()))) { - collectDependencies((ResolvedDependencyResult) dependencyResult, modelBuilder, resolvedArtifacts, - projectModule, - collectedArtifactFiles, - processedModules, finalFlags); - } - } - }); - return; - } - - ModuleVersionIdentifier moduleVersionIdentifier = Preconditions - .checkNotNull(resolvedDependency.getSelected().getModuleVersion()); - - for (QuarkusResolvedArtifact artifact : artifacts) { - String classifier = resolveClassifier(moduleVersionIdentifier, artifact.file); - ArtifactKey artifactKey = new GACT( - moduleVersionIdentifier.getGroup(), - moduleVersionIdentifier.getName(), - classifier, - artifact.type); - if (!isDependency(artifact) || modelBuilder.getDependency(artifactKey) != null) { - continue; - } - - final ArtifactCoords depCoords = new GACTV(artifactKey, moduleVersionIdentifier.getVersion()); - ResolvedDependencyBuilder depBuilder = ResolvedDependencyBuilder.newInstance() - .setCoords(depCoords) - .setRuntimeCp() - .setDeploymentCp(); - if (isFlagOn(flags, COLLECT_DIRECT_DEPS)) { - depBuilder.setDirect(true); - flags = clearFlag(flags, COLLECT_DIRECT_DEPS); - } - if (parentModule != null) { - parentModule.addDependency(new ArtifactDependency(depCoords)); - } - - PathCollection paths = null; - - depBuilder.setResolvedPaths(paths == null ? PathList.of(artifact.file.toPath()) : paths) - .setWorkspaceModule(projectModule); - if (Utils.processQuarkusDependency(depBuilder, modelBuilder)) { - if (isFlagOn(flags, COLLECT_TOP_EXTENSION_RUNTIME_NODES)) { - depBuilder.setFlags(DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT); - flags = clearFlag(flags, COLLECT_TOP_EXTENSION_RUNTIME_NODES); - } - flags = clearFlag(flags, COLLECT_RELOADABLE_MODULES); - } - if (!isFlagOn(flags, COLLECT_RELOADABLE_MODULES)) { - depBuilder.clearFlag(DependencyFlags.RELOADABLE); - } - modelBuilder.addDependency(depBuilder); - collectedArtifactFiles.add(artifact.file); - } - - processedModules.add(ArtifactKey.ga(moduleVersionIdentifier.getGroup(), moduleVersionIdentifier.getName())); - for (DependencyResult dependency : resolvedDependency.getSelected().getDependencies()) { - if (dependency instanceof ResolvedDependencyResult) { - ModuleVersionIdentifier dependencyId = Preconditions - .checkNotNull(((ResolvedDependencyResult) dependency).getSelected().getModuleVersion()); - if (!processedModules.contains(new GACT(dependencyId.getGroup(), dependencyId.getName()))) { - collectDependencies((ResolvedDependencyResult) dependency, modelBuilder, resolvedArtifacts, projectModule, - collectedArtifactFiles, - processedModules, flags); - } - } - } - } - - private static boolean isDependency(QuarkusResolvedArtifact a) { - return a.file.getName().endsWith(ArtifactCoords.TYPE_JAR) - || a.file.getName().endsWith(".exe") - || a.file.isDirectory(); - } - - private static void collectExtensionDependencies(QuarkusResolvedClasspath classpath, ApplicationModelBuilder modelBuilder) { - Map> artifacts = classpath.resolvedArtifactsByComponentIdentifier(); - Set alreadyVisited = new HashSet<>(); - classpath.getRoot().get().getDependencies().forEach(d -> { - if (d instanceof ResolvedDependencyResult) { - collectExtensionDependencies((ResolvedDependencyResult) d, modelBuilder, artifacts, alreadyVisited); - } - }); - } - - private static void collectExtensionDependencies( - ResolvedDependencyResult resolvedDependency, - ApplicationModelBuilder modelBuilder, - Map> resolvedArtifacts, - Set alreadyVisited) { - List artifacts = findArtifacts(resolvedDependency, resolvedArtifacts); - if (artifacts.isEmpty()) { - return; - } - - for (QuarkusResolvedArtifact artifact : artifacts) { - ModuleVersionIdentifier moduleVersionIdentifier = Preconditions - .checkNotNull(resolvedDependency.getSelected().getModuleVersion()); - - String classifier = resolveClassifier(moduleVersionIdentifier, artifact.file); - ArtifactKey artifactKey = new GACT(moduleVersionIdentifier.getGroup(), moduleVersionIdentifier.getName(), - classifier, - artifact.type); - if (!alreadyVisited.add(artifactKey)) { - return; - } - - ResolvedDependencyBuilder dep = modelBuilder.getDependency(artifactKey); - if (dep == null) { - ArtifactCoords artifactCoords = new GACTV(artifactKey, moduleVersionIdentifier.getVersion()); - dep = toDependency(artifactCoords, artifact.file); - modelBuilder.addDependency(dep); - } - dep.setDeploymentCp(); - dep.clearFlag(DependencyFlags.RELOADABLE); - - } - resolvedDependency.getSelected().getDependencies().forEach(d -> { - if (d instanceof ResolvedDependencyResult) { - collectExtensionDependencies((ResolvedDependencyResult) d, modelBuilder, resolvedArtifacts, alreadyVisited); - } - }); - } - - private static List findArtifacts( - ResolvedDependencyResult resolvedDependency, - Map> artifacts) { - return artifacts.getOrDefault(resolvedDependency.getSelected().getId(), Collections.emptyList()); - } - - private static String resolveClassifier(ModuleVersionIdentifier moduleVersionIdentifier, File file) { - String artifactIdVersion = moduleVersionIdentifier.getVersion().isEmpty() - || "unspecified".equals(moduleVersionIdentifier.getVersion()) - ? moduleVersionIdentifier.getName() - : moduleVersionIdentifier.getName() + "-" + moduleVersionIdentifier.getVersion(); - if ((file.getName().endsWith(".jar") || file.getName().endsWith(".pom") || file.getName().endsWith(".exe")) - && file.getName().startsWith(artifactIdVersion + "-")) { - int extensionLength = file.getName().endsWith(".exe") ? 4 : 4; - return file.getName().substring(artifactIdVersion.length() + 1, file.getName().length() - extensionLength); - } - return ""; - } - - static ResolvedDependencyBuilder toDependency(ArtifactCoords artifactCoords, File file, int... flags) { - int allFlags = 0; - for (int f : flags) { - allFlags |= f; - } - PathList paths = PathList.of(file.toPath()); - return ResolvedDependencyBuilder.newInstance() - .setCoords(artifactCoords) - .setResolvedPaths(paths) - .setFlags(allFlags); - } - - /** - * See example https://docs.gradle.org/current/samples/sample_tasks_with_dependency_resolution_result_inputs.html, - * to better understand how this works. - */ - public static abstract class QuarkusResolvedClasspath { - - /** - * Internal since we track defined dependencies via {@link QuarkusApplicationModelTask#getOriginalClasspath} - */ - @Internal - public abstract Property getRoot(); - - /** - * Internal since we track defined dependencies via {@link QuarkusApplicationModelTask#getOriginalClasspath} - */ - @Internal - public abstract Property getResolvedArtifactCollection(); - - /** - * TODO: Remove me - */ - @Internal - public abstract ConfigurableFileCollection getProjectDescriptors(); - - private FileCollection getAllResolvedFiles() { - return getResolvedArtifactCollection().get().getArtifactFiles(); - } - - private Map> resolvedArtifactsByComponentIdentifier() { - return getQuarkusResolvedArtifacts().stream() - .collect(Collectors.groupingBy(artifact -> artifact.getId().getComponentIdentifier())); - } - - private List getQuarkusResolvedArtifacts() { - return getResolvedArtifactCollection().get().getArtifacts().stream() - .map(this::toResolvedArtifact) - .collect(toList()); - } - - private QuarkusResolvedArtifact toResolvedArtifact(ResolvedArtifactResult result) { - String type = result.getVariant().getAttributes().getAttribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE); - File file = result.getFile(); - return new QuarkusResolvedArtifact(result.getId(), file, type); - } - - public void configureFrom(Configuration configuration) { - ResolvableDependencies resolvableDependencies = configuration.getIncoming(); - getRoot().set(resolvableDependencies.getResolutionResult().getRootComponent()); - getResolvedArtifactCollection().set(resolvableDependencies.getArtifacts()); - // TODO: Remove me, since we don't apply workspace plugin anymore, so there are no project descriptors - getProjectDescriptors().setFrom(configuration.getIncoming().artifactView(viewConfiguration -> { - // Project descriptors make sense only for projects - viewConfiguration.withVariantReselection(); - viewConfiguration.componentFilter(component -> component instanceof ProjectComponentIdentifier); - viewConfiguration.attributes(attributes -> attributes.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, - QUARKUS_PROJECT_DESCRIPTOR_ARTIFACT_TYPE)); - }).getFiles()); - } - } - - public static class QuarkusResolvedArtifact implements Serializable { - - private static final long serialVersionUID = 1L; - - private final ComponentArtifactIdentifier id; - private final String type; - private final File file; - - public QuarkusResolvedArtifact(ComponentArtifactIdentifier id, File file, String type) { - this.id = id; - this.type = type; - this.file = file; - } - - public ComponentArtifactIdentifier getId() { - return id; - } - - public String getType() { - return type; - } - - public File getFile() { - return file; - } - } - - public static class QuarkusCapability { - - } - - public static class Utils { - - public static boolean processQuarkusDependency(ResolvedDependencyBuilder artifactBuilder, - ApplicationModelBuilder modelBuilder) { - for (Path artifactPath : artifactBuilder.getResolvedPaths()) { - if (!Files.exists(artifactPath) || !artifactBuilder.getType().equals(ArtifactCoords.TYPE_JAR)) { - break; - } - if (Files.isDirectory(artifactPath)) { - return processQuarkusDir(artifactBuilder, artifactPath.resolve(BootstrapConstants.META_INF), modelBuilder); - } else { - try (FileSystem artifactFs = ZipUtils.newFileSystem(artifactPath)) { - return processQuarkusDir(artifactBuilder, artifactFs.getPath(BootstrapConstants.META_INF), - modelBuilder); - } catch (IOException e) { - throw new RuntimeException("Failed to process " + artifactPath, e); - } - } - } - return false; - } - - private static boolean processQuarkusDir(ResolvedDependencyBuilder artifactBuilder, Path quarkusDir, - ApplicationModelBuilder modelBuilder) { - if (!Files.exists(quarkusDir)) { - return false; - } - final Path quarkusDescr = quarkusDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME); - if (!Files.exists(quarkusDescr)) { - return false; - } - final Properties extProps = readDescriptor(quarkusDescr); - if (extProps == null) { - return false; - } - artifactBuilder.setRuntimeExtensionArtifact(); - final String extensionCoords = artifactBuilder.toGACTVString(); - modelBuilder.handleExtensionProperties(extProps, extensionCoords); - - final String providesCapabilities = extProps.getProperty(BootstrapConstants.PROP_PROVIDES_CAPABILITIES); - if (providesCapabilities != null) { - modelBuilder - .addExtensionCapabilities(CapabilityContract.of(extensionCoords, providesCapabilities, null)); - } - return true; - } - - private static Properties readDescriptor(final Path path) { - final Properties rtProps; - if (!Files.exists(path)) { - // not a platform artifact - return null; - } - rtProps = new Properties(); - try (BufferedReader reader = Files.newBufferedReader(path)) { - rtProps.load(reader); - } catch (IOException e) { - throw new UncheckedIOException("Failed to load extension description " + path, e); - } - return rtProps; - } - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java index d4e7251c8be0c..b50b43b98225e 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuild.java @@ -18,6 +18,7 @@ import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.MapProperty; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; @@ -40,7 +41,7 @@ public abstract class QuarkusBuild extends QuarkusBuildTask { @Inject public QuarkusBuild() { - super("Builds a Quarkus application.", true); + super("Builds a Quarkus application."); } @SuppressWarnings("unused") @@ -48,11 +49,16 @@ public QuarkusBuild nativeArgs(Action> action) { Map nativeArgsMap = new HashMap<>(); action.execute(nativeArgsMap); for (Map.Entry nativeArg : nativeArgsMap.entrySet()) { - additionalForcedProperties.put(expandConfigurationKey(nativeArg.getKey()), nativeArg.getValue().toString()); + getForcedProperties().put(expandConfigurationKey(nativeArg.getKey()), nativeArg.getValue().toString()); } return this; } + @Internal + public MapProperty getForcedProperties() { + return extension().forcedPropertiesProperty(); + } + @Internal public ListProperty getIgnoredEntries() { return extension().ignoredEntriesProperty(); @@ -203,7 +209,7 @@ private void runnerAndArtifactsInputs(Consumer buildInputs, Path sourceDir @SuppressWarnings("deprecation") // legacy JAR @TaskAction public void finalizeQuarkusBuild() { - if (getExtensionView().getForcedProperties().get().containsKey(QUARKUS_IGNORE_LEGACY_DEPLOY_BUILD)) { + if (extension().forcedPropertiesProperty().get().containsKey(QUARKUS_IGNORE_LEGACY_DEPLOY_BUILD)) { getLogger().info("SKIPPING finalizedBy deploy build"); return; } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildCacheableAppParts.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildCacheableAppParts.java index 35d466b5528f8..2ee110cbc19fc 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildCacheableAppParts.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildCacheableAppParts.java @@ -21,7 +21,7 @@ public abstract class QuarkusBuildCacheableAppParts extends QuarkusBuildTask { @Inject public QuarkusBuildCacheableAppParts() { super("Quarkus application build with the ability to cache the built artifacts, excluding dependencies." + - " Do not use this task directly, use '" + QuarkusPlugin.QUARKUS_BUILD_TASK_NAME + "'", true); + " Do not use this task directly, use '" + QuarkusPlugin.QUARKUS_BUILD_TASK_NAME + "'"); } @SuppressWarnings("deprecation") // legacy JAR diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildDependencies.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildDependencies.java index 40e811c1b02a2..1b25b1f95730c 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildDependencies.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildDependencies.java @@ -42,7 +42,7 @@ public abstract class QuarkusBuildDependencies extends QuarkusBuildTask { @Inject public QuarkusBuildDependencies() { super("Collect dependencies for the Quarkus application to be built. " + - "Do not use this task directly, use '" + QuarkusPlugin.QUARKUS_BUILD_TASK_NAME + "'", true); + "Do not use this task directly, use '" + QuarkusPlugin.QUARKUS_BUILD_TASK_NAME + "'"); } /** @@ -144,8 +144,7 @@ private void jarDependencies(Path libBoot, Path libMain) { } ApplicationModel appModel = resolveAppModelForBuild(); - SmallRyeConfig config = getExtensionView().buildEffectiveConfiguration(appModel.getAppArtifact(), new HashMap<>()) - .getConfig(); + SmallRyeConfig config = extension().buildEffectiveConfiguration(appModel.getAppArtifact()).getConfig(); // see https://quarkus.io/guides/class-loading-reference#configuring-class-loading Set removedArtifacts = config.getOptionalValue(CLASS_LOADING_REMOVED_ARTIFACTS, String.class) diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildTask.java index d65757c520bd9..8afb1473cf01d 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildTask.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusBuildTask.java @@ -11,52 +11,44 @@ import javax.inject.Inject; import org.gradle.api.Action; +import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCopyDetails; import org.gradle.api.file.FileSystemOperations; -import org.gradle.api.file.RegularFileProperty; import org.gradle.api.logging.LogLevel; +import org.gradle.api.provider.ListProperty; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.Nested; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.StopExecutionException; -import org.gradle.util.GradleVersion; import org.gradle.workers.WorkQueue; import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.resolver.AppModelResolverException; import io.quarkus.deployment.pkg.PackageConfig; +import io.quarkus.gradle.QuarkusPlugin; import io.quarkus.gradle.tasks.worker.BuildWorker; -import io.quarkus.gradle.tooling.ToolingUtils; +import io.quarkus.maven.dependency.GACTV; import io.smallrye.config.Expressions; import io.smallrye.config.SmallRyeConfig; /** * Base class for the {@link QuarkusBuildDependencies}, {@link QuarkusBuildCacheableAppParts}, {@link QuarkusBuild} tasks */ -public abstract class QuarkusBuildTask extends QuarkusTask { +abstract class QuarkusBuildTask extends QuarkusTask { private static final String QUARKUS_BUILD_DIR = "quarkus-build"; private static final String QUARKUS_BUILD_GEN_DIR = QUARKUS_BUILD_DIR + "/gen"; private static final String QUARKUS_BUILD_APP_DIR = QUARKUS_BUILD_DIR + "/app"; private static final String QUARKUS_BUILD_DEP_DIR = QUARKUS_BUILD_DIR + "/dep"; static final String QUARKUS_ARTIFACT_PROPERTIES = "quarkus-artifact.properties"; static final String NATIVE_SOURCES = "native-sources"; - private final QuarkusPluginExtensionView extensionView; - protected final Map additionalForcedProperties = new HashMap<>(); - QuarkusBuildTask(String description, boolean compatible) { - super(description, compatible); - this.extensionView = getProject().getObjects().newInstance(QuarkusPluginExtensionView.class, extension()); - } + private final GACTV gactv; - /** - * Returns a view of the Quarkus extension that is compatible with the configuration cache. - */ - @Nested - protected QuarkusPluginExtensionView getExtensionView() { - return extensionView; + QuarkusBuildTask(String description) { + super(description); + + gactv = new GACTV(getProject().getGroup().toString(), getProject().getName(), + getProject().getVersion().toString()); } @Inject @@ -64,34 +56,29 @@ protected QuarkusPluginExtensionView getExtensionView() { @Classpath public FileCollection getClasspath() { - return classpath; - } - - private FileCollection classpath = getProject().getObjects().fileCollection(); - - public void setCompileClasspath(FileCollection compileClasspath) { - this.classpath = compileClasspath; + return extension().classpath(); } @Input public Map getCachingRelevantInput() { - return getExtensionView().getCachingRelevantInput().get(); + ListProperty vars = extension().getCachingRelevantProperties(); + return extension().baseConfig().cachingRelevantProperties(vars.get()); } PackageConfig.JarConfig.JarType jarType() { - return getExtensionView().getJarType().get(); + return extension().baseConfig().jarType(); } boolean jarEnabled() { - return getExtensionView().getJarEnabled().get(); + return extension().baseConfig().packageConfig().jar().enabled(); } boolean nativeEnabled() { - return getExtensionView().getNativeEnabled().get(); + return extension().baseConfig().nativeConfig().enabled(); } boolean nativeSourcesOnly() { - return getExtensionView().getNativeSourcesOnly().get(); + return extension().baseConfig().nativeConfig().sourcesOnly(); } Path gradleBuildDir() { @@ -156,28 +143,28 @@ String nativeImageSourceJarDirName() { } String runnerBaseName() { - return getExtensionView().getRunnerName().get(); + BaseConfig baseConfig = extension().baseConfig(); + return baseConfig.packageConfig().outputName().orElseGet(() -> extension().finalName()); } String outputDirectory() { - return getExtensionView().getOutputDirectory().get().toString(); + BaseConfig baseConfig = extension().baseConfig(); + return baseConfig.packageConfig().outputDirectory().map(Path::toString).orElse(QuarkusPlugin.DEFAULT_OUTPUT_DIRECTORY); } private String runnerSuffix() { - return getExtensionView().getRunnerSuffix().get(); - + BaseConfig baseConfig = extension().baseConfig(); + return baseConfig.packageConfig().computedRunnerSuffix(); } - @InputFile - @PathSensitive(PathSensitivity.RELATIVE) - public abstract RegularFileProperty getApplicationModel(); - ApplicationModel resolveAppModelForBuild() { + ApplicationModel appModel; try { - return ToolingUtils.deserializeAppModel(getApplicationModel().get().getAsFile().toPath()); - } catch (IOException e) { - throw new RuntimeException(e); + appModel = extension().getAppModelResolver().resolveModel(gactv); + } catch (AppModelResolverException e) { + throw new GradleException("Failed to resolve Quarkus application model for " + getPath(), e); } + return appModel; } /** @@ -238,8 +225,7 @@ void generateBuild() { }); ApplicationModel appModel = resolveAppModelForBuild(); - SmallRyeConfig config = getExtensionView() - .buildEffectiveConfiguration(appModel.getAppArtifact(), additionalForcedProperties).getConfig(); + SmallRyeConfig config = extension().buildEffectiveConfiguration(appModel.getAppArtifact()).getConfig(); Map quarkusProperties = Expressions.withoutExpansion(() -> { Map values = new HashMap<>(); for (String key : config.getMapKeys("quarkus").values()) { @@ -266,15 +252,15 @@ void generateBuild() { .collect(Collectors.joining("\n ", "\n ", ""))); } - WorkQueue workQueue = workQueue(quarkusProperties, getExtensionView().getCodeGenForkOptions().get()); + WorkQueue workQueue = workQueue(quarkusProperties, () -> extension().buildForkOptions); workQueue.submit(BuildWorker.class, params -> { params.getBuildSystemProperties() - .putAll(getExtensionView().buildSystemProperties(appModel.getAppArtifact(), quarkusProperties)); - params.getBaseName().set(getExtensionView().getFinalName()); + .putAll(extension().buildSystemProperties(appModel.getAppArtifact(), quarkusProperties)); + params.getBaseName().set(extension().finalName()); params.getTargetDirectory().set(buildDir.toFile()); params.getAppModel().set(appModel); - params.getGradleVersion().set(GradleVersion.current().getVersion()); + params.getGradleVersion().set(getProject().getGradle().getGradleVersion()); }); workQueue.await(); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java index a86e1b4e794f9..f3b5a930bb51a 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java @@ -1,11 +1,9 @@ package io.quarkus.gradle.tasks; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -17,23 +15,19 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileCollection; -import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.ListProperty; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.CompileClasspath; import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.InputFiles; -import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.PathSensitive; import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.TaskAction; -import org.gradle.util.GradleVersion; import org.gradle.workers.WorkQueue; import io.quarkus.bootstrap.model.ApplicationModel; import io.quarkus.gradle.tasks.worker.CodeGenWorker; -import io.quarkus.gradle.tooling.ToolingUtils; import io.quarkus.runtime.LaunchMode; @CacheableTask @@ -51,20 +45,11 @@ public abstract class QuarkusGenerateCode extends QuarkusTask { private final LaunchMode launchMode; private final String inputSourceSetName; - private final QuarkusPluginExtensionView extensionView; - @Inject public QuarkusGenerateCode(LaunchMode launchMode, String inputSourceSetName) { - super("Performs Quarkus pre-build preparations, such as sources generation", true); + super("Performs Quarkus pre-build preparations, such as sources generation"); this.launchMode = launchMode; this.inputSourceSetName = inputSourceSetName; - this.extensionView = getProject().getObjects().newInstance(QuarkusPluginExtensionView.class, extension()); - - } - - @Nested - protected QuarkusPluginExtensionView getExtensionView() { - return extensionView; } /** @@ -81,6 +66,12 @@ public void setCompileClasspath(Configuration compileClasspath) { this.compileClasspath = compileClasspath; } + @Input + public Map getCachingRelevantInput() { + ListProperty vars = extension().getCachingRelevantProperties(); + return extension().baseConfig().cachingRelevantProperties(vars.get()); + } + @Input Map getInternalTaskConfig() { // Necessary to distinguish the different `quarkusGenerateCode*` tasks, because the task path is _not_ @@ -108,29 +99,24 @@ public Set getInputDirectory() { return inputDirectories; } - @InputFile - @PathSensitive(PathSensitivity.RELATIVE) - public abstract RegularFileProperty getApplicationModel(); - @OutputDirectory public abstract DirectoryProperty getGeneratedOutputDirectory(); @TaskAction - public void generateCode() throws IOException { - ApplicationModel appModel = ToolingUtils.deserializeAppModel(getApplicationModel().get().getAsFile().toPath()); - Map configMap = getExtensionView() - .buildEffectiveConfiguration(appModel.getAppArtifact(), new HashMap<>()).getValues(); + public void generateCode() { + ApplicationModel appModel = extension().getApplicationModel(launchMode); + Map values = extension().buildEffectiveConfiguration(appModel.getAppArtifact()).getValues(); File outputPath = getGeneratedOutputDirectory().get().getAsFile(); getLogger().debug("Will trigger preparing sources for source directories: {} buildDir: {}", sourcesDirectories, buildDir.getAbsolutePath()); - WorkQueue workQueue = workQueue(configMap, getExtensionView().getCodeGenForkOptions().get()); + WorkQueue workQueue = workQueue(values, () -> extension().codeGenForkOptions); workQueue.submit(CodeGenWorker.class, params -> { - params.getBuildSystemProperties().putAll(configMap); - params.getBaseName().set(getExtensionView().getFinalName()); + params.getBuildSystemProperties().putAll(values); + params.getBaseName().set(extension().finalName()); params.getTargetDirectory().set(buildDir); params.getAppModel().set(appModel); params @@ -138,7 +124,7 @@ public void generateCode() throws IOException { .setFrom(sourcesDirectories.stream().map(Path::toFile).collect(Collectors.toList())); params.getOutputPath().set(outputPath); params.getLaunchMode().set(launchMode); - params.getGradleVersion().set(GradleVersion.current().getVersion()); + params.getGradleVersion().set(getProject().getGradle().getGradleVersion()); }); workQueue.await(); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPluginExtensionView.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPluginExtensionView.java deleted file mode 100644 index f4a8e87aba3d9..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusPluginExtensionView.java +++ /dev/null @@ -1,312 +0,0 @@ -package io.quarkus.gradle.tasks; - -import static io.quarkus.gradle.QuarkusPlugin.BUILD_NATIVE_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.TEST_NATIVE_TASK_NAME; -import static io.quarkus.gradle.tasks.AbstractQuarkusExtension.QUARKUS_PROFILE; -import static io.quarkus.gradle.tasks.AbstractQuarkusExtension.toManifestAttributeKey; -import static io.quarkus.gradle.tasks.AbstractQuarkusExtension.toManifestSectionAttributeKey; -import static io.smallrye.common.expression.Expression.Flag.DOUBLE_COLON; -import static io.smallrye.common.expression.Expression.Flag.LENIENT_SYNTAX; -import static io.smallrye.common.expression.Expression.Flag.NO_SMART_BRACES; -import static io.smallrye.common.expression.Expression.Flag.NO_TRIM; -import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME; - -import java.io.File; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.inject.Inject; - -import org.gradle.api.Action; -import org.gradle.api.Project; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.java.archives.Attributes; -import org.gradle.api.provider.ListProperty; -import org.gradle.api.provider.MapProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.provider.Provider; -import org.gradle.api.provider.ProviderFactory; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.Internal; -import org.gradle.api.tasks.Nested; -import org.gradle.api.tasks.Optional; -import org.gradle.api.tasks.SourceSetContainer; -import org.gradle.process.JavaForkOptions; -import org.gradle.util.GradleVersion; - -import io.quarkus.deployment.pkg.PackageConfig; -import io.quarkus.gradle.QuarkusPlugin; -import io.quarkus.gradle.dsl.Manifest; -import io.quarkus.gradle.extension.QuarkusPluginExtension; -import io.quarkus.maven.dependency.ResolvedDependency; -import io.smallrye.common.expression.Expression; - -/** - * Configuration cache compatible view of Quarkus extension - */ -public abstract class QuarkusPluginExtensionView { - - @Inject - public QuarkusPluginExtensionView(Project project, QuarkusPluginExtension extension) { - project.getGradle().getTaskGraph().whenReady(taskGraph -> { - if (taskGraph.hasTask(project.getPath() + BUILD_NATIVE_TASK_NAME) - || taskGraph.hasTask(project.getPath() + TEST_NATIVE_TASK_NAME)) { - getNativeBuild().set(true); - } else { - getNativeBuild().set(false); - } - }); - getCacheLargeArtifacts().set(extension.getCacheLargeArtifacts()); - getCleanupBuildOutput().set(extension.getCleanupBuildOutput()); - getFinalName().set(extension.getFinalName()); - getCodeGenForkOptions().set(getProviderFactory().provider(() -> extension.codeGenForkOptions)); - getIgnoredEntries().set(extension.ignoredEntriesProperty()); - getMainResources().setFrom(project.getExtensions().getByType(SourceSetContainer.class).getByName(MAIN_SOURCE_SET_NAME) - .getResources().getSourceDirectories()); - getQuarkusBuildProperties().set(extension.getQuarkusBuildProperties()); - getQuarkusRelevantProjectProperties().set(getQuarkusRelevantProjectProperties(project)); - getQuarkusProfileSystemVariable().set(getProviderFactory().systemProperty(QUARKUS_PROFILE)); - getQuarkusProfileEnvVariable().set(getProviderFactory().environmentVariable("QUARKUS_PROFILE")); - getCachingRelevantInput() - .set(extension.baseConfig().cachingRelevantProperties(extension.getCachingRelevantProperties().get())); - getForcedProperties().set(extension.forcedPropertiesProperty()); - Map projectProperties = new HashMap<>(); - for (Map.Entry entry : project.getProperties().entrySet()) { - if ((entry.getKey().startsWith("quarkus.") || entry.getKey().startsWith("platform.quarkus."))) { - projectProperties.put(entry.getKey(), entry.getValue()); - } - } - getProjectProperties().set(projectProperties); - getJarEnabled().set(extension.baseConfig().packageConfig().jar().enabled()); - getManifestAttributes().set(extension.manifest().getAttributes()); - getManifestSections().set(extension.manifest().getSections()); - getNativeEnabled().set(extension.baseConfig().nativeConfig().enabled()); - getNativeSourcesOnly().set(extension.baseConfig().nativeConfig().sourcesOnly()); - getRunnerSuffix().set(extension.baseConfig().packageConfig().computedRunnerSuffix()); - getRunnerName().set(extension.baseConfig().packageConfig().outputName().orElseGet(extension::finalName)); - getOutputDirectory().set(Path.of(extension.baseConfig().packageConfig().outputDirectory().map(Path::toString) - .orElse(QuarkusPlugin.DEFAULT_OUTPUT_DIRECTORY))); - getJarType().set(extension.baseConfig().jarType()); - } - - private Provider> getQuarkusRelevantProjectProperties(Project project) { - if (GradleVersion.current().compareTo(GradleVersion.version("8.0")) >= 0) { - // This is more efficient, i.e.: configuration cache is invalidated only when quarkus properties change - return getProviderFactory().gradlePropertiesPrefixedBy("quarkus."); - } else { - return getProviderFactory().provider(() -> project.getProperties().entrySet().stream() - .filter(e -> e.getValue() != null) - .map(e -> Map.entry(e.getKey(), e.getValue().toString())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); - } - } - - @Inject - public abstract ProviderFactory getProviderFactory(); - - @Input - @Optional - public abstract Property getNativeBuild(); - - @Input - public abstract Property getCacheLargeArtifacts(); - - @Input - public abstract Property getCleanupBuildOutput(); - - @Input - public abstract Property getFinalName(); - - @Input - public abstract MapProperty getProjectProperties(); - - @Nested - public abstract ListProperty> getCodeGenForkOptions(); - - @Input - @Optional - public abstract Property getJarEnabled(); - - @Input - @Optional - public abstract Property getNativeEnabled(); - - @Input - @Optional - public abstract Property getManifest(); - - @Input - @Optional - public abstract Property getNativeSourcesOnly(); - - @Input - public abstract ListProperty getIgnoredEntries(); - - @Input - public abstract MapProperty getQuarkusBuildProperties(); - - @Input - public abstract MapProperty getQuarkusRelevantProjectProperties(); - - @Internal - public abstract ConfigurableFileCollection getMainResources(); - - @Internal - public abstract Property getRunnerSuffix(); - - @Internal - public abstract Property getRunnerName(); - - @Internal - public abstract Property getOutputDirectory(); - - @Input - public abstract Property getJarType(); - - @Input - @Optional - public abstract Property getQuarkusProfileSystemVariable(); - - @Input - @Optional - public abstract Property getQuarkusProfileEnvVariable(); - - @Input - @Optional - public abstract MapProperty getCachingRelevantInput(); - - @Input - @Optional - public abstract MapProperty getForcedProperties(); - - @Input - @Optional - public abstract MapProperty getManifestAttributes(); - - @Input - @Optional - public abstract MapProperty getManifestSections(); - - private void exportCustomManifestProperties(Map properties) { - for (Map.Entry attribute : getManifestAttributes().get().entrySet()) { - properties.put(toManifestAttributeKey(attribute.getKey()), - attribute.getValue()); - } - - for (Map.Entry section : getManifestSections().get().entrySet()) { - for (Map.Entry attribute : section.getValue().entrySet()) { - properties - .put(toManifestSectionAttributeKey(section.getKey(), attribute.getKey()), attribute.getValue()); - } - } - } - - protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArtifact, - Map additionalForcedProperties) { - Map properties = new HashMap<>(); - exportCustomManifestProperties(properties); - - Map defaultProperties = new HashMap<>(); - String userIgnoredEntries = String.join(",", getIgnoredEntries().get()); - if (!userIgnoredEntries.isEmpty()) { - defaultProperties.put("quarkus.package.jar.user-configured-ignored-entries", userIgnoredEntries); - } - Set resourcesDirs = getMainResources().getFiles(); - defaultProperties.putIfAbsent("quarkus.application.name", appArtifact.getArtifactId()); - defaultProperties.putIfAbsent("quarkus.application.version", appArtifact.getVersion()); - - Map forced = new HashMap<>(getForcedProperties().get()); - getProjectProperties().get().forEach((k, v) -> { - forced.put(k, v.toString()); - - }); - additionalForcedProperties.forEach((k, v) -> { - forced.put(k, v.toString()); - }); - if (getNativeBuild().get()) { - forced.put("quarkus.native.enabled", "true"); - } - return EffectiveConfig.builder() - .withForcedProperties(forced) - .withTaskProperties(properties) - .withBuildProperties(getQuarkusBuildProperties().get()) - .withProjectProperties(getQuarkusRelevantProjectProperties().get()) - .withDefaultProperties(defaultProperties) - .withSourceDirectories(resourcesDirs) - .withProfile(getQuarkusProfile()) - .build(); - } - - protected Map buildSystemProperties(ResolvedDependency appArtifact, Map quarkusProperties) { - Map buildSystemProperties = new HashMap<>(); - buildSystemProperties.putIfAbsent("quarkus.application.name", appArtifact.getArtifactId()); - buildSystemProperties.putIfAbsent("quarkus.application.version", appArtifact.getVersion()); - - for (Map.Entry entry : getForcedProperties().get().entrySet()) { - if (entry.getKey().startsWith("quarkus.") || entry.getKey().startsWith("platform.quarkus.")) { - buildSystemProperties.put(entry.getKey(), entry.getValue()); - } - } - for (Map.Entry entry : getQuarkusBuildProperties().get().entrySet()) { - if (entry.getKey().startsWith("quarkus.") || entry.getKey().startsWith("platform.quarkus.")) { - buildSystemProperties.put(entry.getKey(), entry.getValue()); - } - } - for (Map.Entry entry : getProjectProperties().get().entrySet()) { - if ((entry.getKey().startsWith("quarkus.") || entry.getKey().startsWith("platform.quarkus.")) - && entry.getValue() != null) { - buildSystemProperties.put(entry.getKey(), entry.getValue().toString()); - } - } - - Set quarkusValues = new HashSet<>(); - quarkusValues.addAll(quarkusProperties.values()); - quarkusValues.addAll(buildSystemProperties.values()); - - for (String value : quarkusValues) { - Expression expression = Expression.compile(value, LENIENT_SYNTAX, NO_TRIM, NO_SMART_BRACES, DOUBLE_COLON); - for (String reference : expression.getReferencedStrings()) { - String expanded = getForcedProperties().get().get(reference); - if (expanded != null) { - buildSystemProperties.put(reference, expanded); - continue; - } - - expanded = getQuarkusBuildProperties().get().get(reference); - if (expanded != null) { - buildSystemProperties.put(reference, expanded); - continue; - } - expanded = (String) getProjectProperties().get().get(reference); - if (expanded != null) { - buildSystemProperties.put(reference, expanded); - } - } - } - return buildSystemProperties; - } - - private String getQuarkusProfile() { - String profile = getQuarkusProfileSystemVariable().getOrNull(); - if (profile == null) { - profile = getQuarkusProfileEnvVariable().getOrNull(); - } - if (profile == null) { - profile = getQuarkusBuildProperties().get().get(QUARKUS_PROFILE); - } - if (profile == null) { - Object p = getQuarkusRelevantProjectProperties().get().get(QUARKUS_PROFILE); - if (p != null) { - profile = p.toString(); - } - } - if (profile == null) { - profile = "prod"; - } - return profile; - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java index e65e7e8c2759b..e4434f5474a1b 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusRun.java @@ -48,7 +48,7 @@ public QuarkusRun() { } public QuarkusRun(String description) { - super(description, false); + super(description); final ObjectFactory objectFactory = getProject().getObjects(); mainSourceSet = getProject().getExtensions().getByType(SourceSetContainer.class) .getByName(SourceSet.MAIN_SOURCE_SET_NAME); diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusShowEffectiveConfig.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusShowEffectiveConfig.java index adc4479990c7d..7cf99588fa118 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusShowEffectiveConfig.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusShowEffectiveConfig.java @@ -22,7 +22,6 @@ import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; -import io.quarkus.bootstrap.model.ApplicationModel; import io.smallrye.config.SmallRyeConfig; /** @@ -34,7 +33,7 @@ public abstract class QuarkusShowEffectiveConfig extends QuarkusBuildTask { @Inject public QuarkusShowEffectiveConfig() { - super("Collect dependencies for the Quarkus application, prefer the 'quarkusBuild' task", true); + super("Collect dependencies for the Quarkus application, prefer the 'quarkusBuild' task"); this.saveConfigProperties = getProject().getObjects().property(Boolean.class).convention(Boolean.FALSE); } @@ -47,9 +46,8 @@ public Property getSaveConfigProperties() { @TaskAction public void dumpEffectiveConfiguration() { try { - ApplicationModel appModel = resolveAppModelForBuild(); - EffectiveConfig effectiveConfig = getExtensionView() - .buildEffectiveConfiguration(appModel.getAppArtifact(), additionalForcedProperties); + EffectiveConfig effectiveConfig = extension() + .buildEffectiveConfiguration(extension().getApplicationModel().getAppArtifact()); SmallRyeConfig config = effectiveConfig.getConfig(); List sourceNames = new ArrayList<>(); config.getConfigSources().forEach(configSource -> sourceNames.add(configSource.getName())); @@ -66,7 +64,7 @@ public void dumpEffectiveConfiguration() { .collect(Collectors.joining("\n ", "\n ", "\n")); getLogger().lifecycle("Effective Quarkus configuration options: {}", quarkusConfig); - String finalName = getExtensionView().getFinalName().get(); + String finalName = extension().finalName(); String jarType = config.getOptionalValue("quarkus.package.jar.type", String.class).orElse("fast-jar"); File fastJar = fastJar(); getLogger().lifecycle(""" diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java index 23068daa0d43d..e8dade749dc72 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusTask.java @@ -5,6 +5,7 @@ import java.nio.file.Paths; import java.util.List; import java.util.Map; +import java.util.function.Supplier; import javax.inject.Inject; @@ -26,10 +27,6 @@ public abstract class QuarkusTask extends DefaultTask { protected final File buildDir; QuarkusTask(String description) { - this(description, false); - } - - QuarkusTask(String description, boolean configurationCacheCompatible) { setDescription(description); setGroup("quarkus"); this.extension = getProject().getExtensions().findByType(QuarkusPluginExtension.class); @@ -38,9 +35,7 @@ public abstract class QuarkusTask extends DefaultTask { // Calling this method tells Gradle that it should not fail the build. Side effect is that the configuration // cache will be at least degraded, but the build will not fail. - if (!configurationCacheCompatible) { - notCompatibleWithConfigurationCache("The Quarkus Plugin isn't compatible with the configuration cache"); - } + notCompatibleWithConfigurationCache("The Quarkus Plugin isn't compatible with the configuration cache"); } @Inject @@ -50,7 +45,7 @@ QuarkusPluginExtension extension() { return extension; } - WorkQueue workQueue(Map configMap, List> forkOptionsSupplier) { + WorkQueue workQueue(Map configMap, Supplier>> forkOptionsActions) { WorkerExecutor workerExecutor = getWorkerExecutor(); // Use process isolation by default, unless Gradle's started with its debugging system property or the @@ -60,7 +55,7 @@ WorkQueue workQueue(Map configMap, List configureProcessWorkerSpec(processWorkerSpec, - configMap, forkOptionsSupplier)); + configMap, forkOptionsActions.get())); } private void configureProcessWorkerSpec(ProcessWorkerSpec processWorkerSpec, Map configMap, diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/DefaultProjectDescriptor.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/DefaultProjectDescriptor.java deleted file mode 100644 index da56ac82b63db..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/DefaultProjectDescriptor.java +++ /dev/null @@ -1,97 +0,0 @@ -package io.quarkus.gradle.workspace.descriptors; - -import java.io.File; -import java.io.Serializable; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.stream.Collectors; - -public class DefaultProjectDescriptor implements Serializable, ProjectDescriptor { - - private static final long serialVersionUID = 1L; - - private final File projectDir; - private final File buildDir; - private final File buildFile; - - private final Map tasks; - private final Map> sourceSetTasks; - - public DefaultProjectDescriptor(File projectDir, File buildDir, File buildFile, Map tasks, - Map> sourceSetTasks) { - this.projectDir = projectDir; - this.buildDir = buildDir; - this.buildFile = buildFile; - this.tasks = tasks; - this.sourceSetTasks = sourceSetTasks; - } - - @Override - public File getProjectDir() { - return projectDir; - } - - @Override - public File getBuildDir() { - return buildDir; - } - - @Override - public File getBuildFile() { - return buildFile; - } - - public Map> getSourceSetTasks() { - return sourceSetTasks; - } - - public Map getTasks() { - return tasks; - } - - @Override - public Set getTasksForSourceSet(String sourceSetName) { - return sourceSetTasks.getOrDefault(sourceSetName, Collections.emptySet()); - } - - @Override - public String getTaskSource(String task) { - return tasks.get(task).getSourceDir().getAbsolutePath(); - } - - @Override - public String getTaskDestinationDir(String task) { - return tasks.get(task).getDestinationDir().getAbsolutePath(); - } - - @Override - public TaskType getTaskType(String task) { - return tasks.get(task).getTaskType(); - } - - /** - * Returns a new {@link DefaultProjectDescriptor} with only the given source sets. - */ - public DefaultProjectDescriptor withSourceSetView(Set acceptedSourceSets) { - Map> filteredSourceSets = sourceSetTasks.entrySet().stream() - .filter(e -> acceptedSourceSets.contains(e.getKey())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, TreeMap::new)); - Map filteredTasks = tasks.entrySet().stream() - .filter(e -> filteredSourceSets.values().stream().anyMatch(tasks -> tasks.contains(e.getKey()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, TreeMap::new)); - return new DefaultProjectDescriptor(projectDir, buildDir, buildFile, filteredTasks, filteredSourceSets); - } - - @Override - public String toString() { - return "DefaultProjectDescriptor{" + - "\nprojectDir=" + projectDir + - ",\nbuildDir=" + buildDir + - ",\nbuildFile=" + buildFile + - ",\ntasks=" + tasks + - ",\nsourceSetTasks=" + sourceSetTasks + - "\n}"; - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptor.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptor.java deleted file mode 100644 index 1f5ae038bc5ba..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptor.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.quarkus.gradle.workspace.descriptors; - -import java.io.File; -import java.util.Set; - -public interface ProjectDescriptor { - - public enum TaskType { - COMPILE, - RESOURCES - } - - public File getProjectDir(); - - public File getBuildDir(); - - public File getBuildFile(); - - public Set getTasksForSourceSet(String sourceName); - - public String getTaskSource(String task); - - public String getTaskDestinationDir(String task); - - public TaskType getTaskType(String task); - -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptorBuilder.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptorBuilder.java deleted file mode 100644 index acdd22e5661ba..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/ProjectDescriptorBuilder.java +++ /dev/null @@ -1,143 +0,0 @@ -package io.quarkus.gradle.workspace.descriptors; - -import static io.quarkus.gradle.workspace.descriptors.ProjectDescriptor.TaskType.COMPILE; -import static io.quarkus.gradle.workspace.descriptors.ProjectDescriptor.TaskType.RESOURCES; - -import java.io.File; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; - -import org.gradle.api.Project; -import org.gradle.api.provider.Provider; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.SourceSetContainer; -import org.gradle.api.tasks.compile.AbstractCompile; -import org.gradle.api.tasks.testing.Test; -import org.gradle.language.jvm.tasks.ProcessResources; -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile; - -import com.google.common.collect.ImmutableSet; - -public class ProjectDescriptorBuilder { - - private static final Set DEPENDENCY_SOURCE_SETS = ImmutableSet.of(SourceSet.MAIN_SOURCE_SET_NAME, - SourceSet.TEST_SOURCE_SET_NAME, "test-fixtures"); - - private final File projectDir; - private final File buildDir; - private final File buildFile; - private final Map tasks; - private final Map> sourceSetTasks; - private final Set collectOnlySourceSets; - - private ProjectDescriptorBuilder(Project project, Set collectOnlySourceSets) { - this.tasks = new LinkedHashMap<>(); - this.sourceSetTasks = new LinkedHashMap<>(); - this.buildFile = project.getBuildFile(); - this.projectDir = project.getLayout().getProjectDirectory().getAsFile(); - this.buildDir = project.getLayout().getBuildDirectory().get().getAsFile(); - this.collectOnlySourceSets = collectOnlySourceSets; - } - - public static Provider buildForApp(Project target) { - ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder(target, Collections.emptySet()); - target.afterEvaluate(project -> { - project.getTasks().withType(AbstractCompile.class) - .configureEach(builder::readConfigurationFor); - builder.withKotlinJvmCompileType(project); - project.getTasks().withType(ProcessResources.class) - .configureEach(builder::readConfigurationFor); - project.getTasks().withType(Test.class) - .configureEach(builder::readConfigurationFor); - }); - return target.getProviders().provider(() -> new DefaultProjectDescriptor( - builder.projectDir, - builder.buildDir, - builder.buildFile, - builder.tasks, - builder.sourceSetTasks)); - } - - public static Provider buildForDependency(Project target) { - ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder(target, DEPENDENCY_SOURCE_SETS); - target.afterEvaluate(project -> { - project.getTasks().withType(AbstractCompile.class) - .configureEach(builder::readConfigurationFor); - builder.withKotlinJvmCompileType(project); - project.getTasks().withType(ProcessResources.class) - .configureEach(builder::readConfigurationFor); - }); - return target.getProviders().provider(() -> new DefaultProjectDescriptor( - builder.projectDir, - builder.buildDir, - builder.buildFile, - builder.tasks, - builder.sourceSetTasks)); - } - - private void readConfigurationFor(AbstractCompile task) { - if (task.getEnabled() && !task.getSource().isEmpty()) { - File destDir = task.getDestinationDirectory().getAsFile().get(); - task.getSource().visit(fileVisitDetails -> { - if (fileVisitDetails.getRelativePath().getParent().toString().isEmpty()) { - File srcDir = fileVisitDetails.getFile().getParentFile(); - tasks.put(task.getName(), new QuarkusTaskDescriptor(task.getName(), COMPILE, srcDir, destDir)); - SourceSetContainer sourceSets = task.getProject().getExtensions().getByType(SourceSetContainer.class); - sourceSets.stream().filter(sourceSet -> sourceSet.getOutput().getClassesDirs().contains(destDir)) - .forEach(sourceSet -> sourceSetTasks - .computeIfAbsent(sourceSet.getName(), s -> new HashSet<>()) - .add(task.getName())); - fileVisitDetails.stopVisiting(); - } - }); - } - } - - private void readConfigurationFor(Test task) { - } - - private void readConfigurationFor(ProcessResources task) { - if (task.getEnabled() && !task.getSource().isEmpty()) { - File destDir = task.getDestinationDir(); - task.getSource().getAsFileTree().visit(fileVisitDetails -> { - if (fileVisitDetails.getRelativePath().getParent().toString().isEmpty()) { - File srcDir = fileVisitDetails.getFile().getParentFile(); - tasks.put(task.getName(), new QuarkusTaskDescriptor(task.getName(), RESOURCES, srcDir, destDir)); - SourceSetContainer sourceSets = task.getProject().getExtensions().getByType(SourceSetContainer.class); - sourceSets.stream().filter(sourceSet -> destDir.equals(sourceSet.getOutput().getResourcesDir())) - .forEach(sourceSet -> sourceSetTasks - .computeIfAbsent(sourceSet.getName(), s -> new HashSet<>()) - .add(task.getName())); - fileVisitDetails.stopVisiting(); - } - }); - } - } - - private void withKotlinJvmCompileType(Project project) { - try { - Class.forName("org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile"); - project.getTasks().withType(KotlinJvmCompile.class).configureEach(this::readConfigurationFor); - } catch (ClassNotFoundException e) { - // Ignore - } - } - - private void readConfigurationFor(KotlinJvmCompile task) { - if (task.getEnabled() && !task.getSources().isEmpty()) { - File destDir = task.getDestinationDirectory().getAsFile().get(); - AtomicReference srcDir = new AtomicReference<>(); - task.getSources().getAsFileTree().visit(fileVisitDetails -> { - if (fileVisitDetails.getRelativePath().getParent().toString().isEmpty()) { - srcDir.set(fileVisitDetails.getFile().getParentFile()); - fileVisitDetails.stopVisiting(); - } - }); - tasks.put(task.getName(), new QuarkusTaskDescriptor(task.getName(), COMPILE, srcDir.get(), destDir)); - } - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/QuarkusTaskDescriptor.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/QuarkusTaskDescriptor.java deleted file mode 100644 index 2e84ed8ada1a5..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/workspace/descriptors/QuarkusTaskDescriptor.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.quarkus.gradle.workspace.descriptors; - -import java.io.File; -import java.io.Serializable; - -import io.quarkus.gradle.workspace.descriptors.ProjectDescriptor.TaskType; - -public class QuarkusTaskDescriptor implements Serializable { - - private static final long serialVersionUID = 1L; - - private final String taskName; - private final TaskType taskType; - private final File sourceDir; - private final File destinationDir; - - public QuarkusTaskDescriptor(String taskName, TaskType taskType, File sourceDir, File destinationDir) { - this.taskName = taskName; - this.taskType = taskType; - this.sourceDir = sourceDir; - this.destinationDir = destinationDir; - } - - public String getTaskName() { - return taskName; - } - - public TaskType getTaskType() { - return taskType; - } - - public File getSourceDir() { - return sourceDir; - } - - public File getDestinationDir() { - return destinationDir; - } - - @Override - public String toString() { - return "QuarkusTaskDescriptor{" + - "taskName='" + taskName + '\'' + - ", taskType=" + taskType + - ", sourceDir=" + sourceDir + - ", destinationDir=" + destinationDir + - '}'; - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/TasksConfigurationCacheCompatibilityTest.java b/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/TasksConfigurationCacheCompatibilityTest.java deleted file mode 100644 index e1d0d1f957c2f..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/TasksConfigurationCacheCompatibilityTest.java +++ /dev/null @@ -1,149 +0,0 @@ -package io.quarkus.gradle.tasks; - -import static io.quarkus.gradle.QuarkusPlugin.DEPLOY_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.IMAGE_BUILD_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.IMAGE_PUSH_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_BUILD_APP_PARTS_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_BUILD_DEP_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_BUILD_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_GENERATE_CODE_DEV_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_GENERATE_CODE_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_GENERATE_CODE_TESTS_TASK_NAME; -import static io.quarkus.gradle.QuarkusPlugin.QUARKUS_SHOW_EFFECTIVE_CONFIG_TASK_NAME; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Path; -import java.util.stream.Stream; - -import org.apache.commons.io.FileUtils; -import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.GradleRunner; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.io.TempDir; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class TasksConfigurationCacheCompatibilityTest { - - @TempDir - Path testProjectDir; - - private static Stream compatibleTasks() { - return Stream.of( - QUARKUS_GENERATE_CODE_TASK_NAME, - QUARKUS_GENERATE_CODE_DEV_TASK_NAME, - QUARKUS_BUILD_DEP_TASK_NAME, - QUARKUS_BUILD_APP_PARTS_TASK_NAME, - QUARKUS_SHOW_EFFECTIVE_CONFIG_TASK_NAME, - QUARKUS_BUILD_TASK_NAME, - QUARKUS_GENERATE_CODE_TESTS_TASK_NAME); - } - - private static Stream nonCompatibleQuarkusBuildTasks() { - return Stream.of( - IMAGE_BUILD_TASK_NAME, - IMAGE_PUSH_TASK_NAME, - DEPLOY_TASK_NAME); - } - - @Test - @Order(1) - public void quarkusBuildFooTest() throws IOException, URISyntaxException { - URL url = getClass().getClassLoader().getResource("io/quarkus/gradle/tasks/configurationcache/main"); - FileUtils.copyDirectory(new File(url.toURI()), testProjectDir.toFile()); - FileUtils.copyFile(new File("../gradle.properties"), testProjectDir.resolve("gradle.properties").toFile()); - - GradleRunner.create() - .withPluginClasspath() - .withProjectDir(testProjectDir.toFile()) - .withArguments(QUARKUS_GENERATE_CODE_TASK_NAME, "--info", "--stacktrace", "--build-cache", - "--configuration-cache") - .build(); - assertTrue(true); - } - - @ParameterizedTest - @Order(4) - @MethodSource("compatibleTasks") - public void configurationCacheIsReusedTest(String taskName) throws IOException, URISyntaxException { - URL url = getClass().getClassLoader().getResource("io/quarkus/gradle/tasks/configurationcache/main"); - FileUtils.copyDirectory(new File(url.toURI()), testProjectDir.toFile()); - FileUtils.copyFile(new File("../gradle.properties"), testProjectDir.resolve("gradle.properties").toFile()); - - buildResult(":help", "--configuration-cache"); - - BuildResult firstBuild = buildResult(taskName, "--configuration-cache"); - assertTrue(firstBuild.getOutput().contains("Configuration cache entry stored")); - - BuildResult secondBuild = buildResult(taskName, "--configuration-cache"); - assertTrue(secondBuild.getOutput().contains("Reusing configuration cache.")); - } - - @ParameterizedTest - @Order(5) - @MethodSource("compatibleTasks") - public void configurationCacheIsReusedWhenProjectIsolationIsUsedTest(String taskName) - throws IOException, URISyntaxException { - URL url = getClass().getClassLoader().getResource("io/quarkus/gradle/tasks/configurationcache/main"); - FileUtils.copyDirectory(new File(url.toURI()), testProjectDir.toFile()); - FileUtils.copyFile(new File("../gradle.properties"), testProjectDir.resolve("gradle.properties").toFile()); - - BuildResult firstBuild = buildResult(taskName, "-Dorg.gradle.unsafe.isolated-projects=true"); - assertTrue(firstBuild.getOutput().contains("Configuration cache entry stored")); - - BuildResult secondBuild = buildResult(taskName, "-Dorg.gradle.unsafe.isolated-projects=true"); - assertTrue(secondBuild.getOutput().contains("Reusing configuration cache.")); - } - - @ParameterizedTest - @Order(2) - @MethodSource("nonCompatibleQuarkusBuildTasks") - public void quarkusBuildTasksNonCompatibleWithConfigurationCacheNotFail(String taskName) - throws IOException, URISyntaxException { - URL url = getClass().getClassLoader().getResource("io/quarkus/gradle/tasks/configurationcache/main"); - FileUtils.copyDirectory(new File(url.toURI()), testProjectDir.toFile()); - FileUtils.copyFile(new File("../gradle.properties"), testProjectDir.resolve("gradle.properties").toFile()); - - BuildResult build = buildResult(taskName); - assertTrue(build.getOutput().contains("BUILD SUCCESSFUL")); - - } - - @ParameterizedTest - @MethodSource("nonCompatibleQuarkusBuildTasks") - @Order(3) - public void quarkusBuildTasksNonCompatibleWithConfigurationCacheNotFailWhenUsingConfigurationCache(String taskName) - throws IOException, URISyntaxException { - URL url = getClass().getClassLoader().getResource("io/quarkus/gradle/tasks/configurationcache/main"); - FileUtils.copyDirectory(new File(url.toURI()), testProjectDir.toFile()); - FileUtils.copyFile(new File("../gradle.properties"), testProjectDir.resolve("gradle.properties").toFile()); - - BuildResult build = buildResult(taskName, "--no-configuration-cache"); - assertTrue(build.getOutput().contains("BUILD SUCCESSFUL")); - - } - - private BuildResult buildResult(String task, String configurationCacheCommand) { - return GradleRunner.create() - .withPluginClasspath() - .withProjectDir(testProjectDir.toFile()) - .withArguments(task, "--info", "--stacktrace", "--build-cache", configurationCacheCommand) - .build(); - } - - private BuildResult buildResult(String task) { - return GradleRunner.create() - .withPluginClasspath() - .withProjectDir(testProjectDir.toFile()) - .withArguments(task, "--info", "--stacktrace", "--build-cache") - .build(); - } -} diff --git a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/build.gradle.kts b/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/build.gradle.kts deleted file mode 100644 index ff2d8c50f84f8..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -plugins { - java - id("io.quarkus") -} - -buildscript { - repositories { - mavenLocal() - mavenCentral() - } -} - -repositories { - mavenLocal() - mavenCentral() -} - -dependencies { - implementation(enforcedPlatform("io.quarkus:quarkus-bom:${project.property("version")}")) - implementation("jakarta.inject:jakarta.inject-api:2.0.1") -} - -quarkus { - quarkusBuildProperties.put("quarkus.foo", "bar") - manifest { - attributes(mapOf("Manifest-Attribute" to "some-value")) - } - - // The following line is replaced by the tests in `TasksConfigurationCacheCompatibilityTest` - // ADDITIONAL_CONFIG -} diff --git a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/settings.gradle.kts b/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/settings.gradle.kts deleted file mode 100644 index c35dae34f86ef..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/settings.gradle.kts +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = "configuration-cache" diff --git a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/src/main/java/org/acme/Foo.java b/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/src/main/java/org/acme/Foo.java deleted file mode 100644 index 8f4e8542598f4..0000000000000 --- a/devtools/gradle/gradle-application-plugin/src/test/resources/io/quarkus/gradle/tasks/configurationcache/main/src/main/java/org/acme/Foo.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.acme; - -public class Foo { -} \ No newline at end of file diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java index ec5fb1bf5f1e8..ffc0564ff65e0 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -20,7 +19,6 @@ import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.ResolvedDependency; import org.gradle.api.artifacts.dsl.DependencyHandler; -import org.gradle.api.file.FileCollection; import org.gradle.api.internal.artifacts.dependencies.DefaultDependencyArtifact; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; import org.gradle.api.plugins.JavaPlugin; @@ -97,30 +95,6 @@ public static void initConfigurations(Project project) { }); } - private static Configuration[] getOriginalRuntimeClasspaths(Project project, LaunchMode mode) { - List configurationNames; - switch (mode) { - case TEST: - configurationNames = List.of(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME); - break; - case NORMAL: - configurationNames = List.of(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); - break; - case DEVELOPMENT: - configurationNames = List.of( - ToolingUtils.DEV_MODE_CONFIGURATION_NAME, - JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME, - JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); - break; - default: - throw new IllegalArgumentException("Unexpected mode: " + mode); - } - ConfigurationContainer configContainer = project.getConfigurations(); - return configurationNames.stream() - .map(configContainer::getByName) - .toArray(Configuration[]::new); - } - private final Project project; private final LaunchMode mode; @@ -268,15 +242,11 @@ private void setUpCompileOnlyConfiguration() { } } - public FileCollection getOriginalRuntimeClasspathAsInput() { - return project.files((Object[]) getOriginalRuntimeClasspaths(project, mode)); - } - public Configuration getPlatformConfiguration() { return project.getConfigurations().getByName(this.platformConfigurationName); } - public Configuration getRawRuntimeConfiguration() { + private Configuration getRawRuntimeConfiguration() { return project.getConfigurations().getByName(this.runtimeConfigurationName); } diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java index 6a423003ecfbd..06b61927c99fd 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java @@ -627,11 +627,11 @@ private void addSubstitutedProject(PathList.Builder paths, File projectFile) { } } - public static boolean isFlagOn(byte walkingFlags, byte flag) { + private static boolean isFlagOn(byte walkingFlags, byte flag) { return (walkingFlags & flag) > 0; } - public static byte clearFlag(byte flags, byte flag) { + private static byte clearFlag(byte flags, byte flag) { if ((flags & flag) > 0) { flags ^= flag; } diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java index 5d20f796c6d51..861f1ba4c889f 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java @@ -1,7 +1,6 @@ package io.quarkus.gradle.tooling; import java.io.IOException; -import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -161,21 +160,6 @@ public static Path serializeAppModel(ApplicationModel appModel, Task context, bo return serializedModel; } - public static ApplicationModel deserializeAppModel(Path path) throws IOException { - try (ObjectInputStream out = new ObjectInputStream(Files.newInputStream(path))) { - return (ApplicationModel) out.readObject(); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - public static Path serializeAppModel(ApplicationModel appModel, Path serializedModelPath) throws IOException { - try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModelPath))) { - out.writeObject(appModel); - } - return serializedModelPath; - } - public static ApplicationModel create(Project project, LaunchMode mode) { final ModelParameter params = new ModelParameterImpl(); params.setMode(mode.toString()); diff --git a/docs/src/main/asciidoc/gradle-tooling.adoc b/docs/src/main/asciidoc/gradle-tooling.adoc index d0b607b1df823..6cd28b895a85a 100644 --- a/docs/src/main/asciidoc/gradle-tooling.adoc +++ b/docs/src/main/asciidoc/gradle-tooling.adoc @@ -814,33 +814,5 @@ action must be declared as an input of the task. The Quarkus Gradle plugin works with builds that have the link:https://docs.gradle.org/current/userguide/configuration_cache.html[Gradle's configuration cache] enabled, but -the configuration cache is disabled for some of the Quarkus tasks. This means, that the Quarkus plugin does not break such +the configuration cache is disabled for the Quarkus tasks. This means, that the Quarkus plugin does not break such Gradle builds. -The current state of compatibility is shown in the following table: - -[cols="2","4"] -|==== -|Quarkus task|Configuration Cache Compatibility -|`quarkusGenerateCode` |✅ -|`quarkusGenerateCodeDev`|✅ -|`quarkusGenerateCodeTests`|✅ -|`quarkusDependenciesBuild`|✅ -|`quarkusAppPartsBuild`|✅ -|`quarkusShowEffectiveConfig`|✅ -|`quarkusBuild`|✅ -|`quarkusDev`|❌ -|`quarkusRun`|❌ -|`quarkusRemoteDev`|❌ -|`quarkusTest`|❌ -|`quarkusGoOffline`|❌ -|`quarkusInfo`|❌ -|`quarkusUpdate`|❌ -|`imageBuild`|❌ -|`imagePush`|❌ -|`deploy`|❌ -|`listExtensions`|❌ -|`listCategories`|❌ -|`listPlatforms`|❌ -|`addExtension`|❌ -|`removeExtension`|❌ -|==== diff --git a/integration-tests/gradle/src/main/resources/implementation-files/application-files/build.gradle b/integration-tests/gradle/src/main/resources/implementation-files/application-files/build.gradle index 93b08ea565138..3a102c326eb0f 100644 --- a/integration-tests/gradle/src/main/resources/implementation-files/application-files/build.gradle +++ b/integration-tests/gradle/src/main/resources/implementation-files/application-files/build.gradle @@ -1,4 +1,4 @@ -import io.quarkus.gradle.tasks.QuarkusApplicationModelTask +import io.quarkus.gradle.tasks.QuarkusGenerateCode plugins { id 'io.quarkus' @@ -8,4 +8,4 @@ dependencies { implementation files("../common/build/libs/common.jar") } -tasks.withType(QuarkusApplicationModelTask).configureEach { t -> t.dependsOn(project(":common").tasks.named("jar")) } +tasks.withType(QuarkusGenerateCode).configureEach { t -> t.dependsOn(project(":common").tasks.named("jar")) } diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/nativeimage/BasicJavaNativeBuildIT.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/nativeimage/BasicJavaNativeBuildIT.java index 09a1d0dd5cfa6..ed700225f2397 100644 --- a/integration-tests/gradle/src/test/java/io/quarkus/gradle/nativeimage/BasicJavaNativeBuildIT.java +++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/nativeimage/BasicJavaNativeBuildIT.java @@ -19,7 +19,6 @@ public class BasicJavaNativeBuildIT extends QuarkusNativeGradleITBase { @Test public void shouldBuildNativeImage() throws Exception { final File projectDir = getProjectDir("basic-java-native-module"); - gradleConfigurationCache(false); final BuildResult build = runGradleWrapper(projectDir, "clean", "buildNative"); @@ -48,7 +47,6 @@ public void shouldBuildNativeImage() throws Exception { @Test public void shouldBuildNativeImageWithCustomName() throws Exception { final File projectDir = getProjectDir("basic-java-native-module"); - gradleConfigurationCache(false); final BuildResult build = runGradleWrapper(projectDir, "clean", "buildNative", "-Dquarkus.package.output-name=test"); @@ -79,7 +77,6 @@ public void shouldBuildNativeImageWithCustomName() throws Exception { @Test public void shouldBuildNativeImageWithCustomNameWithoutSuffix() throws Exception { final File projectDir = getProjectDir("basic-java-native-module"); - gradleConfigurationCache(false); final BuildResult build = runGradleWrapper(projectDir, "clean", "buildNative", "-Dquarkus.package.output-name=test", "-Dquarkus.package.jar.add-runner-suffix=false");