mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Modify commands to report errors to the IDEA plug-in.
This commit is contained in:
parent
806ca59f97
commit
ce435adf25
7 changed files with 68 additions and 33 deletions
|
@ -17,7 +17,7 @@ interface ICommand {
|
|||
*/
|
||||
fun run(sender: ICommandSender, received: JsonObject)
|
||||
|
||||
fun toCommandData(data: String) = CommandData(name, data)
|
||||
fun toCommandData(data: String, error: String? = null) = CommandData(name, data, error)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.beust.kobalt.internal.remote
|
||||
|
||||
import com.beust.kobalt.misc.log
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.beust.kobalt.api.Kobalt
|
|||
import com.beust.kobalt.api.PluginTask
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.app.*
|
||||
import com.beust.kobalt.app.remote.DependencyData
|
||||
import com.beust.kobalt.app.remote.KobaltClient
|
||||
import com.beust.kobalt.app.remote.KobaltServer
|
||||
import com.beust.kobalt.internal.KobaltSettings
|
||||
|
@ -65,6 +66,7 @@ private class Main @Inject constructor(
|
|||
val pluginInfo: PluginInfo,
|
||||
val projectGenerator: ProjectGenerator,
|
||||
val depFactory: DepFactory,
|
||||
val dependencyData: DependencyData,
|
||||
val resolveDependency: ResolveDependency) {
|
||||
|
||||
data class RunInfo(val jc: JCommander, val args: Args)
|
||||
|
@ -88,7 +90,7 @@ private class Main @Inject constructor(
|
|||
return pluginClassLoader
|
||||
}
|
||||
|
||||
public fun run(jc: JCommander, args: Args, argv: Array<String>): Int {
|
||||
fun run(jc: JCommander, args: Args, argv: Array<String>): Int {
|
||||
//
|
||||
// Install plug-ins requested from the command line
|
||||
//
|
||||
|
@ -101,6 +103,9 @@ private class Main @Inject constructor(
|
|||
//
|
||||
pluginInfo.plugins.forEach { Plugins.addPluginInstance(it) }
|
||||
|
||||
// val data = dependencyData.dependenciesDataFor(homeDir("kotlin/klaxon/kobalt/src/Build.kt"), Args())
|
||||
// println("Data: $data")
|
||||
|
||||
// --listTemplates
|
||||
if (args.listTemplates) {
|
||||
Templates().list(pluginInfo)
|
||||
|
@ -174,8 +179,14 @@ private class Main @Inject constructor(
|
|||
if (!buildFile.exists()) {
|
||||
error(buildFile.path.toFile().path + " does not exist")
|
||||
} else {
|
||||
val allProjects = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
|
||||
val findProjectResult = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
|
||||
.compileBuildFiles(args)
|
||||
if (! findProjectResult.taskResult.success) {
|
||||
throw KobaltException("Couldn't compile build file: "
|
||||
+ findProjectResult.taskResult.errorMessage)
|
||||
}
|
||||
|
||||
val allProjects = findProjectResult.projects
|
||||
|
||||
//
|
||||
// Now that we have projects, add all the repos from repo contributors that need a Project
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.beust.kobalt.app
|
|||
|
||||
import com.beust.kobalt.Args
|
||||
import com.beust.kobalt.Constants
|
||||
import com.beust.kobalt.KobaltException
|
||||
import com.beust.kobalt.Plugins
|
||||
import com.beust.kobalt.TaskResult
|
||||
import com.beust.kobalt.api.Kobalt
|
||||
import com.beust.kobalt.api.KobaltContext
|
||||
import com.beust.kobalt.api.PluginProperties
|
||||
|
@ -39,7 +39,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
|
||||
private val SCRIPT_JAR = "buildScript.jar"
|
||||
|
||||
fun compileBuildFiles(args: Args): List<Project> {
|
||||
fun compileBuildFiles(args: Args): FindProjectResult {
|
||||
//
|
||||
// Create the KobaltContext
|
||||
//
|
||||
|
@ -54,16 +54,21 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
//
|
||||
// Find all the projects in the build file, possibly compiling them
|
||||
//
|
||||
val allProjects = findProjects(context)
|
||||
plugins.applyPlugins(context, allProjects)
|
||||
val projectResult = findProjects(context)
|
||||
if (projectResult.taskResult.success) {
|
||||
plugins.applyPlugins(context, projectResult.projects)
|
||||
}
|
||||
|
||||
return allProjects
|
||||
return projectResult
|
||||
}
|
||||
|
||||
val parsedBuildFiles = arrayListOf<ParsedBuildFile>()
|
||||
|
||||
private fun findProjects(context: KobaltContext): List<Project> {
|
||||
val result = arrayListOf<Project>()
|
||||
class FindProjectResult(val projects: List<Project>, val taskResult: TaskResult)
|
||||
|
||||
private fun findProjects(context: KobaltContext): FindProjectResult {
|
||||
var errorTaskResult: TaskResult? = null
|
||||
val projects = arrayListOf<Project>()
|
||||
buildFiles.forEach { buildFile ->
|
||||
val parsedBuildFile = parseBuildFile(context, buildFile)
|
||||
parsedBuildFiles.add(parsedBuildFile)
|
||||
|
@ -83,35 +88,39 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
// compile it, jar it in buildScript.jar and run it
|
||||
val modifiedBuildFile = KFiles.createTempFile(".kt")
|
||||
KFiles.saveFile(modifiedBuildFile, parsedBuildFile.buildScriptCode)
|
||||
maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path),
|
||||
val taskResult = maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path),
|
||||
"Modified ${Constants.BUILD_FILE_NAME}", buildFile.realPath),
|
||||
buildScriptJarFile, pluginUrls)
|
||||
val projects = buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context)
|
||||
result.addAll(projects)
|
||||
if (taskResult.success) {
|
||||
projects.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context))
|
||||
} else {
|
||||
if (errorTaskResult == null) {
|
||||
errorTaskResult = taskResult
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
return FindProjectResult(projects, if (errorTaskResult != null) errorTaskResult!! else TaskResult())
|
||||
}
|
||||
|
||||
private fun maybeCompileBuildFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File,
|
||||
pluginUrls: List<URL>) {
|
||||
pluginUrls: List<URL>) : TaskResult {
|
||||
log(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile")
|
||||
|
||||
if (buildScriptUtil.isUpToDate(buildFile, buildScriptJarFile)) {
|
||||
log(2, "Build file is up to date")
|
||||
return TaskResult()
|
||||
} else {
|
||||
log(2, "Need to recompile ${buildFile.name}")
|
||||
|
||||
buildScriptJarFile.delete()
|
||||
kotlinCompilePrivate {
|
||||
val result = kotlinCompilePrivate {
|
||||
classpath(files.kobaltJar)
|
||||
classpath(pluginUrls.map { it.file })
|
||||
sourceFiles(listOf(buildFile.path.toFile().absolutePath))
|
||||
output = buildScriptJarFile
|
||||
}.compile(context = context)
|
||||
|
||||
if (! buildScriptJarFile.exists()) {
|
||||
throw KobaltException("Could not compile ${buildFile.name}")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
|||
|
||||
val buildFile = BuildFile(Paths.get(buildFilePath), "GetDependenciesCommand")
|
||||
val buildFileCompiler = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
|
||||
val projects = buildFileCompiler.compileBuildFiles(args)
|
||||
val projectResult = buildFileCompiler.compileBuildFiles(args)
|
||||
val pluginUrls = buildFileCompiler.parsedBuildFiles.flatMap { it.pluginUrls }
|
||||
|
||||
val pluginDependencies = pluginUrls.map { File(it.toURI()) }.map { FileDependency(it.absolutePath) }
|
||||
projects.forEach { project ->
|
||||
projectResult.projects.forEach { project ->
|
||||
val compileDependencies = pluginDependencies.map { toDependencyData(it, "compile") } +
|
||||
allDeps(project.compileDependencies).map { toDependencyData(it, "compile") } +
|
||||
allDeps(project.compileProvidedDependencies).map { toDependencyData(it, "compile") }
|
||||
|
@ -57,7 +57,7 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
|||
compileDependencies, testDependencies,
|
||||
sources.second.toSet(), tests.second.toSet(), sources.first.toSet(), tests.first.toSet()))
|
||||
}
|
||||
return GetDependenciesData(projectDatas)
|
||||
return GetDependenciesData(projectDatas, projectResult.taskResult.errorMessage)
|
||||
}
|
||||
|
||||
/////
|
||||
|
@ -72,5 +72,5 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
|||
val testDependencies: List<DependencyData>, val sourceDirs: Set<String>, val testDirs: Set<String>,
|
||||
val sourceResourceDirs: Set<String>, val testResourceDirs: Set<String>)
|
||||
|
||||
class GetDependenciesData(val projects: List<ProjectData>)
|
||||
class GetDependenciesData(val projects: List<ProjectData>, val errorMessage: String?)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ class GetDependenciesCommand @Inject constructor(val args: Args, val dependencyD
|
|||
|
||||
override fun run(sender: ICommandSender, received: JsonObject) {
|
||||
val buildFile = received.get("buildFile").asString
|
||||
val data = toCommandData(Gson().toJson(dependencyData.dependenciesDataFor(buildFile, args)))
|
||||
val dd = dependencyData.dependenciesDataFor(buildFile, args)
|
||||
val data = toCommandData(Gson().toJson(dd), dd.errorMessage)
|
||||
sender.sendData(data)
|
||||
}
|
||||
}
|
|
@ -14,7 +14,10 @@ import com.beust.kobalt.misc.log
|
|||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.nio.charset.Charset
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
@ -64,8 +67,7 @@ class KotlinCompiler @Inject constructor(
|
|||
allArgs.add("-no-stdlib")
|
||||
}
|
||||
|
||||
val success = invokeCompiler(projectName ?: "kobalt-" + Random().nextInt(), cp, allArgs)
|
||||
return TaskResult(success)
|
||||
return invokeCompiler(projectName ?: "kobalt-" + Random().nextInt(), cp, allArgs)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,10 +80,10 @@ class KotlinCompiler @Inject constructor(
|
|||
* There are plenty of ways in which this method can break but this will be immediately
|
||||
* apparent if it happens.
|
||||
*/
|
||||
private fun invokeCompiler(projectName: String, cp: List<File>, args: List<String>): Boolean {
|
||||
private fun invokeCompiler(projectName: String, cp: List<File>, args: List<String>): TaskResult {
|
||||
val allArgs = listOf("-module-name", "project-" + projectName) + args
|
||||
log(2, "Calling kotlinc " + allArgs.joinToString(" "))
|
||||
val result : Boolean =
|
||||
val result : TaskResult =
|
||||
if (true) {
|
||||
val classLoader = ParentLastClassLoader(cp.map { it.toURI().toURL() })
|
||||
val compiler = classLoader.loadClass("org.jetbrains.kotlin.cli.common.CLICompiler")
|
||||
|
@ -89,13 +91,26 @@ class KotlinCompiler @Inject constructor(
|
|||
it.name == "doMainNoExit" && it.parameterTypes.size == 2
|
||||
}[0]
|
||||
val kCompiler = classLoader.loadClass("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
|
||||
val compilerInstance = kCompiler.newInstance()
|
||||
val exitCode = compilerMain.invoke(null, compilerInstance, allArgs.toTypedArray())
|
||||
|
||||
//
|
||||
// In order to capture the error stream, I need to invoke CLICompiler.exec(), which
|
||||
// is the first method that accepts a PrintStream for the errors in parameter
|
||||
//
|
||||
val baos = ByteArrayOutputStream()
|
||||
val ps = PrintStream(baos)
|
||||
val execMethod = compiler.declaredMethods.filter {
|
||||
it.name == "exec" && it.parameterTypes.size == 2
|
||||
}[0]
|
||||
val exitCode = execMethod.invoke(kCompiler.newInstance(), ps, allArgs.toTypedArray())
|
||||
val errorString = baos.toString(Charset.defaultCharset().toString())
|
||||
|
||||
// The return value is an enum
|
||||
val nameMethod = exitCode.javaClass.getMethod("name")
|
||||
"OK" == nameMethod.invoke(exitCode).toString()
|
||||
val success = "OK" == nameMethod.invoke(exitCode).toString()
|
||||
TaskResult(success, errorString)
|
||||
} else {
|
||||
val exitCode = CLICompiler.doMainNoExit(K2JVMCompiler(), allArgs.toTypedArray())
|
||||
exitCode == ExitCode.OK
|
||||
TaskResult(exitCode == ExitCode.OK)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue