@@ -34,6 +34,7 @@ import org.gradle.api.tasks.SourceSet
3434import org.gradle.api.tasks.TaskAction
3535import org.gradle.api.tasks.compile.AbstractCompile
3636import org.gradle.api.tasks.incremental.IncrementalTaskInputs
37+ import org.gradle.api.tasks.incremental.InputFileDetails
3738import org.gradle.process.JavaForkOptions
3839import org.gradle.process.internal.DefaultJavaForkOptions
3940import org.gradle.process.internal.ExecException
@@ -181,17 +182,19 @@ open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
181182 return reflectionWarnings
182183 }
183184
184- @TaskAction
185- fun compile (inputs : IncrementalTaskInputs ) {
186- compile()
185+ override fun compile () {
186+ throw UnsupportedOperationException ()
187187 }
188188
189- override fun compile () {
189+ @TaskAction
190+ fun compile (inputs : IncrementalTaskInputs ) {
190191 logger.info(" Starting ClojureCompile task" )
191192
192- destinationDir.deleteRecursively()
193193 destinationDir.mkdirs()
194194
195+ inputs.outOfDate { removeOutputFilesDerivedFromInputFile(it, destinationDir) }
196+ inputs.removed { removeOutputFilesDerivedFromInputFile(it, destinationDir) }
197+
195198 if (copySourceToOutput ? : ! aotCompile) {
196199 project.copy {
197200 it.from(getSource()).into(destinationDir)
@@ -269,6 +272,30 @@ open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
269272 }
270273 }
271274
275+ private fun removeOutputFilesDerivedFromInputFile (inputFileDetails : InputFileDetails , destinationDir : File ) {
276+ val sourceAbsoluteFile = inputFileDetails.file
277+ if (isClojureSource(sourceAbsoluteFile)) {
278+ logger.debug(" Removing class files for {}" , inputFileDetails.file)
279+ val sourceCanonicalFileName = sourceAbsoluteFile.canonicalPath
280+ val sourceFileRoot = getSourceRootsFiles()
281+ .find { sourceCanonicalFileName.startsWith(it.canonicalPath) }
282+ ? : throw IllegalStateException (" No source root found for source file ${sourceAbsoluteFile} " )
283+ val sourceRelativeFile = sourceAbsoluteFile.relativeTo(sourceFileRoot)
284+ val sourceRelativeDirectory = sourceRelativeFile.parentFile
285+ val sourceFileName = sourceAbsoluteFile.nameWithoutExtension
286+ destinationDir.resolve(sourceRelativeDirectory)
287+ .listFiles { file -> file.name.startsWith(sourceFileName) }
288+ ?.forEach {
289+ logger.debug(" Deleting derived file {}" , it)
290+ it.delete()
291+ }
292+ }
293+ }
294+
295+ private fun isClojureSource (file : File ): Boolean {
296+ return CLJ_EXTENSION_REGEX .matches(file.extension) && getSourceRoots().any { file.canonicalPath.startsWith(it) }
297+ }
298+
272299 private fun executeScript (script : String , stdout : OutputStream , stderr : OutputStream ) {
273300 val file = createTempFile(" clojure-compiler" , " .clj" , temporaryDir)
274301 file.bufferedWriter().use { out ->
@@ -281,7 +308,7 @@ open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
281308
282309 // clojure.core/compile requires following on its classpath:
283310 // - libs (this.classpath)
284- // - compiled namespaces sources (getSourceRootsFiles)
311+ // - namespaces sources to be compiled (getSourceRootsFiles)
285312 // - *compile-path* directory (this.destinationDir)
286313 exec.classpath = classpath + SimpleFileCollection (getSourceRootsFiles()) + SimpleFileCollection (destinationDir)
287314
@@ -321,16 +348,15 @@ open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
321348 }
322349
323350 private fun getSourceRoots (): HashSet <String > {
324- val roots = source
325- .filter { it is SourceDirectorySet }
326- .flatMap { (it as SourceDirectorySet ).srcDirs }
351+ return getSourceRootsFiles()
327352 .map { it.canonicalPath }
328353 .toHashSet()
329- return roots
330354 }
331355
332356 private fun getSourceRootsFiles (): List <File > {
333- return getSourceRoots().map(::File )
357+ return source
358+ .filter { it is SourceDirectorySet }
359+ .flatMap { (it as SourceDirectorySet ).srcDirs }
334360 }
335361
336362 companion object {
@@ -359,6 +385,7 @@ open class ClojureCompile @Inject constructor(val fileResolver: FileResolver) :
359385 ' \\ ' to " _BSLASH_" ,
360386 ' ?' to " _QMARK_" )
361387
388+ val CLJ_EXTENSION_REGEX = " cljc?" .toRegex()
362389 val DEMUNGE_MAP = CHAR_MAP .map { it.value to it.key }.toMap()
363390 val DEMUNGE_PATTERN = Pattern .compile(DEMUNGE_MAP .keys
364391 .sortedByDescending { it.length }
0 commit comments