[jOOQ/jOOQ#16318] Allow for specifying inputs to the gradle CodegenTask

in order to participate in incremental builds
This commit is contained in:
Lukas Eder 2024-06-12 11:38:57 +02:00
parent 162ae33f6e
commit 12ac2d781b
3 changed files with 55 additions and 40 deletions

View File

@ -40,22 +40,10 @@ package org.jooq.codegen.gradle;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskProvider;
import org.jetbrains.annotations.NotNull;
import org.jooq.tools.StringUtils;
import org.jooq.util.jaxb.tools.MiniJAXB;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
* The jOOQ Codegen Plugin
@ -88,12 +76,11 @@ public class CodegenPlugin implements Plugin<Project> {
CodegenTask.class,
configuration,
codegenClasspath
).configure(configureTask(project, named, configuration));
).configure(configureTask(named, configuration));
});
}
private static Action<CodegenTask> configureTask(
Project project,
List<NamedConfiguration> named,
NamedConfiguration configuration
) {
@ -107,19 +94,7 @@ public class CodegenPlugin implements Plugin<Project> {
task.setDescription("jOOQ code generation" + (configuration.unnamed ? " for all executions" : " for the " + configuration.name + " execution"));
task.setGroup("jOOQ");
task.doFirst(t -> {
SourceSetContainer source = project
.getExtensions()
.findByType(SourceSetContainer.class);
if (source != null) {
source.configureEach(sourceSet -> {
if (sourceSet.getName().equals("main"))
sourceSet.getJava().srcDir(task.getOutputDirectory());
});
}
});
task.doFirst(CodegenTask::registerSourceSet);
};
}
}

View File

@ -39,17 +39,17 @@ package org.jooq.codegen.gradle;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.Directory;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.*;
import org.gradle.work.InputChanges;
import org.jooq.codegen.GenerationTool;
import org.jooq.meta.jaxb.Target;
import org.jooq.tools.StringUtils;
import javax.inject.Inject;
@ -59,7 +59,8 @@ import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static java.lang.Boolean.FALSE;
/**
* The code generation task.
@ -71,20 +72,59 @@ public class CodegenTask extends DefaultTask {
final FileCollection codegenClasspath;
final ProviderFactory providers;
final List<NamedConfiguration> named;
final Property<Boolean> caching;
final Project project;
@Inject
public CodegenTask(
NamedConfiguration configuration,
FileCollection codegenClasspath,
ProviderFactory providers
ProviderFactory providers,
ObjectFactory objects,
Project project
) {
this.configuration = configuration;
this.providers = providers;
this.codegenClasspath = codegenClasspath;
this.named = new ArrayList<>();
this.caching = objects.property(Boolean.class).convention(true);
this.project = project;
// [#16275] [#16316] This default produces unnecessary re-generations of code. We currently don't know our inputs.
getOutputs().upToDateWhen(task -> false);
getOutputs().cacheIf("Caching is activated only in the presence of explicit inputs and when output isn't up to date", CodegenTask::upToDate);
// [#16318] When the task is up-to-date, we still have to register our source set contributions, which
// apparently aren't being cached by gradle's build cache.
getOutputs().upToDateWhen(task -> upToDate(task) && registerSourceSet(task));
}
static boolean registerSourceSet(Task t) {
if (t instanceof CodegenTask task) {
SourceSetContainer source = task.project
.getExtensions()
.findByType(SourceSetContainer.class);
if (source != null)
source.named("main", sourceSet -> sourceSet.getJava().srcDir(task.getOutputDirectory()));
}
return true;
}
@SuppressWarnings("unchecked")
static boolean upToDate(Task task) {
// [#16318] Allow for turning off the feature
if (task.hasProperty("caching") && FALSE.equals(((Property<Boolean>) task.property("caching")).get()))
return false;
TaskInputs inputs = task.getInputs();
// [#16318] .jar files from the classpath don't count as inputs
return !inputs.getFiles().filter(f -> !f.getName().endsWith(".jar")).isEmpty()
|| inputs.getHasSourceFiles()
// There are input properties other than our own declared @Input
|| inputs.getProperties().size() > 2;
}
@TaskAction
@ -109,12 +149,17 @@ public class CodegenTask extends DefaultTask {
}
@Input
public Provider<String> getInput() {
public Provider<String> getConfiguration() {
return providers.provider(() ->
configuration.getConfiguration().toString()
);
}
@Input
public Property<Boolean> getCaching() {
return caching;
}
@Classpath
public FileCollection getClasspath() {
return codegenClasspath;

View File

@ -39,11 +39,9 @@ package org.jooq.codegen.gradle;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.jooq.codegen.GenerationTool;
import org.jooq.meta.jaxb.Configuration;
import org.jooq.meta.jaxb.Generator;
@ -53,9 +51,6 @@ import org.jooq.codegen.gradle.MetaExtensions.*;
import javax.inject.Inject;
import groovy.lang.*;
import org.codehaus.groovy.runtime.*;
import java.io.File;
/**