Skip to content

Commit 03c8011

Browse files
committed
Add codegen source dirs to compile tasks instead of to the main source
sets
1 parent 656dcc4 commit 03c8011

File tree

10 files changed

+190
-45
lines changed

10 files changed

+190
-45
lines changed

build-parent/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<!-- These properties are needed in order for them to be resolvable by the generated projects -->
2222
<compiler-plugin.version>${version.compiler.plugin}</compiler-plugin.version>
2323
<kotlin.version>2.2.10</kotlin.version>
24+
<ksp-gradle-plugin.version>2.2.10-2.0.2</ksp-gradle-plugin.version> <!-- Kotlin Symbol Processing plugin used in a test -->
2425
<dokka.version>2.0.0</dokka.version>
2526
<scala.version>2.13.12</scala.version>
2627
<scala-maven-plugin.version>4.9.5</scala-maven-plugin.version>

devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.nio.file.Path;
88
import java.util.HashMap;
99
import java.util.HashSet;
10+
import java.util.List;
1011
import java.util.Map;
1112
import java.util.Optional;
1213
import java.util.Set;
@@ -348,43 +349,36 @@ public boolean isSatisfiedBy(Task t) {
348349

349350
project.afterEvaluate(this::afterEvaluate);
350351

351-
tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile.class,
352-
compileJava -> {
353-
compileJava.mustRunAfter(quarkusGenerateCode);
354-
compileJava.mustRunAfter(quarkusGenerateCodeDev);
355-
});
356-
tasks.named(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME, JavaCompile.class,
357-
compileTestJava -> {
358-
compileTestJava.dependsOn(quarkusGenerateCode);
359-
compileTestJava.dependsOn(quarkusGenerateCodeTests);
360-
if (project.getGradle().getStartParameter().getTaskNames().contains(QUARKUS_DEV_TASK_NAME)) {
361-
compileTestJava.getOptions().setFailOnError(false);
362-
}
363-
});
364-
365352
TaskProvider<Task> classesTask = tasks.named(JavaPlugin.CLASSES_TASK_NAME);
366353
TaskProvider<Task> resourcesTask = tasks.named(JavaPlugin.PROCESS_RESOURCES_TASK_NAME);
367354
TaskProvider<Task> testClassesTask = tasks.named(JavaPlugin.TEST_CLASSES_TASK_NAME);
368355
TaskProvider<Task> testResourcesTask = tasks.named(JavaPlugin.PROCESS_TEST_RESOURCES_TASK_NAME);
369356

357+
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
358+
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
359+
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
360+
370361
quarkusGenerateCode.configure(task -> {
371362
Configuration config = project.getConfigurations().getByName(
372363
ApplicationDeploymentClasspathBuilder.getBaseRuntimeConfigName(LaunchMode.NORMAL));
373364
task.dependsOn(resourcesTask, config);
374365
task.setCompileClasspath(config);
366+
task.setSourcesDirectories(getSourcesParents(mainSourceSet));
375367
});
376368
quarkusGenerateCodeDev.configure(task -> {
377369
Configuration config = project.getConfigurations().getByName(
378370
ApplicationDeploymentClasspathBuilder
379371
.getBaseRuntimeConfigName(LaunchMode.DEVELOPMENT));
380372
task.dependsOn(resourcesTask, config);
381373
task.setCompileClasspath(config);
374+
task.setSourcesDirectories(getSourcesParents(mainSourceSet));
382375
});
383376
quarkusGenerateCodeTests.configure(task -> {
384377
Configuration config = project.getConfigurations().getByName(
385378
ApplicationDeploymentClasspathBuilder.getBaseRuntimeConfigName(LaunchMode.TEST));
386379
task.dependsOn(resourcesTask, config);
387380
task.setCompileClasspath(config);
381+
task.setSourcesDirectories(getSourcesParents(testSourceSet));
388382
});
389383

