Skip to content

Commit

Permalink
Use SourceSetContainer and lazy APIs in Gradle plugins
Browse files Browse the repository at this point in the history
Signed-off-by: Konstantin Gribov <[email protected]>
  • Loading branch information
grossws committed Jul 9, 2022
1 parent 60fd34f commit fc43c9b
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import javax.inject.Inject;
Expand All @@ -21,7 +20,6 @@
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskContainer;
Expand Down Expand Up @@ -166,24 +164,9 @@ private void registerTasks(Project project, QuarkusPluginExtension quarkusExt) {

configureBuildNativeTask(project);

final Consumer<Test> configureTestTask = t -> {
// Quarkus test configuration action which should be executed before any Quarkus test
// Use anonymous classes in order to leverage task avoidance.
t.doFirst(new Action<Task>() {
@Override
public void execute(Task test) {
quarkusExt.beforeTest(t);
}
});
// also make each task use the JUnit platform since it's the only supported test environment
t.useJUnitPlatform();
// quarkusBuild is expected to run after the project has passed the tests
quarkusBuild.configure(task -> task.shouldRunAfter(t));
};

project.getPlugins().withType(
BasePlugin.class,
basePlugin -> tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(quarkusBuild));
basePlugin -> tasks.named(BasePlugin.ASSEMBLE_TASK_NAME, task -> task.dependsOn(quarkusBuild)));
project.getPlugins().withType(
JavaPlugin.class,
javaPlugin -> {
Expand Down Expand Up @@ -245,8 +228,7 @@ public void execute(Task test) {
quarkusBuild.configure(
task -> task.dependsOn(classesTask, resourcesTask, tasks.named(JavaPlugin.JAR_TASK_NAME)));

SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);

SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME);
Expand Down Expand Up @@ -295,8 +277,20 @@ public void execute(Task test) {
testNative.setClasspath(nativeTestSourceSet.getRuntimeClasspath());
});

tasks.withType(Test.class).forEach(configureTestTask);
tasks.withType(Test.class).whenTaskAdded(configureTestTask::accept);
tasks.withType(Test.class).configureEach(t -> {
// Quarkus test configuration action which should be executed before any Quarkus test
// Use anonymous classes in order to leverage task avoidance.
t.doFirst(new Action<Task>() {
@Override
public void execute(Task task) {
quarkusExt.beforeTest(t);
}
});
// also make each task use the JUnit platform since it's the only supported test environment
t.useJUnitPlatform();
});
// quarkusBuild is expected to run after the project has passed the tests
quarkusBuild.configure(task -> task.shouldRunAfter(tasks.withType(Test.class)));

