1
0
Fork 0
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:
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.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'

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: 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>

View file

@ -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"
)
}
}

View file

@ -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

View file

@ -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

View file

@ -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)
}

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.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
}
}

View file

@ -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)

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 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")

View file

@ -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
}
}
}