390384
quarkusDev.configure(task -> {
@@ -403,18 +397,6 @@ public boolean isSatisfiedBy(Task t) {
403397
quarkusBuildCacheableAppParts.configure(
404398
task -> task.dependsOn(classesTask, resourcesTask, tasks.named(JavaPlugin.JAR_TASK_NAME)));
405399

406-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
407-
408-
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
409-
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
410-
411-
mainSourceSet.getJava().srcDirs(quarkusGenerateCode, quarkusGenerateCodeDev);
412-
testSourceSet.getJava().srcDirs(quarkusGenerateCodeTests);
413-
414-
quarkusGenerateCode.configure(task -> task.setSourcesDirectories(getSourcesParents(mainSourceSet)));
415-
quarkusGenerateCodeDev.configure(task -> task.setSourcesDirectories(getSourcesParents(mainSourceSet)));
416-
quarkusGenerateCodeTests.configure(task -> task.setSourcesDirectories(getSourcesParents(testSourceSet)));
417-
418400
SourceSet intTestSourceSet = sourceSets.getByName(INTEGRATION_TEST_SOURCE_SET_NAME);
419401
intTestSourceSet.setCompileClasspath(
420402
intTestSourceSet.getCompileClasspath()
@@ -487,32 +469,69 @@ public boolean isSatisfiedBy(Task t) {
487469
// quarkusBuild is expected to run after the project has passed the tests
488470
quarkusBuildCacheableAppParts.configure(task -> task.shouldRunAfter(tasks.withType(Test.class)));
489471

490-
SourceSet generatedSourceSet = sourceSets.getByName(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES);
491-
SourceSet generatedTestSourceSet = sourceSets.getByName(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES);
492-
493-
project.afterEvaluate(project1 -> {
494-
// Register the quarkus-generated-code
495-
for (String provider : quarkusExt.getCodeGenerationProviders().get()) {
496-
497-
mainSourceSet.getJava().srcDir(
498-
new File(generatedSourceSet.getJava().getClassesDirectory().get().getAsFile(), provider));
499-
testSourceSet.getJava().srcDir(
500-
new File(generatedTestSourceSet.getJava().getClassesDirectory().get().getAsFile(),
501-
provider));
502-
}
503-
});
472+
tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile.class,
473+
compileJava -> {
474+
// quarkusGenerateCode is a dependency
475+
compileJava.dependsOn(quarkusGenerateCode);
476+
// quarkusGenerateCodeDev must run before compileJava in case quarkusDev is the target
477+
compileJava.mustRunAfter(quarkusGenerateCodeDev);
478+
// add the code gen sources
479+
addCodeGenSourceDirs(compileJava,
480+
sourceSets.getByName(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES), quarkusExt);
481+
});
482+
tasks.named(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME, JavaCompile.class,
483+
compileTestJava -> {
484+
compileTestJava.dependsOn(quarkusGenerateCode);
485+
compileTestJava.dependsOn(quarkusGenerateCodeTests);
486+
if (project.getGradle().getStartParameter().getTaskNames().contains(QUARKUS_DEV_TASK_NAME)) {
487+
compileTestJava.getOptions().setFailOnError(false);
488+
}
489+
// add the code gen test sources
490+
addCodeGenSourceDirs(compileTestJava,
491+
sourceSets.getByName(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES), quarkusExt);
492+
});
504493
});
505494

506495
project.getPlugins().withId("org.jetbrains.kotlin.jvm", plugin -> {
507496
quarkusDev.configure(task -> task.shouldPropagateJavaCompilerArgs(false));
508497
tasks.named("compileKotlin", task -> {
509498
task.mustRunAfter(quarkusGenerateCode);
510499
task.mustRunAfter(quarkusGenerateCodeDev);
500+
addCodeGenSourceDirs(task, project.getExtensions().getByType(SourceSetContainer.class)
501+
.getByName(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES), quarkusExt);
502+
});
503+
tasks.named("compileTestKotlin", task -> {
504+
task.dependsOn(quarkusGenerateCodeTests);
505+
addCodeGenSourceDirs(task, project.getExtensions().getByType(SourceSetContainer.class)
506+
.getByName(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES), quarkusExt);
511507
});
512-
tasks.named("compileTestKotlin", task -> task.dependsOn(quarkusGenerateCodeTests));
513508
});
514509
}
515510

511+
private static void addCodeGenSourceDirs(JavaCompile compileJava, SourceSet generatedSourceSet,
512+
QuarkusPluginExtension quarkusExt) {
513+
final File baseDir = generatedSourceSet.getJava().getClassesDirectory().get().getAsFile();
514+
for (String provider : quarkusExt.getCodeGenerationProviders().get()) {
515+
compileJava.source(new File(baseDir, provider));
516+
}
517+
}
518+
519+
private static void addCodeGenSourceDirs(Task compileKotlin, SourceSet generatedSourceSet,
520+
QuarkusPluginExtension quarkusExt) {
521+
final File baseDir = generatedSourceSet.getJava().getClassesDirectory().get().getAsFile();
522+
final List<String> codeGenProviders = quarkusExt.getCodeGenerationProviders().get();
523+
final Object[] codeGenDirs = new Object[codeGenProviders.size()];
524+
for (int i = 0; i < codeGenDirs.length; ++i) {
525+
codeGenDirs[i] = new File(baseDir, codeGenProviders.get(i));
526+
}
527+
try {
528+
var sourcesMethod = compileKotlin.getClass().getMethod("source", Object[].class);
529+
sourcesMethod.invoke(compileKotlin, new Object[] { codeGenDirs });
530+
} catch (Exception e) {
531+
throw new RuntimeException(e);
532+
}
533+
}
534+
516535
private ApplicationDeploymentClasspathBuilder getDeploymentClasspathBuilder(Project project, LaunchMode mode) {
517536
return new ApplicationDeploymentClasspathBuilder(project, mode, taskDependencyFactory);
518537
}

devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/CachingTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
public class CachingTest {
4141
private static final Map<String, TaskOutcome> ALL_SUCCESS = Map.of(
4242
":quarkusGenerateCode", TaskOutcome.SUCCESS,
43-
":quarkusGenerateCodeDev", TaskOutcome.SUCCESS,
4443
":quarkusGenerateCodeTests", TaskOutcome.SUCCESS,
4544
":quarkusAppPartsBuild", TaskOutcome.SUCCESS,
4645
":quarkusDependenciesBuild", TaskOutcome.SUCCESS,
@@ -56,7 +55,6 @@ public class CachingTest {
5655
":build", TaskOutcome.UP_TO_DATE);
5756
public static final Map<String, TaskOutcome> FROM_CACHE = Map.of(
5857
":quarkusGenerateCode", TaskOutcome.FROM_CACHE,
59-
":quarkusGenerateCodeDev", TaskOutcome.SUCCESS,
6058
":quarkusGenerateCodeTests", TaskOutcome.FROM_CACHE,
6159
":quarkusAppPartsBuild", TaskOutcome.FROM_CACHE,
6260
":quarkusDependenciesBuild", TaskOutcome.SUCCESS,
@@ -211,7 +209,7 @@ void gradleCaching(String packageType, boolean simulateCI, String outputDir, @Te
211209
.describedAs("output: %s", result.getOutput())
212210
.containsEntry(":compileJava", TaskOutcome.FROM_CACHE)
213211
.containsEntry(":quarkusGenerateCode", TaskOutcome.FROM_CACHE)
214-
.containsEntry(":quarkusGenerateCodeDev", TaskOutcome.UP_TO_DATE)
212+
.doesNotContainKey(":quarkusGenerateCodeDev")
215213
.containsEntry(":quarkusAppPartsBuild", isFastOrLegacyJar ? TaskOutcome.FROM_CACHE : TaskOutcome.UP_TO_DATE)
216214
.containsEntry(":quarkusDependenciesBuild", isFastOrLegacyJar ? TaskOutcome.SUCCESS : TaskOutcome.UP_TO_DATE)
217215
.containsEntry(":quarkusBuild", simulateCI || isFastJar ? TaskOutcome.SUCCESS : TaskOutcome.FROM_CACHE);

devtools/gradle/gradle-application-plugin/src/test/java/io/quarkus/gradle/tasks/EagerResolutionTaskTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void eagerResolutionConfigurationBuildsSuccessfully(String taskName) thro
4646
String addingQuarkusExtension = """
4747
quarkus {
4848
cachingRelevantProperties.add("FOO_ENV_VAR")
49-
quarkusBuildProperties.put("quarkus.package.type", "fast-jar")
49+
quarkusBuildProperties.put("quarkus.package.jar.type", "fast-jar")
5050
quarkusBuildProperties.putAll(
5151
provider {
5252
tasks
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
plugins {
2+
kotlin("jvm")
3+
kotlin("plugin.allopen")
4+
id("io.quarkus")
5+
id("com.google.devtools.ksp")
6+
}
7+
8+
repositories {
9+
mavenCentral()
10+
mavenLocal()
11+
}
12+
13+
val quarkusPlatformGroupId: String by project
14+
val quarkusPlatformArtifactId: String by project
15+
val quarkusPlatformVersion: String by project
16+
17+
dependencies {
18+
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
19+
implementation("io.quarkus:quarkus-kotlin")
20+
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
21+
implementation("io.quarkus:quarkus-rest")
22+
testImplementation("io.quarkus:quarkus-junit5")
23+
testImplementation("io.rest-assured:rest-assured")
24+
}
25+
26+
group = "org.acme"
27+
version = "1.0.0-SNAPSHOT"
28+
29+
tasks.withType<Test> {
30+
systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
31+
}
32+
allOpen {
33+
annotation("jakarta.ws.rs.Path")
34+
annotation("jakarta.enterprise.context.ApplicationScoped")
35+
annotation("io.quarkus.test.junit.QuarkusTest")
36+
}
37+
38+
kotlin {
39+
compilerOptions {
40+
javaParameters = true
41+
}
42+
}
43+
44+
java {
45+
// test that the sources JAR works with the KSP plugin
46+
withSourcesJar()
47+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
quarkusPluginId=io.quarkus
2+
quarkusPlatformGroupId=io.quarkus
3+
quarkusPlatformArtifactId=quarkus-bom
4+
kotlinVersion=${kotlin.version}
5+
kspVersion=${ksp-gradle-plugin.version}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
pluginManagement {
2+
val quarkusPluginVersion: String by settings
3+
val quarkusPluginId: String by settings
4+
val kotlinVersion: String by settings
5+
val kspVersion: String by settings
6+
repositories {
7+
mavenLocal {
8+
content {
9+
includeGroupByRegex("io.quarkus.*")
10+
includeGroup("org.hibernate.orm")
11+
}
12+
}
13+
mavenCentral()
14+
gradlePluginPortal()
15+
}
16+
plugins {
17+
id(quarkusPluginId) version quarkusPluginVersion
18+
kotlin("jvm") version kotlinVersion
19+
kotlin("plugin.allopen") version kotlinVersion
20+
id("com.google.devtools.ksp") version kspVersion
21+
}
22+
}
23+
rootProject.name="code-with-quarkus"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.acme
2+
3+
import jakarta.ws.rs.GET
4+
import jakarta.ws.rs.Path
5+
import jakarta.ws.rs.Produces
6+
import jakarta.ws.rs.core.MediaType
7+
8+
@Path("/hello")
9+
class GreetingResource {
10+
11+
@GET
12+
@Produces(MediaType.TEXT_PLAIN)
13+
fun hello() = "Hello from Quarkus REST"
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.acme
2+
3+
import io.quarkus.test.junit.QuarkusTest
4+
import io.restassured.RestAssured.given
5+
import org.hamcrest.CoreMatchers.`is`
6+
import org.junit.jupiter.api.Test
7+
8+
@QuarkusTest
9+
class GreetingResourceTest {
10+
11+
@Test
12+
fun testHelloEndpoint() {
13+
given()
14+
.`when`().get("/hello")
15+
.then()
16+
.statusCode(200)
17+
.body(`is`("Hello from Quarkus REST"))
18+
}
19+
20+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.quarkus.gradle;
2+
3+
import java.io.File;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
/**
8+
* Tests compatibility of the KSP plugin with sourcesJar task.
9+
* Previously, the Quarkus plugin added the codegen sources to the main sources and that created a cyclic task dependencies.
10+
*/
11+
public class KspPluginWithSourcesJarTest extends QuarkusGradleWrapperTestBase {
12+
13+
@Test
14+
public void testKspWithSourcesJar() throws Exception {
15+
final File projectDir = getProjectDir("kotlin-ksp");
16+
runGradleWrapper(projectDir, "clean", "build");
17+
}
18+
}

0 commit comments

Comments
 (0)