mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Refactor build compilation in anticipation of scripting support.
This commit is contained in:
parent
d8283d6dd8
commit
8608df4618
2 changed files with 106 additions and 75 deletions
|
@ -32,7 +32,7 @@ import javax.inject.Inject
|
|||
* 1) Extract the repos() and plugins() statements in a separate .kt and compile it into preBuildScript.jar.
|
||||
* 2) Actually build the whole Build.kt file after adding to the classpath whatever phase 1 found (plugins, repos)
|
||||
*/
|
||||
public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFiles: List<BuildFile>,
|
||||
class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFiles: List<BuildFile>,
|
||||
@Assisted val pluginInfo: PluginInfo, val files: KFiles, val plugins: Plugins,
|
||||
val dependencyManager: DependencyManager, val pluginProperties: PluginProperties,
|
||||
val executors: KobaltExecutors, val buildScriptUtil: BuildScriptUtil, val settings: KobaltSettings,
|
||||
|
@ -71,7 +71,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
return projectResult
|
||||
}
|
||||
|
||||
val parsedBuildFiles = arrayListOf<ParsedBuildFile>()
|
||||
val compiledBuildFiles = arrayListOf<ProcessedBuildFile>()
|
||||
|
||||
class FindProjectResult(val context: KobaltContext, val projects: List<Project>, val pluginUrls: List<URL>,
|
||||
val taskResult: TaskResult)
|
||||
|
@ -80,9 +80,9 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
var errorTaskResult: TaskResult? = null
|
||||
val projects = arrayListOf<Project>()
|
||||
buildFiles.forEach { buildFile ->
|
||||
val parsedBuildFile = parseBuildFile(context, buildFile)
|
||||
parsedBuildFiles.add(parsedBuildFile)
|
||||
val pluginUrls = parsedBuildFile.pluginUrls
|
||||
val compiledBuildFile = parseBuildFile(context, buildFile)
|
||||
compiledBuildFiles.add(compiledBuildFile)
|
||||
val pluginUrls = compiledBuildFile.pluginUrls
|
||||
val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR))
|
||||
|
||||
//
|
||||
|
@ -102,7 +102,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
// Write the modified Build.kt (e.g. maybe profiles were applied) to a temporary file,
|
||||
// compile it, jar it in buildScript.jar and run it
|
||||
val modifiedBuildFile = KFiles.createTempFile(".kt", deleteOnExit = true)
|
||||
KFiles.saveFile(modifiedBuildFile, parsedBuildFile.buildScriptCode)
|
||||
KFiles.saveFile(modifiedBuildFile, compiledBuildFile.splitFile.buildScriptCode)
|
||||
val taskResult = maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path),
|
||||
"Modified ${Constants.BUILD_FILE_NAME}", buildFile.realPath),
|
||||
buildScriptJarFile, pluginUrls)
|
||||
|
@ -118,7 +118,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
context.internalContext.absoluteDir = null
|
||||
|
||||
}
|
||||
val pluginUrls = parsedBuildFiles.flatMap { it.pluginUrls }
|
||||
val pluginUrls = compiledBuildFiles.flatMap { it.pluginUrls }
|
||||
return FindProjectResult(context, projects, pluginUrls,
|
||||
if (errorTaskResult != null) errorTaskResult!! else TaskResult())
|
||||
}
|
||||
|
@ -167,5 +167,5 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
|
|||
* - the URL's of all the plug-ins that were found.
|
||||
*/
|
||||
private fun parseBuildFile(context: KobaltContext, buildFile: BuildFile) =
|
||||
ParsedBuildFile(buildFile, context, buildScriptUtil, dependencyManager, files)
|
||||
ProcessedBuildFile(buildFile, context, buildScriptUtil, dependencyManager, files)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.beust.kobalt.app
|
|||
|
||||
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.Project
|
||||
|
@ -18,15 +19,101 @@ import java.nio.charset.Charset
|
|||
import java.nio.file.Paths
|
||||
import java.util.*
|
||||
|
||||
class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil,
|
||||
/**
|
||||
* Process the given build file (either with kotlinc or through scripting) and return projects and pluginUrls.
|
||||
*/
|
||||
class ProcessedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil,
|
||||
val dependencyManager: DependencyManager, val files: KFiles) {
|
||||
val pluginList = arrayListOf<String>()
|
||||
val repos = arrayListOf<String>()
|
||||
val buildFileClasspath = arrayListOf<String>()
|
||||
val profileLines = arrayListOf<String>()
|
||||
val pluginUrls = arrayListOf<URL>()
|
||||
val projects = arrayListOf<Project>()
|
||||
val activeProfiles = arrayListOf<String>()
|
||||
val splitFile = SplitBuildFile(buildFile, context, dependencyManager, files)
|
||||
|
||||
fun compile(): BuildFileCompiler.FindProjectResult {
|
||||
|
||||
// Find the projects but also invoke the plugins() directive, which will initialize Plugins.dynamicPlugins
|
||||
val projects = CompiledBuildFile(buildScriptUtil, dependencyManager, files)
|
||||
.findProjects(splitFile, context)
|
||||
|
||||
// All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already
|
||||
Plugins.dynamicPlugins.forEach {
|
||||
pluginUrls.add(it.jarFile.get().toURI().toURL())
|
||||
}
|
||||
|
||||
return BuildFileCompiler.FindProjectResult(context, projects, pluginUrls, TaskResult())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a build file with kotlinc.
|
||||
*/
|
||||
class CompiledBuildFile(val buildScriptUtil: BuildScriptUtil, val dependencyManager: DependencyManager,
|
||||
val files: KFiles) {
|
||||
|
||||
fun findProjects(splitFile: SplitBuildFile, context: KobaltContext): List<Project> {
|
||||
//
|
||||
// Compile and run preBuildScriptCode, which contains all the plugins() calls extracted. This
|
||||
// will add all the dynamic plugins found in this code to Plugins.dynamicPlugins
|
||||
//
|
||||
val pluginSourceFile = KFiles.createTempFile(".kt", deleteOnExit = true)
|
||||
pluginSourceFile.writeText(splitFile.preBuildScriptCode, Charset.defaultCharset())
|
||||
kobaltLog(2, "Saved ${pluginSourceFile.absolutePath}")
|
||||
|
||||
//
|
||||
// Compile to preBuildScript.jar
|
||||
//
|
||||
val buildFile = splitFile.buildFile
|
||||
val buildScriptJar = KFiles.findBuildScriptLocation(buildFile, "preBuildScript.jar")
|
||||
val buildScriptJarFile = File(buildScriptJar)
|
||||
if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) {
|
||||
buildScriptJarFile.parentFile.mkdirs()
|
||||
generateJarFile(context, BuildFile(Paths.get(pluginSourceFile.path), "Plugins",
|
||||
Paths.get(buildScriptJar)), buildScriptJarFile, buildFile)
|
||||
VersionFile.generateVersionFile(buildScriptJarFile.parentFile)
|
||||
Kobalt.context!!.internalContext.buildFileOutOfDate = true
|
||||
}
|
||||
|
||||
//
|
||||
// Run preBuildScript.jar to initialize plugins and repos
|
||||
//
|
||||
val result = arrayListOf<Project>()
|
||||
result.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>(), context))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun generateJarFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File,
|
||||
originalFile: BuildFile) {
|
||||
|
||||
//
|
||||
// Compile the jar file
|
||||
//
|
||||
val kotlintDeps = dependencyManager.calculateDependencies(null, context)
|
||||
val deps: List<String> = kotlintDeps.map { it.jarFile.get().absolutePath }
|
||||
val outputJar = File(buildScriptJarFile.absolutePath)
|
||||
val result = kotlinCompilePrivate {
|
||||
classpath(files.kobaltJar)
|
||||
classpath(deps)
|
||||
sourceFiles(buildFile.path.toFile().absolutePath)
|
||||
output = outputJar
|
||||
}.compile(context = context)
|
||||
if (! result.success) {
|
||||
throw KobaltException("Couldn't compile ${originalFile.realPath}:\n"
|
||||
+ result.errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given build file and split it into
|
||||
* - A simple build file with just the repos() and plugins() lines (preBuildScriptCode)
|
||||
* - The full build files with profiles applied (buildScriptCode)
|
||||
*/
|
||||
class SplitBuildFile(val buildFile: BuildFile, val context: KobaltContext, val dependencyManager: DependencyManager,
|
||||
val files: KFiles) {
|
||||
private val pluginList = arrayListOf<String>()
|
||||
private val repos = arrayListOf<String>()
|
||||
private val buildFileClasspath = arrayListOf<String>()
|
||||
private val profileLines = arrayListOf<String>()
|
||||
private val activeProfiles = arrayListOf<String>()
|
||||
|
||||
private val preBuildScript = arrayListOf(
|
||||
"import com.beust.kobalt.*",
|
||||
|
@ -38,7 +125,6 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
|||
|
||||
init {
|
||||
parseBuildFile()
|
||||
initPluginUrls()
|
||||
}
|
||||
|
||||
private fun parseBuildFile() {
|
||||
|
@ -102,61 +188,6 @@ class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val
|
|||
pluginList.forEach { preBuildScript.add(it) }
|
||||
buildFileClasspath.forEach { preBuildScript.add(it) }
|
||||
}
|
||||
|
||||
private fun initPluginUrls() {
|
||||
//
|
||||
// Compile and run preBuildScriptCode, which contains all the plugins() calls extracted. This
|
||||
// will add all the dynamic plugins found in this code to Plugins.dynamicPlugins
|
||||
//
|
||||
val pluginSourceFile = KFiles.createTempFile(".kt", deleteOnExit = true)
|
||||
pluginSourceFile.writeText(preBuildScriptCode, Charset.defaultCharset())
|
||||
kobaltLog(2, "Saved ${pluginSourceFile.absolutePath}")
|
||||
|
||||
//
|
||||
// Compile to preBuildScript.jar
|
||||
//
|
||||
val buildScriptJar = KFiles.findBuildScriptLocation(buildFile, "preBuildScript.jar")
|
||||
val buildScriptJarFile = File(buildScriptJar)
|
||||
if (! buildScriptUtil.isUpToDate(buildFile, File(buildScriptJar))) {
|
||||
buildScriptJarFile.parentFile.mkdirs()
|
||||
generateJarFile(context, BuildFile(Paths.get(pluginSourceFile.path), "Plugins",
|
||||
Paths.get(buildScriptJar)), buildScriptJarFile, buildFile)
|
||||
VersionFile.generateVersionFile(buildScriptJarFile.parentFile)
|
||||
Kobalt.context!!.internalContext.buildFileOutOfDate = true
|
||||
}
|
||||
|
||||
//
|
||||
// Run preBuildScript.jar to initialize plugins and repos
|
||||
//
|
||||
projects.addAll(buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>(), context))
|
||||
|
||||
//
|
||||
// All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already
|
||||
//
|
||||
Plugins.dynamicPlugins.forEach {
|
||||
pluginUrls.add(it.jarFile.get().toURI().toURL())
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateJarFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File,
|
||||
originalFile: BuildFile) {
|
||||
|
||||
//
|
||||
// Compile the jar file
|
||||
//
|
||||
val kotlintDeps = dependencyManager.calculateDependencies(null, context)
|
||||
val deps: List<String> = kotlintDeps.map { it.jarFile.get().absolutePath }
|
||||
val outputJar = File(buildScriptJarFile.absolutePath)
|
||||
val result = kotlinCompilePrivate {
|
||||
classpath(files.kobaltJar)
|
||||
classpath(deps)
|
||||
sourceFiles(buildFile.path.toFile().absolutePath)
|
||||
output = outputJar
|
||||
}.compile(context = context)
|
||||
if (! result.success) {
|
||||
throw KobaltException("Couldn't compile ${originalFile.realPath}:\n"
|
||||
+ result.errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue