forked from hibernate/hibernate-orm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
source-generation.gradle
171 lines (144 loc) · 6.84 KB
/
source-generation.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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
}
}