diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt index 0aad921d..9f4e9db7 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompiler.kt @@ -5,10 +5,17 @@ import com.beust.kobalt.api.Project import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.IClasspathDependency import com.google.inject.Inject +import java.io.File +/** + * Abstract the compilation process by running an ICompilerAction parameterized by a CompilerActionInfo. + * Also validates the classpath and run all the classpath contributors. + */ class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager) { fun doCompile(project: Project?, context: KobaltContext?, action: ICompilerAction, info: CompilerActionInfo) : TaskResult { + File(info.outputDir).mkdirs() + val allDependencies = arrayListOf() allDependencies.addAll(info.dependencies) allDependencies.addAll(calculateDependencies(project, context, info.dependencies)) diff --git a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt index f432d46d..bdfd8c6f 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/RunCommand.kt @@ -6,8 +6,8 @@ import java.io.InputStream import java.io.InputStreamReader public class RunCommand(val command: String) { - val defaultSuccess = { output: List -> log(1, "Success:\n " + output.join("\n"))} - val defaultError = { output: List -> log(1, "Error:\n " + output.join("\n"))} + val defaultSuccess = { output: List -> log(1, "Success:\n " + output.joinToString("\n"))} + val defaultError = { output: List -> log(1, "Error:\n " + output.joinToString("\n"))} var directory = File(".") @@ -19,7 +19,7 @@ public class RunCommand(val command: String) { val pb = ProcessBuilder(allArgs) pb.directory(directory) - log(1, "Running command: " + allArgs.join(" ")) + log(1, "Running command: " + allArgs.joinToString(" ")) val process = pb.start() pb.environment().put("ANDROID_HOME", "/Users/beust/android/adt-bundle-mac-x86_64-20140702/sdk") val errorCode = process.waitFor() diff --git a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt index b5305e39..f47452ba 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt @@ -12,7 +12,6 @@ import com.beust.kobalt.misc.RunCommand import com.beust.kobalt.misc.log import com.beust.kobalt.plugin.java.JavaCompiler import com.beust.kobalt.plugin.packaging.JarUtils -import com.google.common.collect.ArrayListMultimap import com.google.common.collect.HashMultimap import com.google.inject.Inject import com.google.inject.Singleton @@ -37,8 +36,11 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) : val ANDROID_HOME = "/Users/beust/android/adt-bundle-mac-x86_64-20140702/sdk" override val name = "android" + var context: KobaltContext? = null + override fun apply(project: Project, context: KobaltContext) { log(1, "Applying plug-in Android on project $project") + this.context = context if (accept(project)) { project.compileDependencies.add(FileDependency(androidJar(project).toString())) } @@ -144,8 +146,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler) : val sourceFiles = arrayListOf(Paths.get(rDirectory, "R.java").toFile().path) val buildDir = Paths.get(project.buildDirectory, "generated", "classes").toFile() - javaCompiler.compile("Compiling R.java", null, listOf(), listOf(), - sourceFiles, buildDir) + javaCompiler.compile(project, context, listOf(), sourceFiles, buildDir.absolutePath, listOf()) return buildDir } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt index ea706188..a401912d 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt @@ -2,8 +2,11 @@ package com.beust.kobalt.plugin.java import com.beust.kobalt.JavaInfo import com.beust.kobalt.SystemProperties +import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.Project -import com.beust.kobalt.internal.JvmCompilerPlugin +import com.beust.kobalt.internal.CompilerActionInfo +import com.beust.kobalt.internal.ICompilerAction +import com.beust.kobalt.internal.JvmCompiler import com.beust.kobalt.internal.TaskResult import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.IClasspathDependency @@ -13,43 +16,47 @@ import com.google.inject.Singleton import java.io.File @Singleton -class JavaCompiler @Inject constructor(val dependencyManager: DependencyManager){ - fun compile(name: String, directory: String?, compilerArgs: List, cpList: List, - sourceFiles: List, outputDirectory: File): TaskResult { +class JavaCompiler @Inject constructor(val dependencyManager: DependencyManager, + val jvmCompiler: JvmCompiler){ + /** + * Create an ICompilerAction and a CompilerActionInfo suitable to be passed to doCompiler() to perform the + * actual compilation. + */ + fun compile(project: Project?, context: KobaltContext?, dependencies: List, + sourceFiles: List, outputDir: String, args: List) : TaskResult { - outputDirectory.mkdirs() - val jvm = JavaInfo.create(File(SystemProperties.javaBase)) - val javac = jvm.javacExecutable + val info = CompilerActionInfo(dependencies, sourceFiles, outputDir, args) + val compilerAction = object : ICompilerAction { + override fun compile(info: CompilerActionInfo): TaskResult { - val args = arrayListOf( - javac!!.absolutePath, - "-d", outputDirectory.absolutePath) - if (cpList.size > 0) { - val fullClasspath = dependencyManager.transitiveClosure(cpList) - val stringClasspath = fullClasspath.map { it.jarFile.get().absolutePath } - JvmCompilerPlugin.validateClasspath(stringClasspath) - args.add("-classpath") - args.add(stringClasspath.joinToString(File.pathSeparator)) + val jvm = JavaInfo.create(File(SystemProperties.javaBase)) + val javac = jvm.javacExecutable + + val args = arrayListOf( + javac!!.absolutePath, + "-d", info.outputDir) + if (dependencies.size > 0) { + args.add("-classpath") + args.add(info.dependencies.map {it.jarFile.get()}.joinToString(File.pathSeparator)) + } + args.addAll(info.compilerArgs) + args.addAll(info.sourceFiles) + + val pb = ProcessBuilder(args) + if (outputDir != null) { + pb.directory(File(outputDir)) + } + pb.inheritIO() + val line = args.joinToString(" ") + log(1, " Compiling ${sourceFiles.size} files with classpath size " + info.dependencies.size) + log(2, " Compiling ${project?.name}:\n$line") + val process = pb.start() + val errorCode = process.waitFor() + + return if (errorCode == 0) TaskResult(true, "Compilation succeeded") + else TaskResult(false, "There were errors") + } } - args.addAll(compilerArgs) - args.addAll(sourceFiles) - - val pb = ProcessBuilder(args) - if (directory != null) { - pb.directory(File(directory)) - } - pb.inheritIO() - // pb.redirectErrorStream(true) - // pb.redirectError(File("/tmp/kobalt-err")) - // pb.redirectOutput(File("/tmp/kobalt-out")) - val line = args.joinToString(" ") - log(1, " Compiling ${sourceFiles.size} files") - log(2, " Compiling $name:\n$line") - val process = pb.start() - val errorCode = process.waitFor() - - return if (errorCode == 0) TaskResult(true, "Compilation succeeded") - else TaskResult(false, "There were errors") - + return jvmCompiler.doCompile(project, context, compilerAction, info) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt index 25b49ebe..2d811e03 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt @@ -48,8 +48,8 @@ public class JavaPlugin @Inject constructor( private fun compilePrivate(project: Project, cpList: List, sourceFiles: List, outputDirectory: File): TaskResult { - val result = javaCompiler.compile(project.name!!, project.directory, compilerArgs, cpList, sourceFiles, - outputDirectory) + val result = javaCompiler.compile(project, context, cpList, sourceFiles, outputDirectory.absolutePath, + compilerArgs) return result } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt index b48e0810..2443dd2f 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt @@ -36,8 +36,12 @@ class KotlinCompiler @Inject constructor(override val localRepo : LocalRepo, return result } + /** + * Create an ICompilerAction and a CompilerActionInfo suitable to be passed to doCompiler() to perform the + * actual compilation. + */ fun compile(project: Project?, compileDependencies: List, otherClasspath: List, - source: List, output: String, args: List) : TaskResult { + source: List, outputDir: String, args: List) : TaskResult { val executor = executors.newExecutor("KotlinCompiler", 10) val compilerDep = depFactory.create("org.jetbrains.kotlin:kotlin-compiler-embeddable:$KOTLIN_VERSION", executor) @@ -57,7 +61,7 @@ class KotlinCompiler @Inject constructor(override val localRepo : LocalRepo, .plus(compileDependencies) .plus(classpathList) .plus(otherClasspath.map { FileDependency(it)}) - val info = CompilerActionInfo(dependencies, source, output, args) + val info = CompilerActionInfo(dependencies, source, outputDir, args) val compilerAction = object: ICompilerAction { override fun compile(info: CompilerActionInfo): TaskResult { log(1, "Compiling ${source.size} files")