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

Merge branch 'master' of github.com:cbeust/kobalt

This commit is contained in:
Cedric Beust 2015-10-19 16:47:16 -07:00
commit 233492c237
12 changed files with 233 additions and 53 deletions

View file

@ -48,7 +48,8 @@ dependencies {
'com.google.inject.extensions:guice-assistedinject:4.0', 'com.google.inject.extensions:guice-assistedinject:4.0',
'com.google.guava:guava:18.0', 'com.google.guava:guava:18.0',
'org.apache.maven:maven-model:3.3.3', 'org.apache.maven:maven-model:3.3.3',
'com.github.spullara.mustache.java:compiler:0.8.18' 'com.github.spullara.mustache.java:compiler:0.8.18',
"io.reactivex:rxjava:1.0.14"
// compile files("/Users/beust/.kobalt/repository/com/beust/kobalt-example-plugin/build/libs/kobalt-example-plugin.jar") // compile files("/Users/beust/.kobalt/repository/com/beust/kobalt-example-plugin/build/libs/kobalt-example-plugin.jar")
testCompile 'org.testng:testng:6.9.6' testCompile 'org.testng:testng:6.9.6'

View file

@ -40,5 +40,6 @@
<orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.10" level="project" /> <orderEntry type="library" scope="TEST" name="Gradle: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.apache.ant:ant-launcher:1.7.0" level="project" /> <orderEntry type="library" scope="TEST" name="Gradle: org.apache.ant:ant-launcher:1.7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.1" level="project" /> <orderEntry type="library" scope="TEST" name="Gradle: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Gradle: io.reactivex:rxjava:1.0.14" level="project" />
</component> </component>
</module> </module>

View file

@ -66,7 +66,8 @@ val kobalt = kotlinProject(wrapper) {
"com.google.inject.extensions:guice-assistedinject:4.0", "com.google.inject.extensions:guice-assistedinject:4.0",
"com.google.guava:guava:19.0-rc2", "com.google.guava:guava:19.0-rc2",
"org.apache.maven:maven-model:3.3.3", "org.apache.maven:maven-model:3.3.3",
"com.github.spullara.mustache.java:compiler:0.9.1" "com.github.spullara.mustache.java:compiler:0.9.1",
"io.reactivex:rxjava:1.0.14"
) )
} }
} }

View file

