mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-25 16:07:12 -07:00
Merge branch 'master' of github.com:cbeust/kobalt
This commit is contained in:
commit
233492c237
12 changed files with 233 additions and 53 deletions
|
@ -48,7 +48,8 @@ dependencies {
|
|||
'com.google.inject.extensions:guice-assistedinject:4.0',
|
||||
'com.google.guava:guava:18.0',
|
||||
'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")
|
||||
testCompile 'org.testng:testng:6.9.6'
|
||||
|
|
|
@ -40,5 +40,6 @@
|
|||
<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.hamcrest:hamcrest-core:1.1" level="project" />
|
||||
<orderEntry type="library" name="Gradle: io.reactivex:rxjava:1.0.14" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -66,7 +66,8 @@ val kobalt = kotlinProject(wrapper) {
|
|||
"com.google.inject.extensions:guice-assistedinject:4.0",
|
||||
"com.google.guava:guava:19.0-rc2",
|
||||
"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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ class Args {
|
|||
"dependencies")
|
||||
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")
|
||||
var dev: Boolean = false
|
||||
|
||||
|
@ -29,6 +32,16 @@ class Args {
|
|||
@Parameter(names = arrayOf("--log"), description = "Define the log level (1-3)")
|
||||
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")
|
||||
var tasks: Boolean = false
|
||||
|
||||
|
|
|
@ -47,11 +47,19 @@ private class Main @Inject constructor(
|
|||
val depFactory: DepFactory,
|
||||
val checkVersions: CheckVersions,
|
||||
val github: GithubApi,
|
||||
val updateKobalt: UpdateKobalt) {
|
||||
val updateKobalt: UpdateKobalt,
|
||||
val client: KobaltClient,
|
||||
val server: KobaltServer) {
|
||||
|
||||
data class RunInfo(val jc: JCommander, val args: Args)
|
||||
|
||||
public fun run(jc: JCommander, args: Args) : Int {
|
||||
|
||||
if (args.client) {
|
||||
client.run()
|
||||
return 0
|
||||
}
|
||||
|
||||
var result = 0
|
||||
val latestVersionFuture = github.latestKobaltVersion
|
||||
benchmark("Build", {
|
||||
|
@ -77,30 +85,28 @@ private class Main @Inject constructor(
|
|||
return result
|
||||
}
|
||||
|
||||
public class Worker<T>(val runNodes: ArrayList<T>, val n: T) : IWorker<T> {
|
||||
override val priority = 0
|
||||
|
||||
override fun call() : TaskResult2<T> {
|
||||
log(2, "Running node ${n}")
|
||||
runNodes.add(n)
|
||||
return TaskResult2(n != 3, n)
|
||||
}
|
||||
}
|
||||
|
||||
private fun runTest() {
|
||||
with(Topological<String>()) {
|
||||
addEdge("b1", "a1")
|
||||
addEdge("b1", "a2")
|
||||
addEdge("b2", "a1")
|
||||
addEdge("b2", "a2")
|
||||
addEdge("c1", "b1")
|
||||
addEdge("c1", "b2")
|
||||
val sorted = sort(arrayListOf("a1", "a2", "b1", "b2", "c1", "x", "y"))
|
||||
println("Sorted: ${sorted}")
|
||||
}
|
||||
}
|
||||
|
||||
private val SCRIPT_JAR = "buildScript.jar"
|
||||
// public class Worker<T>(val runNodes: ArrayList<T>, val n: T) : IWorker<T> {
|
||||
// override val priority = 0
|
||||
//
|
||||
// override fun call() : TaskResult2<T> {
|
||||
// log(2, "Running node $n")
|
||||
// runNodes.add(n)
|
||||
// return TaskResult2(n != 3, n)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun runTest() {
|
||||
// with(Topological<String>()) {
|
||||
// addEdge("b1", "a1")
|
||||
// addEdge("b1", "a2")
|
||||
// addEdge("b2", "a1")
|
||||
// addEdge("b2", "a2")
|
||||
// addEdge("c1", "b1")
|
||||
// addEdge("c1", "b2")
|
||||
// val sorted = sort(arrayListOf("a1", "a2", "b1", "b2", "c1", "x", "y"))
|
||||
// println("Sorted: $sorted")
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun runWithArgs(jc: JCommander, args: Args) : Int {
|
||||
var result = 0
|
||||
|
@ -122,7 +128,15 @@ private class Main @Inject constructor(
|
|||
} else {
|
||||
val context = KobaltContext(args)
|
||||
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
|
||||
|
|
|
@ -94,8 +94,7 @@ public class Kobalt {
|
|||
/**
|
||||
* @return the projects sorted topologically.
|
||||
*/
|
||||
fun sortProjects(allProjects: ArrayList<Project>) : List<Project>
|
||||
= topological.sort(allProjects)
|
||||
fun sortProjects(allProjects: ArrayList<Project>) = topological.sort(allProjects)
|
||||
|
||||
fun findPlugin(name: String) = Plugins.findPlugin(name)
|
||||
}
|
||||
|
|
52
src/main/kotlin/com/beust/kobalt/internal/KobaltClient.kt
Normal file
52
src/main/kotlin/com/beust/kobalt/internal/KobaltClient.kt
Normal 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())
|
||||
}
|
||||
}
|
94
src/main/kotlin/com/beust/kobalt/internal/KobaltServer.kt
Normal file
94
src/main/kotlin/com/beust/kobalt/internal/KobaltServer.kt
Normal 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(",") +
|
||||
"]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,12 +5,12 @@ import com.beust.kobalt.api.Kobalt
|
|||
import com.beust.kobalt.api.Plugin
|
||||
import com.beust.kobalt.api.Project
|
||||
import com.beust.kobalt.api.annotation.Task
|
||||
import com.beust.kobalt.internal.KobaltServer
|
||||
import com.beust.kobalt.maven.KobaltException
|
||||
import com.beust.kobalt.misc.KFiles
|
||||
import com.beust.kobalt.misc.countChar
|
||||
import com.beust.kobalt.misc.log
|
||||
import com.beust.kobalt.misc.*
|
||||
import com.beust.kobalt.plugin.kotlin.kotlinCompilePrivate
|
||||
import com.google.inject.assistedinject.Assisted
|
||||
import rx.subjects.PublishSubject
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
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
|
||||
}
|
||||
|
||||
val observable = PublishSubject.create<BuildScriptInfo>()
|
||||
|
||||
private val SCRIPT_JAR = "buildScript.jar"
|
||||
|
||||
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))
|
||||
|
||||
maybeCompileBuildFile(buildFile, buildScriptJarFile, pluginUrls)
|
||||
val output = parseBuildScriptJarFile(buildScriptJarFile, pluginUrls)
|
||||
result.addAll(output.projects)
|
||||
val buildScriptInfo = parseBuildScriptJarFile(buildScriptJarFile, pluginUrls)
|
||||
result.addAll(buildScriptInfo.projects)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -107,7 +109,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
|
|||
//
|
||||
// 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
|
||||
|
@ -130,7 +132,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
|
|||
class BuildScriptInfo(val projects: List<Project>, val classLoader: ClassLoader)
|
||||
|
||||
private fun parseBuildScriptJarFile(buildScriptJarFile: File, urls: List<URL>) : BuildScriptInfo {
|
||||
val result = arrayListOf<Project>()
|
||||
val projects = arrayListOf<Project>()
|
||||
var stream : InputStream? = null
|
||||
val allUrls = arrayListOf<URL>().plus(urls).plus(arrayOf(
|
||||
buildScriptJarFile.toURI().toURL(),
|
||||
|
@ -156,7 +158,7 @@ public class ScriptCompiler2 @Inject constructor(@Assisted("buildFiles") val bui
|
|||
if (cl != null) {
|
||||
classes.add(cl)
|
||||
} else {
|
||||
throw KobaltException("Couldn't instantiate ${className}")
|
||||
throw KobaltException("Couldn't instantiate $className")
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
val r = method.invoke(null)
|
||||
if (r is Project) {
|
||||
log(2, "Found project ${r} in class ${cls}")
|
||||
result.add(r)
|
||||
log(2, "Found project $r in class $cls")
|
||||
projects.add(r)
|
||||
}
|
||||
} else {
|
||||
val taskAnnotation = method.getAnnotation(Task::class.java)
|
||||
if (taskAnnotation != null) {
|
||||
// Plugins.defaultPlugin.addTask(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
|
||||
return BuildScriptInfo(Kobalt.sortProjects(result), classLoader)
|
||||
val result = BuildScriptInfo(Kobalt.sortProjects(projects), classLoader)
|
||||
observable.onNext(result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class Gpg {
|
|||
if (gpg != null) {
|
||||
val directory = files.get(0).parentFile.absoluteFile
|
||||
files.forEach { file ->
|
||||
val ascFile = File(directory, file.absolutePath + ".asc")
|
||||
val ascFile = File(file.absolutePath + ".asc")
|
||||
ascFile.delete()
|
||||
val allArgs = arrayListOf<String>()
|
||||
allArgs.add(gpg)
|
||||
|
|
|
@ -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 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")
|
||||
|
||||
|
|
|
@ -13,19 +13,21 @@ import java.nio.file.StandardCopyOption
|
|||
public class KFiles {
|
||||
val kobaltJar : String
|
||||
get() {
|
||||
val jar = joinDir(distributionsDir, Kobalt.version, "kobalt/wrapper/kobalt-" + Kobalt.version + ".jar")
|
||||
val jarFile = File(jar)
|
||||
val envJar = System.getenv("KOBALT_JAR")
|
||||
if (! jarFile.exists() && envJar != null) {
|
||||
if (envJar != null) {
|
||||
debug("Using kobalt jar $envJar")
|
||||
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 {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue