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

Profiles.

This commit is contained in:
Cedric Beust 2015-11-26 05:23:42 -08:00
parent 833f2e2bbf
commit 57f8ec90c4
4 changed files with 120 additions and 32 deletions

View file

@ -42,6 +42,9 @@ class Args {
@Parameter(names = arrayOf("--port"), description = "Port, if --server was specified") @Parameter(names = arrayOf("--port"), description = "Port, if --server was specified")
var port: Int = DEFAULT_SERVER_PORT var port: Int = DEFAULT_SERVER_PORT
@Parameter(names = arrayOf("--profiles"), description = "Comma-separate list of profiles to run")
var profiles: String? = null
@Parameter(names = arrayOf("--resolve"), description = "Resolve the given dependency and display its tree") @Parameter(names = arrayOf("--resolve"), description = "Resolve the given dependency and display its tree")
var dependency: String? = null var dependency: String? = null

View file

@ -2,17 +2,29 @@ package com.beust.kobalt.api
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.Plugins import com.beust.kobalt.Plugins
import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.Variant import com.beust.kobalt.Variant
import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.KobaltExecutors
public class KobaltContext(val args: Args) { public class KobaltContext(val args: Args) {
var variant: Variant = Variant()
val profiles = arrayListOf<String>()
init {
args.profiles?.split(",")?.filterNotNull()?.forEach {
profiles.add(it)
}
}
fun findPlugin(name: String) = Plugins.findPlugin(name) fun findPlugin(name: String) = Plugins.findPlugin(name)
//
// Injected
//
lateinit var pluginInfo: PluginInfo lateinit var pluginInfo: PluginInfo
lateinit var pluginProperties: PluginProperties lateinit var pluginProperties: PluginProperties
lateinit var dependencyManager: DependencyManager lateinit var dependencyManager: DependencyManager
lateinit var executors: KobaltExecutors lateinit var executors: KobaltExecutors
var variant: Variant = Variant()
} }

View file

@ -6,8 +6,12 @@ import com.beust.kobalt.Plugins
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.kotlin.internal.ParsedBuildFile
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.* import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.Topological
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
@ -75,7 +79,8 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
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 pluginUrls = findPlugInUrls(context, buildFile) val pair = processBuildFile(context, buildFile)
val pluginUrls = pair.second
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
@ -87,8 +92,13 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
} }
} }
maybeCompileBuildFile(context, buildFile, buildScriptJarFile, pluginUrls) // Write the modified Build.kt (e.g. maybe profiles were applied) to a temporary file,
val buildScriptInfo = parseBuildScriptJarFile(buildScriptJarFile, pluginUrls) // compile it and run it
val modifiedBuildFile = KFiles.createTempFile(".kt")
KFiles.saveFile(modifiedBuildFile, pair.first.buildScriptCode)
maybeCompileBuildFile(context, BuildFile(Paths.get(modifiedBuildFile.path), "Modified Build.kt"),
buildScriptJarFile, pluginUrls)
val buildScriptInfo = runBuildScriptJarFile(buildScriptJarFile, pluginUrls)
result.addAll(buildScriptInfo.projects) result.addAll(buildScriptInfo.projects)
} }
return result return result
@ -123,36 +133,21 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
/** /**
* Generate the script file with only the plugins()/repos() directives and run it. Then return * Generate the script file with only the plugins()/repos() directives and run it. Then return
* the URL's of all the plug-ins that were found. * - the source code for the modified Build.kt (after profiles are applied)
* - the URL's of all the plug-ins that were found.
*/ */
private fun findPlugInUrls(context: KobaltContext, buildFile: BuildFile): List<URL> { private fun processBuildFile(context: KobaltContext, buildFile: BuildFile): Pair<ParsedBuildFile, List<URL>> {
val result = arrayListOf<URL>() val result = arrayListOf<URL>()
val pluginCode = arrayListOf(
"import com.beust.kobalt.*", // Parse the build file so we can generate preBuildScript and buildScript from it.
"import com.beust.kobalt.api.*" val parsedBuildFile = ParsedBuildFile(buildFile.path.toFile(), context)
)
var parenCount = 0
buildFile.path.toFile().forEachLine(Charset.defaultCharset()) { line ->
var index = line.indexOf("plugins(")
if (index == -1) index = line.indexOf("repos(")
if (parenCount > 0 || index >= 0) {
if (index == -1) index = 0
with(line.substring(index)) {
parenCount += line countChar '('
if (parenCount > 0) {
pluginCode.add(line)
}
parenCount -= line countChar ')'
}
}
}
// //
// Compile and run pluginCode, which contains all the plugins() calls extracted. This // 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 // will add all the dynamic plugins found in this code to Plugins.dynamicPlugins
// //
val pluginSourceFile = KFiles.createTempFile(".kt") val pluginSourceFile = KFiles.createTempFile(".kt")
pluginSourceFile.writeText(pluginCode.joinToString("\n"), Charset.defaultCharset()) pluginSourceFile.writeText(parsedBuildFile.preBuildScriptCode, Charset.defaultCharset())
log(2, "Saved ${pluginSourceFile.absolutePath}") log(2, "Saved ${pluginSourceFile.absolutePath}")
// //
@ -169,7 +164,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
// //
// Run preBuildScript.jar to initialize plugins and repos // Run preBuildScript.jar to initialize plugins and repos
// //
parseBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>()) runBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>())
// //
// All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already // All the plug-ins are now in Plugins.dynamicPlugins, download them if they're not already
@ -178,7 +173,7 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
result.add(it.jarFile.get().toURI().toURL()) result.add(it.jarFile.get().toURI().toURL())
} }
return result return Pair(parsedBuildFile, result)
} }
private val VERSION_FILE = "version.txt" private val VERSION_FILE = "version.txt"
@ -205,7 +200,10 @@ public class BuildFileCompiler @Inject constructor(@Assisted("buildFiles") val b
class BuildScriptInfo(val projects: List<Project>) class BuildScriptInfo(val projects: List<Project>)
private fun parseBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>) : BuildScriptInfo { /**
* 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>() val projects = arrayListOf<Project>()
var stream : InputStream? = null var stream : InputStream? = null
val allUrls = (urls + arrayOf( val allUrls = (urls + arrayOf(

View file

@ -0,0 +1,75 @@
package com.beust.kobalt.kotlin.internal
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.misc.countChar
import java.io.File
import java.nio.charset.Charset
import java.util.*
class ParsedBuildFile(val file: File, val context: KobaltContext) {
val plugins = arrayListOf<String>()
val repos = arrayListOf<String>()
val profileLines = arrayListOf<String>()
private val preBuildScript = arrayListOf("import com.beust.kobalt.*",
"import com.beust.kobalt.api.*")
val preBuildScriptCode : String get() = preBuildScript.joinToString("\n")
private val buildScript = arrayListOf<String>()
val buildScriptCode : String get() = buildScript.joinToString("\n")
init {
parseBuildFile()
}
private fun parseBuildFile() {
var parenCount = 0
file.forEachLine(Charset.defaultCharset()) { line ->
var current: ArrayList<String>? = null
var index = line.indexOf("plugins(")
if (index >= 0) {
current = plugins
} else {
index = line.indexOf("repos(")
if (index >= 0) {
current = repos
}
}
if (parenCount > 0 || current != null) {
if (index == -1) index = 0
with(line.substring(index)) {
parenCount += line countChar '('
if (parenCount > 0) {
current!!.add(line)
}
parenCount -= line countChar ')'
}
}
/**
* If the current line matches one of the profile, turns the declaration into
* val profile = true, otherwise return the same line
*/
fun correctProfileLine(line: String) : String {
if (line.contains("experimental")) {
println("DONOTCOMMIT")
}
context.profiles.forEach {
if (line.matches(kotlin.text.Regex("[ \\t]*val[ \\t]+$it[ \\t]+=.*"))) {
with("val $it = true") {
profileLines.add(this)
return this
}
}
}
return line
}
buildScript.add(correctProfileLine(line))
}
repos.forEach { preBuildScript.add(it) }
plugins.forEach { preBuildScript.add(it) }
}
}