SourceSet generatedSourceSet = sourceSets.create(QuarkusGenerateCode.QUARKUS_GENERATED_SOURCES);
SourceSet generatedTestSourceSet = sourceSets.create(QuarkusGenerateCode.QUARKUS_TEST_GENERATED_SOURCES);
Expand Down Expand Up @@ -384,8 +378,7 @@ private void afterEvaluate(Project project) {
.sourceSetExtension();

if (sourceSetExtension.extraNativeTest() != null) {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
SourceSet nativeTestSourceSets = sourceSets.getByName(NATIVE_TEST_SOURCE_SET_NAME);
nativeTestSourceSets.setCompileClasspath(
nativeTestSourceSets.getCompileClasspath()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

import org.gradle.api.GradleException;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.CompileClasspath;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskAction;

import io.quarkus.bootstrap.BootstrapException;
Expand Down Expand Up @@ -108,42 +108,39 @@ public void prepareQuarkus() {
.setIsolateDeployment(true)
.build().bootstrap()) {

final JavaPluginConvention javaConvention = getProject().getConvention().findPlugin(JavaPluginConvention.class);
if (javaConvention != null) {
final String generateSourcesDir = test ? QUARKUS_TEST_GENERATED_SOURCES : QUARKUS_GENERATED_SOURCES;
final SourceSet generatedSources = javaConvention.getSourceSets().findByName(generateSourcesDir);
List<Path> paths = new ArrayList<>();
generatedSources.getOutput()
.filter(f -> f.getName().equals(generateSourcesDir))
.forEach(f -> paths.add(f.toPath()));
if (paths.isEmpty()) {
throw new GradleException("Failed to create quarkus-generated-sources");
}

getLogger().debug("Will trigger preparing sources for source directory: {} buildDir: {}",
sourcesDirectories, getProject().getBuildDir().getAbsolutePath());

QuarkusClassLoader deploymentClassLoader = appCreationContext.createDeploymentClassLoader();
Class<?> codeGenerator = deploymentClassLoader.loadClass(CodeGenerator.class.getName());

Optional<Method> initAndRun = Arrays.stream(codeGenerator.getMethods())
.filter(m -> m.getName().equals(INIT_AND_RUN))
.findAny();
if (initAndRun.isEmpty()) {
throw new GradleException("Failed to find " + INIT_AND_RUN + " method in " + CodeGenerator.class.getName());
}

initAndRun.get().invoke(null, deploymentClassLoader,
PathList.from(sourcesDirectories),
paths.get(0),
buildDir,
sourceRegistrar,
appCreationContext.getApplicationModel(),
realProperties,
launchMode.name(),
test);
SourceSetContainer sourceSets = getProject().getExtensions().getByType(SourceSetContainer.class);
final String generateSourcesDir = test ? QUARKUS_TEST_GENERATED_SOURCES : QUARKUS_GENERATED_SOURCES;
final SourceSet generatedSources = sourceSets.findByName(generateSourcesDir);
List<Path> paths = new ArrayList<>();
generatedSources.getOutput()
.filter(f -> f.getName().equals(generateSourcesDir))
.forEach(f -> paths.add(f.toPath()));
if (paths.isEmpty()) {
throw new GradleException("Failed to create quarkus-generated-sources");
}

getLogger().debug("Will trigger preparing sources for source directory: {} buildDir: {}",
sourcesDirectories, getProject().getBuildDir().getAbsolutePath());

QuarkusClassLoader deploymentClassLoader = appCreationContext.createDeploymentClassLoader();
Class<?> codeGenerator = deploymentClassLoader.loadClass(CodeGenerator.class.getName());

Optional<Method> initAndRun = Arrays.stream(codeGenerator.getMethods())
.filter(m -> m.getName().equals(INIT_AND_RUN))
.findAny();
if (initAndRun.isEmpty()) {
throw new GradleException("Failed to find " + INIT_AND_RUN + " method in " + CodeGenerator.class.getName());
}

initAndRun.get().invoke(null, deploymentClassLoader,
PathList.from(sourcesDirectories),
paths.get(0),
buildDir,
sourceRegistrar,
appCreationContext.getApplicationModel(),
realProperties,
launchMode.name(),
test);
} catch (BootstrapException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
throw new GradleException("Failed to generate sources in the QuarkusPrepare task", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@

import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;

import io.quarkus.bootstrap.util.IoUtils;

public class QuarkusGradleUtils {

private static final String ERROR_COLLECTING_PROJECT_CLASSES = "Failed to collect project's classes in a temporary dir";

public static SourceSetContainer getSourceSets(Project project) {
return project.getExtensions().getByType(SourceSetContainer.class);
}

public static SourceSet getSourceSet(Project project, String sourceSetName) {
final JavaPluginConvention javaConvention = project.getConvention().findPlugin(JavaPluginConvention.class);
if (javaConvention == null) {
throw new IllegalArgumentException("The project does not include the Java plugin");
}
return javaConvention.getSourceSets().getByName(sourceSetName);
return getSourceSets(project).getByName(sourceSetName);
}

public static String getClassesDir(SourceSet sourceSet, File tmpDir, boolean test) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import org.gradle.api.artifacts.ModuleVersionIdentifier;
import org.gradle.api.artifacts.ResolvedArtifact;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.testing.Test;
Expand Down Expand Up @@ -49,8 +49,8 @@ public void apply(Project project) {
private void registerTasks(Project project, QuarkusExtensionConfiguration quarkusExt) {
TaskContainer tasks = project.getTasks();

JavaPluginConvention convention = project.getConvention().getPlugin(JavaPluginConvention.class);
SourceSet mainSourceSet = convention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME);
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
Configuration runtimeModuleClasspath = project.getConfigurations()
.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);

Expand All @@ -65,7 +65,7 @@ private void registerTasks(Project project, QuarkusExtensionConfiguration quarku
javaPlugin -> {
tasks.named(JavaPlugin.PROCESS_RESOURCES_TASK_NAME, task -> task.finalizedBy(extensionDescriptorTask));
tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME, task -> task.dependsOn(extensionDescriptorTask));
tasks.withType(Test.class, test -> test.useJUnitPlatform());
tasks.withType(Test.class).configureEach(Test::useJUnitPlatform);
addAnnotationProcessorDependency(project);
});

Expand All @@ -84,7 +84,7 @@ private void registerTasks(Project project, QuarkusExtensionConfiguration quarku
task.setDeploymentModuleClasspath(deploymentModuleClasspath);
});

deploymentProject.getTasks().withType(Test.class, test -> {
deploymentProject.getTasks().withType(Test.class).configureEach(test -> {
test.useJUnitPlatform();
test.doFirst(task -> {
final Map<String, Object> props = test.getSystemProperties();
Expand Down
Loading

0 comments on commit fc43c9b

Please sign in to comment.