-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathNebulaFacetPlugin.groovy
More file actions
138 lines (116 loc) · 6.03 KB
/
Copy pathNebulaFacetPlugin.groovy
File metadata and controls
138 lines (116 loc) · 6.03 KB
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
package nebula.plugin.responsible
import nebula.core.NamedContainerProperOrder
import nebula.plugin.responsible.ide.EclipsePluginConfigurer
import nebula.plugin.responsible.ide.IdePluginConfigurer
import nebula.plugin.responsible.ide.IdeaPluginConfigurer
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.plugins.JavaBasePlugin
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.testing.Test
import org.gradle.internal.reflect.Instantiator
class NebulaFacetPlugin implements Plugin<Project> {
Project project
NamedDomainObjectContainer<FacetDefinition> extension
@Override
void apply(Project project) {
this.project = project
extension = container(FacetDefinition, new NamedDomainObjectFactory<FacetDefinition>() {
@Override
FacetDefinition create(String name) {
if (name.contains('Test')) {
return new TestFacetDefinition(name)
} else {
return new FacetDefinition(name)
}
}
})
project.extensions.add('facets', extension)
// TODO Add remove call, to protect against removals
extension.all { FacetDefinition facet ->
// Might have to perform this in afterEvaluate
project.plugins.withType(JavaBasePlugin) {
JavaPluginConvention javaConvention = project.convention.getPlugin(JavaPluginConvention)
SourceSetContainer sourceSets = javaConvention.sourceSets
sourceSets.matching { it.name == facet.parentSourceSet }.all { SourceSet parentSourceSet ->
// Since we're using NamedContainerProperOrder, we're configured already.
SourceSet sourceSet = createSourceSet(parentSourceSet, facet)
Configuration parentCompile = project.configurations.getByName(parentSourceSet.compileConfigurationName)
project.configurations.getByName(sourceSet.compileConfigurationName).extendsFrom(parentCompile)
Configuration parentRuntime = project.configurations.getByName(parentSourceSet.runtimeConfigurationName)
project.configurations.getByName(sourceSet.runtimeConfigurationName).extendsFrom(parentRuntime)
// Make sure at the classes get built as part of build
project.tasks.getByName('build').dependsOn(sourceSet.classesTaskName)
if (facet instanceof TestFacetDefinition) {
Test testTask = createTestTask(facet.testTaskName, sourceSet)
testTask.mustRunAfter(project.tasks.getByName('test'))
if (facet.includeInCheckLifecycle) {
project.tasks.getByName('check').dependsOn(testTask)
}
}
// Idea module.scopes is initialized by the JavaPlugin, without waiting for the Java plugin, we'll
// get an NPE when we access the plus method.
project.plugins.withType(JavaPlugin) {
IdePluginConfigurer idePluginConfigurer = new IdeaPluginConfigurer(project)
idePluginConfigurer.configure(sourceSet, facet)
IdePluginConfigurer eclipsePluginConfigurer = new EclipsePluginConfigurer(project)
eclipsePluginConfigurer.configure(sourceSet, facet)
}
}
}
}
}
/**
* Creates the integration test Gradle task and defines the output directories.
*
* @param sourceSet to be used for the integration test task.
* @return the integration test task, as a Gradle Test object.
*/
Test createTestTask(String testName, SourceSet sourceSet) {
Test task = project.tasks.create(testName, Test)
task.setGroup(JavaBasePlugin.VERIFICATION_GROUP)
task.description("Runs the ${sourceSet.name} tests")
task.reports.html.destination = new File("${project.buildDir}/reports/${sourceSet.name}")
task.reports.junitXml.destination = new File("${project.buildDir}/${sourceSet.name}-results")
task.testClassesDir = sourceSet.output.classesDir
task.classpath = sourceSet.runtimeClasspath
task
}
/**
* Based on the JavaPluginConvention, creates a SourceSet for the appropriate to UsableSourceSet.
*
* @return the new SourceSet
*/
SourceSet createSourceSet(SourceSet parentSourceSet, FacetDefinition set) {
JavaPluginConvention javaConvention = project.convention.getPlugin(JavaPluginConvention)
SourceSetContainer sourceSets = javaConvention.sourceSets
sourceSets.create(set.name) {
compileClasspath += parentSourceSet.output
compileClasspath += parentSourceSet.compileClasspath
runtimeClasspath += it.output + it.compileClasspath
if (set.srcDir != set.name) {
applySrcDirOverride(it, set.srcDir)
}
}
}
void applySrcDirOverride(SourceSet srcSet, String srcDir) {
def srcProperties = ['java', 'resources', 'antlr', 'groovy', 'scala']
srcProperties.each {
if (srcSet.hasProperty(it)) {
srcSet."$it".srcDirs = [ "src/${srcDir}/$it" ]
}
}
}
public <C> NamedContainerProperOrder<C> container(Class<C> type, NamedDomainObjectFactory<C> factory) {
Instantiator instantiator = ((ProjectInternal) project).getServices().get(Instantiator.class);
return instantiator.newInstance(NamedContainerProperOrder.class, type, instantiator, factory);
}
// TODO React to changes on a FacetDefinition, and re-create source set
}