1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-27 00:38:11 -07:00

Refactoring of BuildScript.

This commit is contained in:
Cedric Beust 2015-11-27 09:12:40 -08:00
parent 947c620e56
commit 43ccceb71e
5 changed files with 246 additions and 198 deletions

View file

@ -1,6 +1,7 @@
package com.beust.kobalt.internal.remote package com.beust.kobalt.internal.remote
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.kotlin.BuildFile import com.beust.kobalt.kotlin.BuildFile
import com.beust.kobalt.kotlin.BuildFileCompiler import com.beust.kobalt.kotlin.BuildFileCompiler
@ -28,16 +29,16 @@ class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors,
val buildFile = BuildFile(Paths.get(received.get("buildFile").asString), "GetDependenciesCommand") val buildFile = BuildFile(Paths.get(received.get("buildFile").asString), "GetDependenciesCommand")
val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo) val scriptCompiler = buildFileCompilerFactory.create(listOf(buildFile), pluginInfo)
scriptCompiler.observable.subscribe { scriptCompiler.observable.subscribe {
buildScriptInfo -> if (buildScriptInfo.projects.size > 0) { projects -> if (projects.size > 0) {
sender.sendData(toData(buildScriptInfo)) sender.sendData(toData(projects))
} }
} }
scriptCompiler.compileBuildFiles(args) scriptCompiler.compileBuildFiles(args)
} }
private fun toData(info: BuildFileCompiler.BuildScriptInfo) : CommandData { private fun toData(projects: List<Project>) : CommandData {
val projectDatas = arrayListOf<ProjectData>()
val executor = executors.miscExecutor val executor = executors.miscExecutor
val projects = arrayListOf<ProjectData>()
fun toDependencyData(d: IClasspathDependency, scope: String) : DependencyData { fun toDependencyData(d: IClasspathDependency, scope: String) : DependencyData {
val dep = MavenDependency.create(d.id, executor) val dep = MavenDependency.create(d.id, executor)
@ -46,7 +47,7 @@ class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors,
fun allDeps(l: List<IClasspathDependency>) = dependencyManager.transitiveClosure(l) fun allDeps(l: List<IClasspathDependency>) = dependencyManager.transitiveClosure(l)
info.projects.forEach { project -> projects.forEach { project ->
val allDependencies = val allDependencies =
allDeps(project.compileDependencies).map { toDependencyData(it, "compile") } + allDeps(project.compileDependencies).map { toDependencyData(it, "compile") } +
allDeps(project.compileProvidedDependencies).map { toDependencyData(it, "provided") } + allDeps(project.compileProvidedDependencies).map { toDependencyData(it, "provided") } +
@ -54,10 +55,10 @@ class GetDependenciesCommand @Inject constructor(val executors: KobaltExecutors,
allDeps(project.testDependencies).map { toDependencyData(it, "testCompile") } + allDeps(project.testDependencies).map { toDependencyData(it, "testCompile") } +
allDeps(project.testProvidedDependencies).map { toDependencyData(it, "testProvided") } allDeps(project.testProvidedDependencies).map { toDependencyData(it, "testProvided") }
projects.add(ProjectData(project.name, allDependencies)) projectDatas.add(ProjectData(project.name, allDependencies))
} }
log(1, "Returning BuildScriptInfo") log(1, "Returning BuildScriptInfo")
val result = toCommandData(Gson().toJson(GetDependenciesData(projects))) val result = toCommandData(Gson().toJson(GetDependenciesData(projectDatas)))
log(2, " $result") log(2, " $result")
return result return result
} }

View file

@ -3,28 +3,24 @@ package com.beust.kobalt.kotlin
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.KobaltException import com.beust.kobalt.KobaltException
import com.beust.kobalt.Plugins import com.beust.kobalt.Plugins
import com.beust.kobalt.api.* import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.PluginProperties
import com.beust.kobalt.api.Project
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.kotlin.internal.BuildScriptUtil
import com.beust.kobalt.kotlin.internal.ParsedBuildFile import com.beust.kobalt.kotlin.internal.ParsedBuildFile
import com.beust.kobalt.kotlin.internal.VersionFile
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.Topological
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
import com.google.inject.assistedinject.Assisted import com.google.inject.assistedinject.Assisted
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.lang.reflect.Modifier
import java.net.URL import java.net.URL
import java.net.URLClassLoader
import java.nio.charset.Charset
import java.nio.file.Paths import java.nio.file.Paths
import java.util.*
import java.util.jar.JarInputStream
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -35,13 +31,13 @@ import javax.inject.Inject
public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFiles: List<BuildFile>, public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val buildFiles: List<BuildFile>,
@Assisted val pluginInfo: PluginInfo, val files: KFiles, val plugins: Plugins, @Assisted val pluginInfo: PluginInfo, val files: KFiles, val plugins: Plugins,
val dependencyManager: DependencyManager, val pluginProperties: PluginProperties, val dependencyManager: DependencyManager, val pluginProperties: PluginProperties,
val executors: KobaltExecutors) { val executors: KobaltExecutors, val buildScriptUtil: BuildScriptUtil) {
interface IFactory { interface IFactory {
fun create(@Assisted("buildFiles") buildFiles: List<BuildFile>, pluginInfo: PluginInfo) : BuildFileCompiler fun create(@Assisted("buildFiles") buildFiles: List<BuildFile>, pluginInfo: PluginInfo) : BuildFileCompiler
} }
val observable = PublishSubject.create<BuildScriptInfo>() val observable = PublishSubject.create<List<Project>>()
private val SCRIPT_JAR = "buildScript.jar" private val SCRIPT_JAR = "buildScript.jar"
@ -65,31 +61,17 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
return allProjects return allProjects
} }
/**
* Make sure all the projects have a unique name.
*/
private fun validateProjects(projects: List<Project>) {
val seen = hashSetOf<String>()
projects.forEach {
if (seen.contains(it.name)) {
throw KobaltException("Duplicate project name: $it")
} else {
seen.add(it.name)
}
}
}
private fun findProjects(context: KobaltContext): List<Project> { private fun findProjects(context: KobaltContext): List<Project> {
val result = arrayListOf<Project>() val result = arrayListOf<Project>()
buildFiles.forEach { buildFile -> buildFiles.forEach { buildFile ->
val pair = processBuildFile(context, buildFile) val processBuildFile = parseBuildFile(context, buildFile)
val pluginUrls = pair.second val pluginUrls = processBuildFile.pluginUrls
val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR)) val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR))
// If the script jar files were generated by a different version, wipe them in case the API // If the script jar files were generated by a different version, wipe them in case the API
// changed in-between // changed in-between
buildScriptJarFile.parentFile.let { dir -> buildScriptJarFile.parentFile.let { dir ->
if (! isSameVersionFile(dir)) { if (! VersionFile.isSameVersionFile(dir)) {
log(1, "Detected new installation, wiping $dir") log(1, "Detected new installation, wiping $dir")
dir.listFiles().map { it.delete() } dir.listFiles().map { it.delete() }
} }
@ -98,24 +80,20 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
// Write the modified Build.kt (e.g. maybe profiles were applied) to a temporary file, // 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 // compile it, jar it in buildScript.jar and run it
val modifiedBuildFile = KFiles.createTempFile(".kt") val modifiedBuildFile = KFiles.createTempFile(".kt")
KFiles.saveFile(modifiedBuildFile, pair.first.buildScriptCode) KFiles.saveFile(modifiedBuildFile, processBuildFile.buildScriptCode)
maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path), "Modified Build.kt"), maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path), "Modified Build.kt"),
buildScriptJarFile, pluginUrls) buildScriptJarFile, pluginUrls)
val buildScriptInfo = runBuildScriptJarFile(buildScriptJarFile, pluginUrls) val projects = buildScriptUtil.runBuildScriptJarFile(buildScriptJarFile, pluginUrls, context)
result.addAll(buildScriptInfo.projects) result.addAll(projects)
} }
return result return result
} }
private fun isUpToDate(buildFile: BuildFile, jarFile: File) =
buildFile.exists() && jarFile.exists()
&& buildFile.lastModified < jarFile.lastModified()
private fun maybeCompileBuildFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File, private fun maybeCompileBuildFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File,
pluginUrls: List<URL>) { pluginUrls: List<URL>) {
log(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile") log(2, "Running build file ${buildFile.name} jar: $buildScriptJarFile")
if (isUpToDate(buildFile, buildScriptJarFile)) { if (buildScriptUtil.isUpToDate(buildFile, buildScriptJarFile)) {
log(2, "Build file is up to date") log(2, "Build file is up to date")
} else { } else {
log(2, "Need to recompile ${buildFile.name}") log(2, "Need to recompile ${buildFile.name}")
@ -139,156 +117,12 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
* - the source code for the modified Build.kt (after profiles are applied) * - the source code for the modified Build.kt (after profiles are applied)
* - the URL's of all the plug-ins that were found. * - the URL's of all the plug-ins that were found.
*/ */
private fun processBuildFile(context: KobaltContext, buildFile: BuildFile): Pair<ParsedBuildFile, List<URL>> { private fun parseBuildFile(context: KobaltContext, buildFile: BuildFile) : ParsedBuildFile {
val result = arrayListOf<URL>()
// Parse the build file so we can generate preBuildScript and buildScript from it. // Parse the build file so we can generate preBuildScript and buildScript from it.
val parsedBuildFile = ParsedBuildFile(buildFile.path.toFile(), context) with(ParsedBuildFile(buildFile, context, buildScriptUtil, dependencyManager, files)) {
//
// 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")
pluginSourceFile.writeText(parsedBuildFile.preBuildScriptCode, Charset.defaultCharset())
log(2, "Saved ${pluginSourceFile.absolutePath}")
//
// Compile to preBuildScript.jar
//
val buildScriptJar = KFiles.findBuildScriptLocation(buildFile, "preBuildScript.jar")
val buildScriptJarFile = File(buildScriptJar)
if (! isUpToDate(buildFile, File(buildScriptJar))) {
buildScriptJarFile.parentFile.mkdirs()
generateJarFile(context, BuildFile(Paths.get(pluginSourceFile.path), "Plugins"), buildScriptJarFile)
generateVersionFile(buildScriptJarFile.parentFile)
}
//
// Run preBuildScript.jar to initialize plugins and repos
//
runBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>())
//
// All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already
//
Plugins.dynamicPlugins.forEach {
result.add(it.jarFile.get().toURI().toURL())
}
return Pair(parsedBuildFile, result)
}
private val VERSION_FILE = "version.txt"
private fun generateVersionFile(directory: File) {
KFiles.saveFile(File(directory, VERSION_FILE), Kobalt.version)
}
private fun isSameVersionFile(directory: File) =
with(File(directory, VERSION_FILE)) {
! exists() || (exists() && readText() == Kobalt.version)
}
private fun generateJarFile(context: KobaltContext, buildFile: BuildFile, buildScriptJarFile: File) {
val kotlintDeps = dependencyManager.calculateDependencies(null, context)
val deps: List<String> = kotlintDeps.map { it.jarFile.get().absolutePath }
kotlinCompilePrivate {
classpath(files.kobaltJar)
classpath(deps)
sourceFiles(buildFile.path.toFile().absolutePath)
output = File(buildScriptJarFile.absolutePath)
}.compile(context = context)
}
class BuildScriptInfo(val projects: List<Project>)
/**
* Run the given preBuildScript (or buildScript) jar file, using a classloader made of the passed URL's.
*/
private fun runBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>) : BuildScriptInfo {
val projects = arrayListOf<Project>()
var stream : InputStream? = null
val allUrls = (urls + arrayOf(
buildScriptJarFile.toURI().toURL()) + File(files.kobaltJar).toURI().toURL())
.toTypedArray()
val classLoader = URLClassLoader(allUrls)
//
// Install all the plugins
//
plugins.installPlugins(Plugins.dynamicPlugins, classLoader)
try {
stream = JarInputStream(FileInputStream(buildScriptJarFile))
var entry = stream.nextJarEntry
val classes = hashSetOf<Class<*>>()
while (entry != null) {
val name = entry.name;
if (name.endsWith(".class")) {
val className = name.substring(0, name.length - 6).replace("/", ".")
var cl : Class<*>? = classLoader.loadClass(className)
if (cl != null) {
classes.add(cl)
} else {
throw KobaltException("Couldn't instantiate $className")
}
}
entry = stream.nextJarEntry;
}
// Invoke all the "val" found on the _DefaultPackage class (the Build.kt file)
classes.filter { cls ->
cls.name != "_DefaultPackage"
}.forEach { cls ->
cls.methods.forEach { method ->
// Invoke vals and see if they return a Project
if (method.name.startsWith("get") && Modifier.isStatic(method.modifiers)) {
try {
val r = method.invoke(null)
if (r is Project) {
log(2, "Found project $r in class $cls")
projects.add(r)
}
} catch(ex: Throwable) {
throw ex.cause ?: KobaltException(ex)
}
} else {
val taskAnnotation = method.getAnnotation(Task::class.java)
if (taskAnnotation != null) {
Plugins.defaultPlugin.methodTasks.add(IPlugin.MethodTask(method, taskAnnotation))
}
}}
}
} finally {
stream?.close()
}
validateProjects(projects)
//
// Now that the build file has run, fetch all the project contributors, grab the projects from them and sort
// them topologically
//
Topological<Project>().let { topologicalProjects ->
val all = hashSetOf<Project>()
pluginInfo.projectContributors.forEach { contributor ->
val descriptions = contributor.projects()
descriptions.forEach { pd ->
all.add(pd.project)
pd.dependsOn.forEach { dependsOn ->
topologicalProjects.addEdge(pd.project, dependsOn)
all.add(dependsOn)
}
}
}
val result = BuildScriptInfo(topologicalProjects.sort(ArrayList(all)))
// Notify possible listeners (e.g. KobaltServer) we now have all the projects // Notify possible listeners (e.g. KobaltServer) we now have all the projects
observable.onNext(result) observable.onNext(projects)
return result return this
} }
} }
} }

View file

@ -0,0 +1,135 @@
package com.beust.kobalt.kotlin.internal
import com.beust.kobalt.KobaltException
import com.beust.kobalt.Plugins
import com.beust.kobalt.api.IPlugin
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.kotlin.BuildFile
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.Topological
import com.beust.kobalt.misc.log
import com.google.inject.Inject
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.lang.reflect.Modifier
import java.net.URL
import java.net.URLClassLoader
import java.util.*
import java.util.jar.JarInputStream
class BuildScriptUtil @Inject constructor(val plugins: Plugins, val files: KFiles){
val projects = arrayListOf<Project>()
/**
* Run the given preBuildScript (or buildScript) jar file, using a classloader made of the passed URL's.
* This list is empty when we run preBuildScript.jar but for buildScript.jar, it contains the list of
* URL's found from running preBuildScript.jar.
*/
fun runBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>,
context: KobaltContext) : List<Project> {
var stream : InputStream? = null
val allUrls = (urls + arrayOf(
buildScriptJarFile.toURI().toURL()) + File(files.kobaltJar).toURI().toURL())
.toTypedArray()
val classLoader = URLClassLoader(allUrls)
//
// Install all the plugins
//
plugins.installPlugins(Plugins.dynamicPlugins, classLoader)
//
// Classload all the jar files and invoke their methods
//
try {
stream = JarInputStream(FileInputStream(buildScriptJarFile))
var entry = stream.nextJarEntry
val classes = hashSetOf<Class<*>>()
while (entry != null) {
val name = entry.name;
if (name.endsWith(".class")) {
val className = name.substring(0, name.length - 6).replace("/", ".")
var cl : Class<*>? = classLoader.loadClass(className)
if (cl != null) {
classes.add(cl)
} else {
throw KobaltException("Couldn't instantiate $className")
}
}
entry = stream.nextJarEntry;
}
// Invoke all the "val" found on the _DefaultPackage class (the Build.kt file)
classes.filter { cls ->
cls.name != "_DefaultPackage"
}.forEach { cls ->
cls.methods.forEach { method ->
// Invoke vals and see if they return a Project
if (method.name.startsWith("get") && Modifier.isStatic(method.modifiers)) {
try {
val r = method.invoke(null)
if (r is Project) {
log(2, "Found project $r in class $cls")
projects.add(r)
}
} catch(ex: Throwable) {
throw ex.cause ?: KobaltException(ex)
}
} else {
val taskAnnotation = method.getAnnotation(Task::class.java)
if (taskAnnotation != null) {
Plugins.defaultPlugin.methodTasks.add(IPlugin.MethodTask(method, taskAnnotation))
}
}}
}
} finally {
stream?.close()
}
validateProjects(projects)
//
// Now that the build file has run, fetch all the project contributors, grab the projects from them and sort
// them topologically
//
Topological<Project>().let { topologicalProjects ->
val all = hashSetOf<Project>()
context.pluginInfo.projectContributors.forEach { contributor ->
val descriptions = contributor.projects()
descriptions.forEach { pd ->
all.add(pd.project)
pd.dependsOn.forEach { dependsOn ->
topologicalProjects.addEdge(pd.project, dependsOn)
all.add(dependsOn)
}
}
}
val result = topologicalProjects.sort(ArrayList(all))
return result
}
}
fun isUpToDate(buildFile: BuildFile, jarFile: File) =
buildFile.exists() && jarFile.exists()
&& buildFile.lastModified < jarFile.lastModified()
/**
* Make sure all the projects have a unique name.
*/
private fun validateProjects(projects: List<Project>) {
val seen = hashSetOf<String>()
projects.forEach {
if (seen.contains(it.name)) {
throw KobaltException("Duplicate project name: $it")
} else {
seen.add(it.name)
}
}
}
}