@ -13,6 +13,9 @@ class Args {
"dependencies") "dependencies")
var checkVersions = false var checkVersions = false
@Parameter(names = arrayOf("--client"))
var client: Boolean = false
@Parameter(names = arrayOf("--dev"), description = "Turn of dev mode, resulting in a more verbose log output") @Parameter(names = arrayOf("--dev"), description = "Turn of dev mode, resulting in a more verbose log output")
var dev: Boolean = false var dev: Boolean = false
@ -29,6 +32,16 @@ class Args {
@Parameter(names = arrayOf("--log"), description = "Define the log level (1-3)") @Parameter(names = arrayOf("--log"), description = "Define the log level (1-3)")
var log: Int = 1 var log: Int = 1
companion object {
const val DEFAULT_SERVER_PORT = 3867
}
@Parameter(names = arrayOf("--port"), description = "Port, if --server was specified")
var port: Int = DEFAULT_SERVER_PORT
@Parameter(names = arrayOf("--server"), description = "Run in server mode")
var serverMode: Boolean = false
@Parameter(names = arrayOf("--tasks"), description = "Display the tasks available for this build") @Parameter(names = arrayOf("--tasks"), description = "Display the tasks available for this build")
var tasks: Boolean = false var tasks: Boolean = false

View file

@ -47,11 +47,19 @@ private class Main @Inject constructor(
val depFactory: DepFactory, val depFactory: DepFactory,
val checkVersions: CheckVersions, val checkVersions: CheckVersions,
val github: GithubApi, val github: GithubApi,
val updateKobalt: UpdateKobalt) { val updateKobalt: UpdateKobalt,
val client: KobaltClient,
val server: KobaltServer) {
data class RunInfo(val jc: JCommander, val args: Args) data class RunInfo(val jc: JCommander, val args: Args)
public fun run(jc: JCommander, args: Args) : Int { public fun run(jc: JCommander, args: Args) : Int {
if (args.client) {
client.run()
return 0
}
var result = 0 var result = 0
val latestVersionFuture = github.latestKobaltVersion val latestVersionFuture = github.latestKobaltVersion
benchmark("Build", { benchmark("Build", {
@ -77,30 +85,28 @@ private class Main @Inject constructor(
return result return result
} }
public class Worker<T>(val runNodes: ArrayList<T>, val n: T) : IWorker<T> { // public class Worker<T>(val runNodes: ArrayList<T>, val n: T) : IWorker<T> {
override val priority = 0 // override val priority = 0
//
override fun call() : TaskResult2<T> { // override fun call() : TaskResult2<T> {
log(2, "Running node ${n}") // log(2, "Running node $n")
runNodes.add(n) // runNodes.add(n)
return TaskResult2(n != 3, n) // return TaskResult2(n != 3, n)
} // }
} // }
//
private fun runTest() { // private fun runTest() {
with(Topological<String>()) { // with(Topological<String>()) {
addEdge("b1", "a1") // addEdge("b1", "a1")
addEdge("b1", "a2") // addEdge("b1", "a2")
addEdge("b2", "a1") // addEdge("b2", "a1")
addEdge("b2", "a2") // addEdge("b2", "a2")
addEdge("c1", "b1") // addEdge("c1", "b1")
addEdge("c1", "b2") // addEdge("c1", "b2")
val sorted = sort(arrayListOf("a1", "a2", "b1", "b2", "c1", "x", "y")) // val sorted = sort(arrayListOf("a1", "a2", "b1", "b2", "c1", "x", "y"))
println("Sorted: ${sorted}") // println("Sorted: $sorted")
} // }
} // }
private val SCRIPT_JAR = "buildScript.jar"
private fun runWithArgs(jc: JCommander, args: Args) : Int { private fun runWithArgs(jc: JCommander, args: Args) : Int {
var result = 0 var result = 0
@ -122,7 +128,15 @@ private class Main @Inject constructor(
} else { } else {
val context = KobaltContext(args) val context = KobaltContext(args)
Kobalt.context = context Kobalt.context = context
val allProjects = script2.create(arrayListOf(buildFile)).findProjects() val scriptCompiler = script2.create(arrayListOf(buildFile))
if (args.serverMode) {
scriptCompiler.observable.subscribe {
info -> server.sendInfo(info)
}
executors.miscExecutor.submit(server)
}
val allProjects = scriptCompiler.findProjects()
// //
// Force each project.directory to be an absolute path, if it's not already // Force each project.directory to be an absolute path, if it's not already

View file

@ -94,8 +94,7 @@ public class Kobalt {
/** /**
* @return the projects sorted topologically. * @return the projects sorted topologically.
*/ */
fun sortProjects(allProjects: ArrayList<Project>) : List<Project> fun sortProjects(allProjects: ArrayList<Project>) = topological.sort(allProjects)
= topological.sort(allProjects)
fun findPlugin(name: String) = Plugins.findPlugin(name) fun findPlugin(name: String) = Plugins.findPlugin(name)
} }

View file

@ -0,0 +1,52 @@
package com.beust.kobalt.internal
import com.beust.kobalt.Args
import com.beust.kobalt.kotlin.ScriptCompiler2
import com.beust.kobalt.mainNoExit
import com.beust.kobalt.misc.log
import com.google.inject.Inject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.ConnectException
import java.net.Socket
import java.util.concurrent.Executors
public class KobaltClient @Inject constructor() : Runnable {
var outgoing: PrintWriter? = null
override fun run() {
val portNumber = Args.DEFAULT_SERVER_PORT
Executors.newFixedThreadPool(1).submit {
log(1, "Lauching Kobalt main")
mainNoExit(arrayOf("--dev", "--server", "assemble"))
}
var done = false
var attempts = 1
while (attempts < 3 && ! done) {
try {
val socket = Socket("localhost", portNumber)
val ins = BufferedReader(InputStreamReader(socket.inputStream))
done = true
log(1, "Launching listening server")
var fromServer = ins.readLine()
while (fromServer != null) {
log(1, "From server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromServer = ins.readLine()
}
} catch(ex: ConnectException) {
log(1, "Server not up, sleeping a bit")
Thread.sleep(2000)
attempts++
}
}
}
fun sendInfo(info: ScriptCompiler2.BuildScriptInfo) {
outgoing!!.println("Sending info with project count: " + info.projects.size())
}
}

View file

@ -0,0 +1,94 @@
package com.beust.kobalt.internal
import com.beust.kobalt.Args
import com.beust.kobalt.api.Project
import com.beust.kobalt.kotlin.ScriptCompiler2
import com.beust.kobalt.maven.IClasspathDependency
import com.beust.kobalt.maven.MavenDependency
import com.beust.kobalt.maven.SimpleDep
import com.beust.kobalt.misc.KobaltExecutors
import com.beust.kobalt.misc.log
import com.google.inject.Inject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.ServerSocket
import java.util.concurrent.Executor
import java.util.concurrent.ExecutorService
public class KobaltServer @Inject constructor(val executors: KobaltExecutors) : Runnable {
var outgoing: PrintWriter? = null
val pending = arrayListOf<ScriptCompiler2.BuildScriptInfo>()
override fun run() {
val portNumber = Args.DEFAULT_SERVER_PORT
log(1, "Starting on port $portNumber")
val serverSocket = ServerSocket(portNumber)
val clientSocket = serverSocket.accept()
outgoing = PrintWriter(clientSocket.outputStream, true)
if (pending.size() > 0) {
log(1, "Emptying the queue, size $pending.size()")
synchronized(pending) {
pending.forEach { sendInfo(it) }
pending.clear()
}
}
val ins = BufferedReader(InputStreamReader(clientSocket.inputStream))
var inputLine = ins.readLine()
while (inputLine != null) {
log(1, "Received $inputLine")
if (inputLine.equals("Bye."))
break;
inputLine = ins.readLine()
}
}
fun sendInfo(info: ScriptCompiler2.BuildScriptInfo) {
if (outgoing != null) {
val json = toJson(info, executors.miscExecutor)
outgoing!!.println(json)
} else {
log(1, "Queuing $info")
synchronized(pending) {
pending.add(info)
}
}
}
companion object {
internal fun toJson(info: ScriptCompiler2.BuildScriptInfo, executor: ExecutorService): String {
val result = "{ projects: [" +
info.projects.map { toJson(it, executor) }.join(",\n") +
"]\n}\n"
return result
}
private fun toJson(project: Project, executor: ExecutorService): String {
var result = "{\n" +
arrayListOf(
"\"name\" : \"${project.name}\"",
toJson("dependencies", project.compileDependencies, executor),
toJson("providedDependencies", project.compileProvidedDependencies, executor),
toJson("runtimeDependencies", project.compileRuntimeDependencies, executor),
toJson("testDependencies", project.testDependencies, executor),
toJson("testProvidedDependencies", project.testProvidedDependencies, executor)
).join(",\n") +
"}\n"
return result
}
private fun toJson(name: String, dependencies: List<IClasspathDependency>, executor: ExecutorService) : String {
return "\"$name\" : [" +
dependencies.map {
val dep = MavenDependency.create(it.id, executor)
val path = dep.jarFile.get()
"{\n" +
"\"id\" : \"${it.id}\",\n" +
"\"path\" : \"$path\"" +
"}\n"
}.join(",") +
"]"
}
}
}

View file

@ -5,12 +5,12 @@ import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.Plugin import com.beust.kobalt.api.Plugin
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.internal.KobaltServer
import com.beust.kobalt.maven.KobaltException import com.beust.kobalt.maven.KobaltException
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.*
import com.beust.kobalt.misc.countChar
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 java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.InputStream import java.io.InputStream
@ -29,6 +29,8 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
fun create(@Assisted("buildFiles") buildFiles: List<BuildFile>) : ScriptCompiler2 fun create(@Assisted("buildFiles") buildFiles: List<BuildFile>) : ScriptCompiler2
} }
val observable = PublishSubject.create<BuildScriptInfo>()
private val SCRIPT_JAR = "buildScript.jar" private val SCRIPT_JAR = "buildScript.jar"
fun findProjects(): List<Project> { fun findProjects(): List<Project> {
@ -38,8 +40,8 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR)) val buildScriptJarFile = File(KFiles.findBuildScriptLocation(buildFile, SCRIPT_JAR))
maybeCompileBuildFile(buildFile, buildScriptJarFile, pluginUrls) maybeCompileBuildFile(buildFile, buildScriptJarFile, pluginUrls)
val output = parseBuildScriptJarFile(buildScriptJarFile, pluginUrls) val buildScriptInfo = parseBuildScriptJarFile(buildScriptJarFile, pluginUrls)
result.addAll(output.projects) result.addAll(buildScriptInfo.projects)
} }
return result return result
} }
@ -107,7 +109,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
// //
// Run preBuildScript.jar to initialize plugins and repos // Run preBuildScript.jar to initialize plugins and repos
// //
val projectInfo = parseBuildScriptJarFile(buildScriptJarFile, arrayListOf<URL>()) parseBuildScriptJarFile(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
@ -130,7 +132,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
class BuildScriptInfo(val projects: List<Project>, val classLoader: ClassLoader) class BuildScriptInfo(val projects: List<Project>, val classLoader: ClassLoader)
private fun parseBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>) : BuildScriptInfo { private fun parseBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>) : BuildScriptInfo {
val result = arrayListOf<Project>() val projects = arrayListOf<Project>()
var stream : InputStream? = null var stream : InputStream? = null
val allUrls = arrayListOf<URL>().plus(urls).plus(arrayOf( val allUrls = arrayListOf<URL>().plus(urls).plus(arrayOf(
buildScriptJarFile.toURI().toURL(), buildScriptJarFile.toURI().toURL(),
@ -156,7 +158,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
if (cl != null) { if (cl != null) {
classes.add(cl) classes.add(cl)
} else { } else {
throw KobaltException("Couldn't instantiate ${className}") throw KobaltException("Couldn't instantiate $className")
} }
} }
entry = stream.nextJarEntry; entry = stream.nextJarEntry;
@ -171,13 +173,12 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
if (method.name.startsWith("get") && Modifier.isStatic(method.modifiers)) { if (method.name.startsWith("get") && Modifier.isStatic(method.modifiers)) {
val r = method.invoke(null) val r = method.invoke(null)
if (r is Project) { if (r is Project) {
log(2, "Found project ${r} in class ${cls}") log(2, "Found project $r in class $cls")
result.add(r) projects.add(r)
} }
} else { } else {
val taskAnnotation = method.getAnnotation(Task::class.java) val taskAnnotation = method.getAnnotation(Task::class.java)
if (taskAnnotation != null) { if (taskAnnotation != null) {
// Plugins.defaultPlugin.addTask(taskAnnotation, )
Plugins.defaultPlugin.methodTasks.add(Plugin.MethodTask(method, taskAnnotation)) Plugins.defaultPlugin.methodTasks.add(Plugin.MethodTask(method, taskAnnotation))
} }
@ -188,6 +189,8 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
} }
// Now that we all the projects, sort them topologically // Now that we all the projects, sort them topologically
return BuildScriptInfo(Kobalt.sortProjects(result), classLoader) val result = BuildScriptInfo(Kobalt.sortProjects(projects), classLoader)
observable.onNext(result)
return result
} }
} }

View file

@ -38,7 +38,7 @@ public class Gpg {
if (gpg != null) { if (gpg != null) {
val directory = files.get(0).parentFile.absoluteFile val directory = files.get(0).parentFile.absoluteFile
files.forEach { file -> files.forEach { file ->
val ascFile = File(directory, file.absolutePath + ".asc") val ascFile = File(file.absolutePath + ".asc")
ascFile.delete() ascFile.delete()
val allArgs = arrayListOf<String>() val allArgs = arrayListOf<String>()
allArgs.add(gpg) allArgs.add(gpg)

View file

@ -25,7 +25,7 @@ open public class SimpleDep(override val groupId: String, override val artifactI
fun toPomFile(r: RepoFinder.RepoResult) = toFile(r.version, r.snapshotVersion, ".pom") fun toPomFile(r: RepoFinder.RepoResult) = toFile(r.version, r.snapshotVersion, ".pom")
fun toJarFile(v: String) = toFile(v, "", ".jar") fun toJarFile(v: String = version) = toFile(v, "", ".jar")
fun toJarFile(r: RepoFinder.RepoResult) = toFile(r.version, r.snapshotVersion, ".jar") fun toJarFile(r: RepoFinder.RepoResult) = toFile(r.version, r.snapshotVersion, ".jar")

View file

@ -13,19 +13,21 @@ import java.nio.file.StandardCopyOption
public class KFiles { public class KFiles {
val kobaltJar : String val kobaltJar : String
get() { get() {
val jar = joinDir(distributionsDir, Kobalt.version, "kobalt/wrapper/kobalt-" + Kobalt.version + ".jar")
val jarFile = File(jar)
val envJar = System.getenv("KOBALT_JAR") val envJar = System.getenv("KOBALT_JAR")
if (! jarFile.exists() && envJar != null) { if (envJar != null) {
debug("Using kobalt jar $envJar") debug("Using kobalt jar $envJar")
return File(envJar).absolutePath return File(envJar).absolutePath
}
if (! jarFile.exists()) {
// Will only happen when building kobalt itself: the jar file might not be in the dist/ directory
// yet since we're currently building it. Instead, use the classes directly
return File(joinDir("build", "classes", "main")).absolutePath
} else { } else {
return jar val jar = joinDir(distributionsDir, Kobalt.version, "kobalt/wrapper/kobalt-" + Kobalt.version + ".jar")
val jarFile = File(jar)
if (! jarFile.exists()) {
return jarFile.absolutePath
} else {
// Will only happen when building kobalt itself: the jar file might not be in the dist/ directory
// yet since we're currently building it. Instead, use the classes directly
debug("Couldn't find a kobalt.jar file, using build/classes/main")
return java.io.File(joinDir("build", "classes", "main")).absolutePath
}
} }
} }