blob: 028130b24142a85b2c69ee393bed3cf46ce29ebf [file] [log] [blame]
package io.bazel.kotlin.builder.tasks.js
import io.bazel.kotlin.builder.toolchain.CompilationException
import io.bazel.kotlin.builder.toolchain.KotlinToolchain
import io.bazel.kotlin.builder.utils.CompilationTaskContext
import io.bazel.kotlin.builder.utils.addAll
import io.bazel.kotlin.builder.utils.jars.JarCreator
import io.bazel.kotlin.builder.utils.jars.SourceJarCreator
import io.bazel.kotlin.builder.utils.resolveTwinVerified
import io.bazel.kotlin.builder.utils.verifiedPath
import io.bazel.kotlin.model.JsCompilationTask
import java.io.FileOutputStream
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class Kotlin2JsTaskExecutor @Inject constructor(
private val invoker: KotlinToolchain.K2JSCompilerInvoker
) {
fun execute(context: CompilationTaskContext, task: JsCompilationTask) {
task.compile(context)
val jsPath = Paths.get(task.outputs.js)
val jsMetaFile = jsPath.resolveTwinVerified(".meta.js")
val jsDirectory = jsPath.parent.resolve(jsPath.toFile().nameWithoutExtension)
task.createJar(jsDirectory, listOf(jsPath, jsPath.resolveTwinVerified(".js.map"), jsMetaFile))
// this mutates the jsPath file , so do it after creating the jar.
appendMetaToPrimary(jsPath, jsMetaFile)
task.createSourceJar()
}
private fun JsCompilationTask.compile(context: CompilationTaskContext) {
val args = mutableListOf<String>().also {
it.addAll(passThroughFlagsList)
it.addAll("-libraries", inputs.librariesList.joinToString(":"))
it.addAll("-output", outputs.js)
it.addAll(inputs.kotlinSourcesList)
}
context.whenTracing { printLines("js compile args", args) }
context.executeCompilerTask(args, invoker::compile)
}
private fun JsCompilationTask.createSourceJar() {
try {
SourceJarCreator(Paths.get(outputs.srcjar), false).also { creator ->
creator.addSources(inputs.kotlinSourcesList.map { Paths.get(it) }.stream())
}.execute()
} catch (ex: Throwable) {
throw CompilationException("could not create source jar", ex)
}
}
/**
* Append the meta file to the JS file. This is an accepted pattern, and it allows us to not have to export the
* meta.js file with the js.
*/
private fun appendMetaToPrimary(jsPath: Path, jsMetaFile: Path) {
try {
FileOutputStream(jsPath.toFile(), true).use { Files.copy(jsMetaFile, it) }
} catch (ex: Throwable) {
throw CompilationException("could not normalize js file", ex)
}
}
private fun JsCompilationTask.createJar(jsDirectoryPath: Path, rootEntries: List<Path>) {
try {
val outputJarPath = Paths.get(outputs.jar)
JarCreator(outputJarPath).also { creator ->
creator.addDirectory(jsDirectoryPath)
creator.addRootEntries(rootEntries.map { it.toString() })
creator.execute()
}
} catch (ex: Throwable) {
throw CompilationException("error creating js jar", ex)
}
}
}