View file

@ -1,17 +1,30 @@
package com.beust.kobalt.kotlin.internal package com.beust.kobalt.kotlin.internal
import com.beust.kobalt.Plugins
import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project
import com.beust.kobalt.kotlin.BuildFile
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.countChar import com.beust.kobalt.misc.countChar
import com.beust.kobalt.misc.log
import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
import java.io.File import java.io.File
import java.net.URL
import java.nio.charset.Charset import java.nio.charset.Charset
import java.nio.file.Paths
import java.util.* import java.util.*
class ParsedBuildFile(val file: File, val context: KobaltContext) { class ParsedBuildFile(val buildFile: BuildFile, val context: KobaltContext, val buildScriptUtil: BuildScriptUtil,
val plugins = arrayListOf<String>() val dependencyManager: DependencyManager, val files: KFiles) {
val pluginList = arrayListOf<String>()
val repos = arrayListOf<String>() val repos = arrayListOf<String>()
val profileLines = arrayListOf<String>() val profileLines = arrayListOf<String>()
val pluginUrls = arrayListOf<URL>()
val projects = arrayListOf<Project>()
private val preBuildScript = arrayListOf("import com.beust.kobalt.*", private val preBuildScript = arrayListOf(
"import com.beust.kobalt.*",
"import com.beust.kobalt.api.*") "import com.beust.kobalt.api.*")
val preBuildScriptCode : String get() = preBuildScript.joinToString("\n") val preBuildScriptCode : String get() = preBuildScript.joinToString("\n")
@ -20,15 +33,16 @@ class ParsedBuildFile(val file: File, val context: KobaltContext) {
init { init {
parseBuildFile() parseBuildFile()
initPluginUrls()
} }
private fun parseBuildFile() { private fun parseBuildFile() {
var parenCount = 0 var parenCount = 0
file.forEachLine(Charset.defaultCharset()) { line -> buildFile.path.toFile().forEachLine(Charset.defaultCharset()) { line ->
var current: ArrayList<String>? = null var current: ArrayList<String>? = null
var index = line.indexOf("plugins(") var index = line.indexOf("plugins(")
if (index >= 0) { if (index >= 0) {
current = plugins current = pluginList
} else { } else {
index = line.indexOf("repos(") index = line.indexOf("repos(")
if (index >= 0) { if (index >= 0) {
@ -66,7 +80,51 @@ class ParsedBuildFile(val file: File, val context: KobaltContext) {
} }
repos.forEach { preBuildScript.add(it) } repos.forEach { preBuildScript.add(it) }
plugins.forEach { preBuildScript.add(it) } pluginList.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")
pluginSourceFile.writeText(preBuildScriptCode, Charset.defaultCharset())
log(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"), buildScriptJarFile)
VersionFile.generateVersionFile(buildScriptJarFile.parentFile)
}
//
// 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) {
val kotlintDeps = dependencyManager.calculateDependencies(null, context)
val deps: List<String> = kotlintDeps.map { it.jarFile.get().absolutePath }
kotlinCompilePrivate {
classpath(files.kobaltJar)
classpath(deps)
sourceFiles(buildFile.path.toFile().absolutePath)
output = File(buildScriptJarFile.absolutePath)
}.compile(context = context)
} }
} }

View file

@ -0,0 +1,20 @@
package com.beust.kobalt.kotlin.internal
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.misc.KFiles
import java.io.File
class VersionFile {
companion object {
private val VERSION_FILE = "version.txt"
fun generateVersionFile(directory: File) {
KFiles.saveFile(File(directory, VERSION_FILE), Kobalt.version)
}
fun isSameVersionFile(directory: File) =
with(File(directory, VERSION_FILE)) {
! exists() || (exists() && readText() == Kobalt.version)
}
}
}