Skip to content

Commit 42b7423

Browse files
committed
Added support for multiple source sets (issue #11) and basic support for Gradle incremental tasks (issue #10).
When Gradle detects there were no changes to the input files, it won't call Clojure compile task at all.
1 parent 596daf1 commit 42b7423

File tree

1 file changed

+60
-76
lines changed

1 file changed

+60
-76
lines changed

src/main/kotlin/cursive/ClojurePlugin.kt

Lines changed: 60 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import org.gradle.api.Project
2222
import org.gradle.api.file.FileCollection
2323
import org.gradle.api.file.SourceDirectorySet
2424
import org.gradle.api.internal.ConventionTask
25-
import org.gradle.api.internal.HasConvention
2625
import org.gradle.api.internal.file.FileResolver
2726
import org.gradle.api.internal.file.collections.SimpleFileCollection
2827
import org.gradle.api.internal.plugins.DslObject
@@ -34,6 +33,7 @@ import org.gradle.api.plugins.JavaPluginConvention
3433
import org.gradle.api.tasks.SourceSet
3534
import org.gradle.api.tasks.TaskAction
3635
import org.gradle.api.tasks.compile.AbstractCompile
36+
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
3737
import org.gradle.process.JavaForkOptions
3838
import org.gradle.process.internal.DefaultJavaForkOptions
3939
import org.gradle.process.internal.ExecException
@@ -53,60 +53,32 @@ class ClojurePlugin : Plugin<Project> {
5353

5454
override fun apply(project: Project) {
5555
logger.info("Applying ClojurePlugin")
56-
val javaBasePlugin = project.plugins.apply(JavaBasePlugin::class.java)
56+
project.plugins.apply(JavaBasePlugin::class.java)
57+
project.plugins.apply(JavaPlugin::class.java)
58+
5759
val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
5860

59-
project.plugins.apply(JavaPlugin::class.java)
61+
javaPluginConvention.sourceSets?.all { sourceSet ->
62+
val compileTask = createClojureCompileTask(project, sourceSet)
6063

61-
val mainSourceSet = javaPluginConvention.sourceSets?.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
62-
if (mainSourceSet is HasConvention) {
63-
val mainCompileTask = createCompileTask(project, mainSourceSet)
64-
val conventionMapping = mainCompileTask.conventionMapping
65-
conventionMapping.map("classpath", {
66-
mainSourceSet.compileClasspath
67-
.plus(SimpleFileCollection(mainSourceSet.allSource.srcDirs))
68-
.plus(SimpleFileCollection(mainSourceSet.output.classesDir))
69-
})
70-
conventionMapping.map("namespaces", {
71-
mainCompileTask.findNamespaces()
72-
})
73-
}
7464

75-
val testSourceSet = javaPluginConvention.sourceSets?.getByName(SourceSet.TEST_SOURCE_SET_NAME)
76-
if (testSourceSet is HasConvention) {
77-
val testCompileTask = createCompileTask(project, testSourceSet)
78-
79-
val mainSrcDirs = mainSourceSet?.allSource?.srcDirs ?: emptyList<File>()
80-
val testSrcDirs = testSourceSet.allSource.srcDirs
81-
val outputDirs = if (mainSourceSet != null)
82-
listOf(mainSourceSet.output.classesDir, testSourceSet.output.classesDir)
83-
else
84-
listOf(testSourceSet.output.classesDir)
85-
86-
val compileMapping = testCompileTask.conventionMapping
87-
compileMapping.map("classpath", {
88-
testSourceSet.compileClasspath
89-
.plus(SimpleFileCollection(mainSrcDirs + testSrcDirs + outputDirs))
90-
})
91-
compileMapping.map("namespaces", {
92-
testCompileTask.findNamespaces()
93-
})
94-
95-
val testTask = createTestTask(project)
96-
97-
val testRunnerMapping = testTask.conventionMapping
98-
testRunnerMapping.map("classpath", {
99-
testSourceSet.runtimeClasspath.plus(SimpleFileCollection(mainSrcDirs + testSrcDirs + outputDirs))
100-
})
101-
testRunnerMapping.map("namespaces", {
102-
testCompileTask.findNamespaces()
103-
})
104-
105-
testTask.dependsOn(testCompileTask.name)
65+
if (sourceSet.name == SourceSet.TEST_SOURCE_SET_NAME) {
66+
val testTask = createTestTask(project)
67+
68+
val testTaskMapping = testTask.conventionMapping
69+
testTaskMapping.map("classpath", {
70+
sourceSet.runtimeClasspath
71+
})
72+
testTaskMapping.map("namespaces", {
73+
compileTask.findNamespaces()
74+
})
75+
76+
testTask.dependsOn(compileTask.name)
77+
}
10678
}
10779
}
10880

109-
fun createCompileTask(project: Project, sourceSet: SourceSet): ClojureCompiler {
81+
fun createClojureCompileTask(project: Project, sourceSet: SourceSet): ClojureCompile {
11082
val projectInternal = project as ProjectInternal
11183
val sourceRootDir: String = "src/${sourceSet.name}/clojure"
11284

@@ -124,26 +96,32 @@ class ClojurePlugin : Plugin<Project> {
12496
sourceSet.resources?.filter?.exclude { clojureDirSet.contains(it.file) }
12597

12698
val name = sourceSet.getCompileTaskName("clojure")
127-
val compilerClass = ClojureCompiler::class.java
128-
logger.info("Creating Clojure compile task $name with class $compilerClass")
129-
val compile = project.tasks.create(name, compilerClass)
130-
compile.description = "Compiles the $sourceSet Clojure code"
131-
132-
val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName)
133-
if (javaTask != null) {
134-
compile.dependsOn(javaTask.name)
99+
val clojureCompileClass = ClojureCompile::class.java
100+
logger.info("Creating Clojure compile task $name with class $clojureCompileClass")
101+
val clojureCompileTask = project.tasks.create(name, clojureCompileClass)
102+
clojureCompileTask.description = "Compiles the $sourceSet Clojure code"
103+
104+
val javaCompileTask = project.tasks.findByName(sourceSet.compileJavaTaskName)
105+
if (javaCompileTask != null) {
106+
clojureCompileTask.dependsOn(javaCompileTask.name)
135107
}
136108

137-
project.tasks.findByName(sourceSet.classesTaskName)?.dependsOn(compile.name)
109+
project.tasks.findByName(sourceSet.classesTaskName)?.dependsOn(clojureCompileTask.name)
138110

139-
val conventionMapping = compile.conventionMapping
111+
val conventionMapping = clojureCompileTask.conventionMapping
112+
conventionMapping.map("classpath", {
113+
sourceSet.compileClasspath
114+
})
115+
conventionMapping.map("namespaces", {
116+
clojureCompileTask.findNamespaces()
117+
})
140118
conventionMapping.map("destinationDir", {
141119
sourceSet.output.classesDir
142120
})
143121

144-
compile.source(clojureDirSet)
122+
clojureCompileTask.source(clojureDirSet)
145123

146-
return compile
124+
return clojureCompileTask
147125
}
148126
}
149127

@@ -161,7 +139,6 @@ fun createTestTask(project: Project): ClojureTestRunner {
161139
return testRunner
162140
}
163141

164-
165142
interface ClojureSourceSet {
166143
fun getClojure(): SourceDirectorySet
167144
fun clojure(configureClosure: Closure<Any?>?): ClojureSourceSet
@@ -178,14 +155,14 @@ open class ClojureSourceSetImpl(displayName: String?, resolver: FileResolver?) :
178155
override fun getClojure(): SourceDirectorySet = clojure
179156

180157
override fun clojure(configureClosure: Closure<Any?>?): ClojureSourceSet {
181-
ApiFacade.configureByClosure(this, configureClosure)
158+
ApiFacade.configureByClosure(clojure, configureClosure)
182159
return this
183160
}
184161
}
185162

186163
class ReflectionWarnings(var enabled: Boolean, var projectOnly: Boolean, var asErrors: Boolean)
187164

188-
open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
165+
open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
189166
AbstractCompile(),
190167
JavaForkOptions by DefaultJavaForkOptions(fileResolver) {
191168

@@ -205,8 +182,15 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
205182
}
206183

207184
@TaskAction
185+
fun compile(inputs: IncrementalTaskInputs) {
186+
compile()
187+
}
188+
208189
override fun compile() {
209-
logger.info("Starting ClojureCompiler task")
190+
logger.info("Starting ClojureCompile task")
191+
192+
destinationDir.deleteRecursively()
193+
destinationDir.mkdirs()
210194

211195
if (copySourceToOutput ?: !aotCompile) {
212196
project.copy {
@@ -240,8 +224,6 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
240224
"(System/exit 0)")
241225
.joinToString("\n")
242226

243-
// println(script)
244-
245227
val stdout = object : LineProcessingOutputStream() {
246228
override fun processLine(line: String) {
247229
System.out.print(line)
@@ -293,12 +275,16 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
293275
out.write("$script\n")
294276
}
295277

296-
// println("Classpath: " + classpath.joinToString(", "))
297-
298278
val exec = JavaExecHandleBuilder(fileResolver)
299279
copyTo(exec)
300280
exec.main = "clojure.main"
301-
exec.classpath = classpath
281+
282+
// clojure.core/compile requires following on its classpath:
283+
// - libs (this.classpath)
284+
// - compiled namespaces sources (getSourceRootsFiles)
285+
// - *compile-path* directory (this.destinationDir)
286+
exec.classpath = classpath + SimpleFileCollection(getSourceRootsFiles()) + SimpleFileCollection(destinationDir)
287+
302288
exec.setArgs(listOf("-i", file.canonicalPath))
303289
exec.defaultCharacterEncoding = "UTF8"
304290

@@ -329,10 +315,8 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
329315
}
330316

331317
val sources = getSource()
332-
// println("Sources: " + sources.joinToString(", "))
333318
val roots = getSourceRoots()
334-
// println("Roots: " + roots.joinToString(", "))
335-
val namespaces = sources.map { findNamespace(it, roots) }.toList()
319+
val namespaces = sources.map { findNamespace(it, roots) }
336320
return namespaces
337321
}
338322

@@ -345,6 +329,10 @@ open class ClojureCompiler @Inject constructor(val fileResolver: FileResolver) :
345329
return roots
346330
}
347331

332+
private fun getSourceRootsFiles(): List<File> {
333+
return getSourceRoots().map(::File)
334+
}
335+
348336
companion object {
349337
val CHAR_MAP = mapOf('-' to "_",
350338
':' to "_COLON_",
@@ -440,8 +428,6 @@ open class ClojureTestRunner @Inject constructor(val fileResolver: FileResolver)
440428

441429
val script = "$testRunnerScript\n$runnerInvocation"
442430

443-
// println(script)
444-
445431
executeScript(script)
446432
}
447433

@@ -453,8 +439,6 @@ open class ClojureTestRunner @Inject constructor(val fileResolver: FileResolver)
453439

454440
val classpath = conventionMapping.getConventionValue<FileCollection>(SimpleFileCollection(), "classpath", false)
455441

456-
// println("Classpath: " + classpath.joinToString(", "))
457-
458442
val exec = JavaExecHandleBuilder(fileResolver)
459443
copyTo(exec)
460444
exec.main = "clojure.main"

0 commit comments

Comments
 (0)