172 lines
6.8 KiB
Groovy
172 lines
6.8 KiB
Groovy
import java.util.concurrent.Callable
|
|
|
|
apply plugin: SourceGenerationPlugin
|
|
|
|
/**
|
|
* A plugin for dealing with AnnotationProcessor-based source generation.
|
|
* <p/>
|
|
* Creates (or reuses) a grouping task named `generateSources` which is responsible
|
|
* for coordinating (via task deps) the running of all source-generation tasks.
|
|
* <p/>
|
|
* Additionally a grouping task is created for each SourceSet to hold the generation
|
|
* task for that SourceSet. This task is named following the `run{SourceSet.name}SourceGenerators`.
|
|
* This task is also injected into the SourceSet as `sourceGeneratorsTask` for scripts to access
|
|
*/
|
|
class SourceGenerationPlugin implements Plugin<Project> {
|
|
public static final String GROUP = "sourceGeneration";
|
|
public static final String GENERATE_SOURCES_TASK_NAME = "generateSources";
|
|
|
|
@Override
|
|
public void apply(Project project) {
|
|
final JavaPluginConvention javaPluginConvention = project.getConvention().findPlugin( JavaPluginConvention.class );
|
|
if ( javaPluginConvention == null ) {
|
|
// something seriously awry
|
|
return;
|
|
}
|
|
|
|
project.convention.plugins[GROUP] = new SourceGenerationPluginConvention( project );
|
|
|
|
// first set up the overall generateSources task
|
|
Task generateSourcesTask = project.getTasks().findByName( GENERATE_SOURCES_TASK_NAME );
|
|
if ( generateSourcesTask == null ) {
|
|
generateSourcesTask = project.getTasks().create( GENERATE_SOURCES_TASK_NAME );
|
|
generateSourcesTask.setGroup( GROUP );
|
|
generateSourcesTask.setDescription( "Grouping task for all source generation tasks" );
|
|
}
|
|
|
|
// for each source set, define the specific grouping tasks (and associate with the generateSources as a
|
|
// task dependency)
|
|
for ( SourceSet sourceSet : javaPluginConvention.getSourceSets() ) {
|
|
final ExtraPropertiesExtension extProps = ( (ExtensionAware) sourceSet ).getExtensions().getExtraProperties();
|
|
|
|
// find the main javac task for this sourceSet (so we can add dependsOn to it)
|
|
final JavaCompile javaCompileTask = (JavaCompile) project.getTasks().getByName( sourceSet.getCompileJavaTaskName() );
|
|
|
|
// create the pre-apt generation grouping task
|
|
final String sourceGeneratorsTaskName = sourceSet.getTaskName( "run", "sourceGenerators" );
|
|
final Task sourceGeneratorsTask = project.getTasks().create( sourceGeneratorsTaskName );
|
|
sourceGeneratorsTask.setGroup( GROUP );
|
|
sourceGeneratorsTask.setDescription(
|
|
String.format(
|
|
"Grouping task for running all source generation tasks for the %s source-set of the %s project",
|
|
sourceSet.getName(),
|
|
project.getName()
|
|
)
|
|
);
|
|
generateSourcesTask.dependsOn( sourceGeneratorsTask );
|
|
javaCompileTask.dependsOn( sourceGeneratorsTask );
|
|
|
|
final File aptDir = new File( new File( project.getBuildDir(), "generated-src/apt" ), sourceSet.name );
|
|
javaCompileTask.options.compilerArgs += [ "-s", aptDir.absolutePath ];
|
|
javaCompileTask.doFirst({
|
|
if ( !aptDir.exists() ) {
|
|
if ( !aptDir.mkdirs() ) {
|
|
project.logger.warn( "Unable to create APT dir : " + aptDir.absolutePath )
|
|
}
|
|
}
|
|
})
|
|
|
|
generateSourcesTask.dependsOn( javaCompileTask )
|
|
|
|
extProps.set( "sourceGeneratorsTask", sourceGeneratorsTask );
|
|
extProps.set( "aptDir", aptDir );
|
|
}
|
|
}
|
|
}
|
|
|
|
class SourceGenerationPluginConvention {
|
|
public static final String METAGEN_DEPENDENCY_CONFIG_NAME = "hibernateJpaModelGenTool";
|
|
public static final String METAGEN_PROCESSOR_NAME = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor";
|
|
|
|
private final Project project;
|
|
|
|
// practicality says we only ever deal with 2 source-sets:
|
|
private JavaCompile mainProcOnlyTask;
|
|
private JavaCompile testProcOnlyTask;
|
|
|
|
SourceGenerationPluginConvention(Project project) {
|
|
this.project = project
|
|
}
|
|
|
|
/**
|
|
* Exposed to the build scripts to be able to apply JPA Metamodel Generation support to the
|
|
* SourceSet it specifies.
|
|
*
|
|
* @param sourceSet The SourceSet to which JPA Metamodel Generation support should be applied.
|
|
*/
|
|
public void addMetaGenProcessor(SourceSet sourceSet) {
|
|
if ( sourceSet.name.equals( "main" ) ) {
|
|
if ( mainProcOnlyTask == null ) {
|
|
mainProcOnlyTask = generateProcessorOnlyTask( sourceSet )
|
|
}
|
|
}
|
|
else if ( sourceSet.name.equals( "test" ) ) {
|
|
if ( testProcOnlyTask == null ) {
|
|
testProcOnlyTask = generateProcessorOnlyTask( sourceSet )
|
|
}
|
|
}
|
|
else {
|
|
throw new IllegalArgumentException( "SourceSet (" + sourceSet.name + ") not valid for source generation" )
|
|
}
|
|
}
|
|
|
|
private JavaCompile generateProcessorOnlyTask(SourceSet sourceSet) {
|
|
final File targetDir = sourceSet.aptDir;
|
|
|
|
// find the main javac task for this sourceSet (we will alter it a bit later on)
|
|
final JavaCompile javaCompileTask = (JavaCompile) project.getTasks().getByName( sourceSet.getCompileJavaTaskName() );
|
|
|
|
final ExtraPropertiesExtension extProps = ( (ExtensionAware) sourceSet ).getExtensions().getExtraProperties();
|
|
|
|
final String aptTaskName = sourceSet.getTaskName( "run", "annotationProcessors" );
|
|
// final AnnotationProcessorOnlyTask aptTask = project.getTasks().create( aptTaskName, AnnotationProcessorOnlyTask.class );
|
|
final JavaCompile aptTask = project.getTasks().create( aptTaskName, JavaCompile.class );
|
|
aptTask.options.compilerArgs += [
|
|
"-nowarn",
|
|
"-proc:only",
|
|
"-encoding", "UTF-8",
|
|
"-s", targetDir.getAbsolutePath(),
|
|
"-processor", METAGEN_PROCESSOR_NAME
|
|
]
|
|
|
|
aptTask.setGroup( SourceGenerationPlugin.GROUP );
|
|
aptTask.setDescription(
|
|
String.format(
|
|
"Grouping task for running all AnnotationProcessors (javac -proc:only) for the %s sourceSet of the %s project",
|
|
sourceSet.getName(),
|
|
project.getName()
|
|
)
|
|
);
|
|
|
|
// sourceSet.getAllJava() returns a SourceDirectorySet which is a "live view" meaning it keeps expanding
|
|
// even as we add to it. The problem is that later on here we will add the output directory of this task
|
|
// to this SourceDirectorySet; we need to make sure that we use the view of the SourceDirectorySet *before* that
|
|
// happens as the source for this task. getSrcDirs() does that
|
|
aptTask.source( sourceSet.getAllJava() )
|
|
aptTask.destinationDir = targetDir
|
|
|
|
aptTask.setSourceCompatibility( javaCompileTask.getSourceCompatibility() );
|
|
aptTask.setTargetCompatibility( javaCompileTask.getTargetCompatibility() );
|
|
aptTask.setDependencyCacheDir( javaCompileTask.getDependencyCacheDir() );
|
|
|
|
aptTask.getConventionMapping().map(
|
|
"classpath",
|
|
new Callable<FileCollection>() {
|
|
public FileCollection call() throws Exception {
|
|
return javaCompileTask.getClasspath() + project.configurations[METAGEN_DEPENDENCY_CONFIG_NAME]
|
|
}
|
|
}
|
|
);
|
|
|
|
aptTask.mustRunAfter( extProps.get( "sourceGeneratorsTask" ) );
|
|
javaCompileTask.dependsOn( aptTask );
|
|
project.tasks.findByName( SourceGenerationPlugin.GENERATE_SOURCES_TASK_NAME ).dependsOn( aptTask )
|
|
|
|
// Add the APT output dir to the source set
|
|
// - so that the generated sources get compiled during main javac
|
|
sourceSet.getJava().srcDir( targetDir );
|
|
return aptTask
|
|
}
|
|
}
|
|
|