Fixed Kotlin2Js output not being the output of the compileKotlin2Js tasks.

Therefore, fixed Kotlin2Js output not present in JAR.
Reworked the clean behavior in regard to compileKotlin2Js tasks.
Fixed duplicate source roots passed to the compiler.

Issues:
- #KT-15829 Fixed
- #KT-16267 Fixed
- #KT-15902 Fixed
This commit is contained in:
Sergey Igushkin
2017-02-10 16:00:53 +03:00
parent ad313750e7
commit 9e1afe71f2
5 changed files with 73 additions and 21 deletions
@@ -9,11 +9,11 @@ class ExecutionStrategyJsIT : ExecutionStrategyIT() {
project.setupWorkingDir()
val buildGradle = project.projectDir.getFileByName("build.gradle")
buildGradle.modify { it.replace("apply plugin: \"kotlin\"", "apply plugin: \"kotlin2js\"") +
"\ncompileKotlin2Js.kotlinOptions.outputFile = \"out.js\"" }
"\ncompileKotlin2Js.kotlinOptions.outputFile = \"web/js/out.js\"" }
}
override fun CompiledProject.checkOutput() {
assertFileExists("out.js")
assertFileExists("web/js/out.js")
}
}
@@ -4,6 +4,8 @@ import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
import java.util.zip.ZipFile
import kotlin.test.assertEquals
class Kotlin2JsGradlePluginIT : BaseGradleIT() {
@Test
@@ -38,8 +40,6 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
project.build("clean") {
assertSuccessful()
assertReportExists()
assertContains(":mainProject:cleanCompileKotlin2Js\n")
assertNoSuchFile("mainProject/web/js/app.js")
// Test that we don't accidentally remove the containing directory
// This would fail if we used the default clean task of the copy task
@@ -52,7 +52,38 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
project.build("clean") {
assertSuccessful()
assertReportExists()
assertContains(":mainProject:cleanCompileKotlin2Js UP-TO-DATE")
}
}
@Test
fun testJarIncludesJsDefaultOutput() {
val project = Project("kotlin2JsNoOutputFileProject", "2.10")
project.build("jar") {
assertSuccessful()
assertContains(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsNoOutputFileProject.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(1, jar.entries().asSequence().count { it.name == "kotlin2JsNoOutputFileProject_main.js" },
"The jar should contain an entry `kotlin2JsNoOutputFileProject_main.js` with no duplicates")
}
}
@Test
fun testJarIncludesJsOutputSetExplicitly() {
val project = Project("kotlin2JsModuleKind", "2.10")
project.build(":jar") {
assertSuccessful()
assertContains(":compileKotlin2Js")
val jarPath = "build/libs/kotlin2JsModuleKind.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(1, jar.entries().asSequence().count { it.name == "app.js" },
"The jar should contain an entry `app.js` with no duplicates")
}
}
@@ -107,6 +138,12 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
assertFileExists("build/kotlin2js/main/module.js")
assertFileExists("build/kotlin2js/integrationTest/module-inttests.js")
val jarPath = "build/libs/kotlin2JsProjectWithCustomSourceset-inttests.jar"
assertFileExists(jarPath)
val jar = ZipFile(fileInWorkingDir(jarPath))
assertEquals(1, jar.entries().asSequence().count { it.name == "module-inttests.js" },
"The jar should contain an entry `module-inttests.js` with no duplicates")
}
}
@@ -33,6 +33,13 @@ dependencies {
integrationTestCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version"
}
task integrationTestJar(type: Jar) {
from sourceSets.integrationTest.output
classifier = 'inttests'
}
build.dependsOn integrationTestJar
task jarSources(type: Jar) {
from sourceSets.main.allSource
classifier = 'source'
@@ -7,6 +7,7 @@ import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.model.SourceProvider
import groovy.lang.Closure
import org.gradle.api.InvalidUserDataException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
@@ -20,16 +21,18 @@ import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.internal.*
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
import org.jetbrains.kotlin.gradle.internal.initKapt
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.plugin.android.KotlinJillTask
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProviderAndroidWrapper
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File
import java.net.URL
import java.util.*
@@ -186,18 +189,30 @@ internal class Kotlin2JsSourceSetProcessor(
taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.",
compileTaskNameSuffix = "kotlin2Js"
) {
private val clean = project.tasks.findByName("clean")
private val build = project.tasks.findByName("build")
override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile =
tasksProvider.createKotlinJSTask(project, taskName, sourceSet.name)
override fun doTargetSpecificProcessing() {
val taskName = kotlinTask.name
build?.dependsOn(taskName)
clean?.dependsOn("clean" + taskName.capitalize())
project.tasks.findByName(sourceSet.classesTaskName).dependsOn(kotlinTask)
kotlinTask.source(kotlinSourceSet.kotlin)
createCleanSourceMapTask()
// outputFile can be set later during the configuration phase, get it only after the phase:
project.afterEvaluate {
kotlinTask.kotlinOptions.outputFile = File(kotlinTask.outputFile).absolutePath
val outputDir = File(kotlinTask.outputFile).parentFile
if (FileUtil.isAncestor(outputDir, project.rootDir, false))
throw InvalidUserDataException(
"The output directory '$outputDir' (defined by outputFile of $kotlinTask) contains or " +
"matches the project root directory '${project.rootDir}'.\n" +
"Gradle will not be able to build the project because of the root directory lock.\n" +
"To fix this, consider using the default outputFile location instead of providing it explicitly.")
sourceSet.output.setClassesDir(outputDir)
kotlinTask.destinationDir = outputDir
}
}
private fun createCleanSourceMapTask() {
@@ -207,7 +222,7 @@ internal class Kotlin2JsSourceSetProcessor(
task.delete(object : Closure<String>(this) {
override fun call(): String? = (kotlinTask.property("outputFile") as String) + ".map"
})
clean?.dependsOn(taskName)
project.tasks.findByName("clean")?.dependsOn(taskName)
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.gradle.tasks
import org.codehaus.groovy.runtime.MethodClosure
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.logging.Logger
@@ -44,7 +43,6 @@ import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistry
import org.jetbrains.kotlin.incremental.multiproject.ArtifactDifferenceRegistryProvider
import org.jetbrains.kotlin.utils.LibraryUtils
import java.io.File
import java.rmi.Remote
import java.util.*
import kotlin.properties.Delegates
@@ -322,10 +320,6 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
val outputFile: String
get() = kotlinOptions.outputFile ?: defaultOutputFile.canonicalPath
init {
@Suppress("LeakingThis")
outputs.file(MethodClosure(this, "getOutputFile"))
}
override fun findKotlinCompilerJar(project: Project): File? =
findKotlinJsCompilerJar(project)
@@ -348,7 +342,6 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
logger.debug("Calling compiler")
destinationDir.mkdirs()
args.freeArgs = args.freeArgs + sourceRoots.kotlinSourceFiles.map { it.absolutePath }
val friendDependency = friendTaskName
?.let { project.getTasksByName(it, false).singleOrNull() as? Kotlin2JsCompile }