Changes to configuration of Kotlin source set

* Include the Java source directory set as-is, without iterating over
its srcDirs
* Avoid Java sources duplication with newer Gradle versions.

Issue #KT-16764 Fixed
Issue #KT-17564 Fixed
This commit is contained in:
Sergey Igushkin
2017-09-15 16:47:44 +03:00
parent c5e5a43f68
commit 5ce514bd42
2 changed files with 81 additions and 5 deletions
@@ -29,6 +29,7 @@ import java.io.File
import java.util.zip.ZipFile
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
class KotlinGradleIT: BaseGradleIT() {
@@ -659,4 +660,60 @@ class KotlinGradleIT: BaseGradleIT() {
}
}
}
}
@Test
fun testSrcDirTaskDependency() {
Project("simpleProject", "4.1").apply {
setupWorkingDir()
File(projectDir, "build.gradle").appendText("""${'\n'}
task generateSources {
outputs.dir('generated')
doLast {
def file = new File('generated/test/TestClass.java')
file.parentFile.mkdirs()
file.text = ""${'"'}
package test;
public class TestClass { }
""${'"'}
}
}
sourceSets.main.java.srcDir(tasks.generateSources)
""".trimIndent())
File(projectDir, "src/main/kotlin/helloWorld.kt").appendText("""${'\n'}
fun usageOfGeneratedSource() = test.TestClass()
""".trimIndent())
build("build") {
assertSuccessful()
}
}
}
@Test
fun testSourceJar() {
Project("simpleProject", "4.1").apply {
setupWorkingDir()
val additionalSrcDir = "src/additional/kotlin/"
File(projectDir, additionalSrcDir).mkdirs()
File(projectDir, "$additionalSrcDir/additionalSource.kt").writeText("fun hello() = 123")
File(projectDir, "build.gradle").appendText("""${'\n'}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier 'source'
duplicatesStrategy = 'fail' // fail in case of Java source duplication, see KT-17564
}
sourceSets.main.kotlin.srcDir('$additionalSrcDir') // test that additional srcDir is included
""".trimIndent())
build("sourcesJar") {
assertSuccessful()
val sourcesJar = ZipFile(File(projectDir, "build/libs/simpleProject-source.jar"))
assertNotNull(sourcesJar.getEntry("additionalSource.kt"))
}
}
}
}
@@ -10,6 +10,7 @@ import org.gradle.api.*
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.plugins.InvalidPluginException
@@ -86,11 +87,30 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
private fun addKotlinDirSetToSources() {
val kotlinDirSet = kotlinSourceSet.kotlin
sourceSet.allJava.source(kotlinDirSet)
sourceSet.allSource.source(kotlinDirSet)
// Try to avoid duplicate Java sources in allSource:
val kotlinSrcDirsToAdd = filterOutJavaSrcDirsIfPossible(kotlinDirSet)
sourceSet.allJava.srcDirs(kotlinSrcDirsToAdd)
sourceSet.allSource.srcDirs(kotlinSrcDirsToAdd)
sourceSet.resources.filter.exclude { it.file in kotlinDirSet }
}
private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection {
// If the API used below is not available, fall back to not filtering the Java sources.
if (SourceDirectorySet::class.java.methods.none { it.name == "getSourceDirectories" }) {
return sourceDirectorySet
}
fun getSourceDirectories(sourceDirectorySet: SourceDirectorySet): FileCollection {
val method = SourceDirectorySet::class.java.getMethod("getSourceDirectories")
return method(sourceDirectorySet) as FileCollection
}
// Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet
return getSourceDirectories(sourceDirectorySet).minus(getSourceDirectories(sourceSet.java))
}
private fun createKotlinCompileTask(): T {
val name = sourceSet.getCompileTaskName(compileTaskNameSuffix)
logger.kotlinDebug("Creating kotlin compile task $name")
@@ -129,6 +149,7 @@ internal class Kotlin2JvmSourceSetProcessor(
override fun doTargetSpecificProcessing() {
val aptConfiguration = project.createAptConfiguration(sourceSet.name, kotlinPluginVersion)
kotlinSourceSet.kotlin.source(sourceSet.java)
project.afterEvaluate { project ->
if (project != null) {
@@ -154,8 +175,6 @@ internal class Kotlin2JvmSourceSetProcessor(
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
}
sourceSet.java.srcDirs.forEach { kotlinSourceSet.kotlin.srcDir(it) }
// KotlinCompile.source(kotlinDirSet) should be called only after all java roots are added to kotlinDirSet
// otherwise some java roots can be ignored
kotlinTask.source(kotlinSourceSet.kotlin)