mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 08:27:12 -07:00
Add isLatest
to nodes returned from the GetDependencies call.
This commit is contained in:
parent
2ebf932d21
commit
50b1ded7bb
10 changed files with 101 additions and 33 deletions
|
@ -0,0 +1,35 @@
|
||||||
|
package com.beust.kobalt.internal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic operations on graph-like structures.
|
||||||
|
*/
|
||||||
|
object GraphUtil {
|
||||||
|
/**
|
||||||
|
* Apply the operation in `closure` to all the nodes in the tree.
|
||||||
|
*/
|
||||||
|
fun <T> map(roots: List<T>, children: (T) -> List<T>, closure: (T) -> Unit) {
|
||||||
|
roots.forEach {
|
||||||
|
closure(it)
|
||||||
|
map(children(it), children, closure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display each node in the roots by calling the `display` function on each of them.
|
||||||
|
*/
|
||||||
|
fun <T> displayGraph(roots: List<T>,
|
||||||
|
children: (T) -> List<T>,
|
||||||
|
display: (node: T, indent: String) -> Unit) {
|
||||||
|
|
||||||
|
fun pd(node: T, indent: String) {
|
||||||
|
display(node, indent)
|
||||||
|
children(node).forEach {
|
||||||
|
pd(it, indent + " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roots.forEach {
|
||||||
|
pd(it, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.beust.kobalt.api.IClasspathDependency
|
||||||
import com.beust.kobalt.api.Kobalt
|
import com.beust.kobalt.api.Kobalt
|
||||||
import com.beust.kobalt.api.PluginTask
|
import com.beust.kobalt.api.PluginTask
|
||||||
import com.beust.kobalt.app.*
|
import com.beust.kobalt.app.*
|
||||||
import com.beust.kobalt.app.remote.DependencyData
|
import com.beust.kobalt.app.remote.RemoteDependencyData
|
||||||
import com.beust.kobalt.app.remote.KobaltClient
|
import com.beust.kobalt.app.remote.KobaltClient
|
||||||
import com.beust.kobalt.app.remote.KobaltServer
|
import com.beust.kobalt.app.remote.KobaltServer
|
||||||
import com.beust.kobalt.internal.Gc
|
import com.beust.kobalt.internal.Gc
|
||||||
|
@ -69,7 +69,7 @@ private class Main @Inject constructor(
|
||||||
val projectGenerator: ProjectGenerator,
|
val projectGenerator: ProjectGenerator,
|
||||||
val serverFactory: KobaltServer.IFactory,
|
val serverFactory: KobaltServer.IFactory,
|
||||||
val projectFinder: ProjectFinder,
|
val projectFinder: ProjectFinder,
|
||||||
val dependencyData: DependencyData,
|
val dependencyData: RemoteDependencyData,
|
||||||
val resolveDependency: ResolveDependency) {
|
val resolveDependency: ResolveDependency) {
|
||||||
|
|
||||||
data class RunInfo(val jc: JCommander, val args: Args)
|
data class RunInfo(val jc: JCommander, val args: Args)
|
||||||
|
|
|
@ -15,7 +15,7 @@ import javax.inject.Inject
|
||||||
* The response is a GetDependenciesData.
|
* The response is a GetDependenciesData.
|
||||||
*/
|
*/
|
||||||
@Deprecated(message = "Only used by old server, to be deleted")
|
@Deprecated(message = "Only used by old server, to be deleted")
|
||||||
class GetDependenciesCommand @Inject constructor(val args: Args, val dependencyData: DependencyData) : ICommand {
|
class GetDependenciesCommand @Inject constructor(val args: Args, val dependencyData: RemoteDependencyData) : ICommand {
|
||||||
|
|
||||||
override val name = "getDependencies"
|
override val name = "getDependencies"
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ class GetDependencyGraphHandler : WebSocketListener {
|
||||||
// Get the dependencies for the requested build file and send progress to the web
|
// Get the dependencies for the requested build file and send progress to the web
|
||||||
// socket for each project
|
// socket for each project
|
||||||
try {
|
try {
|
||||||
val dependencyData = getInstance(DependencyData::class.java)
|
val dependencyData = getInstance(RemoteDependencyData::class.java)
|
||||||
val args = getInstance(Args::class.java)
|
val args = getInstance(Args::class.java)
|
||||||
|
|
||||||
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
||||||
|
@ -75,16 +75,16 @@ class GetDependencyGraphHandler : WebSocketListener {
|
||||||
} catch(ex: Throwable) {
|
} catch(ex: Throwable) {
|
||||||
Exceptions.printStackTrace(ex)
|
Exceptions.printStackTrace(ex)
|
||||||
val errorMessage = ex.stackTrace.map { it.toString() }.joinToString("\n<p>")
|
val errorMessage = ex.stackTrace.map { it.toString() }.joinToString("\n<p>")
|
||||||
DependencyData.GetDependenciesData(errorMessage = errorMessage)
|
RemoteDependencyData.GetDependenciesData(errorMessage = errorMessage)
|
||||||
} finally {
|
} finally {
|
||||||
SparkServer.cleanUpCallback()
|
SparkServer.cleanUpCallback()
|
||||||
eventBus.unregister(busListener)
|
eventBus.unregister(busListener)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DependencyData.GetDependenciesData(
|
RemoteDependencyData.GetDependenciesData(
|
||||||
errorMessage = "buildFile wasn't passed in the query parameter")
|
errorMessage = "buildFile wasn't passed in the query parameter")
|
||||||
}
|
}
|
||||||
sendWebsocketCommand(s.remote, DependencyData.GetDependenciesData.NAME, result)
|
sendWebsocketCommand(s.remote, RemoteDependencyData.GetDependenciesData.NAME, result)
|
||||||
s.close()
|
s.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
// @Produces(MediaType.APPLICATION_JSON)
|
// @Produces(MediaType.APPLICATION_JSON)
|
||||||
// fun getDependencies(@QueryParam("buildFile") buildFile: String) : String {
|
// fun getDependencies(@QueryParam("buildFile") buildFile: String) : String {
|
||||||
// try {
|
// try {
|
||||||
// val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
|
// val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
|
||||||
// val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
// val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
||||||
//
|
//
|
||||||
// val projects = JerseyServer.initCallback(buildFile)
|
// val projects = JerseyServer.initCallback(buildFile)
|
||||||
|
|
|
@ -47,7 +47,7 @@ interface Api {
|
||||||
|
|
||||||
@Deprecated(message = "Replaced with /v1/getDependencies")
|
@Deprecated(message = "Replaced with /v1/getDependencies")
|
||||||
@POST("/v0/getDependencies")
|
@POST("/v0/getDependencies")
|
||||||
fun getDependencies(@Query("buildFile") buildFile: String) : Call<List<DependencyData.GetDependenciesData>>
|
fun getDependencies(@Query("buildFile") buildFile: String) : Call<List<RemoteDependencyData.GetDependenciesData>>
|
||||||
}
|
}
|
||||||
|
|
||||||
class KobaltWebSocketClient : Runnable {
|
class KobaltWebSocketClient : Runnable {
|
||||||
|
@ -82,8 +82,8 @@ class KobaltWebSocketClient : Runnable {
|
||||||
if (wsCommand.errorMessage != null) {
|
if (wsCommand.errorMessage != null) {
|
||||||
warn("Received error message from server: " + wsCommand.errorMessage)
|
warn("Received error message from server: " + wsCommand.errorMessage)
|
||||||
} else {
|
} else {
|
||||||
if (wsCommand.commandName == DependencyData.GetDependenciesData.NAME) {
|
if (wsCommand.commandName == RemoteDependencyData.GetDependenciesData.NAME) {
|
||||||
val dd = Gson().fromJson(wsCommand.payload, DependencyData.GetDependenciesData::class.java)
|
val dd = Gson().fromJson(wsCommand.payload, RemoteDependencyData.GetDependenciesData::class.java)
|
||||||
println("Received dependency data: " + dd.projects.size + " projects"
|
println("Received dependency data: " + dd.projects.size + " projects"
|
||||||
+ " error: " + dd.errorMessage)
|
+ " error: " + dd.errorMessage)
|
||||||
} else if (wsCommand.commandName == ProgressCommand.NAME) {
|
} else if (wsCommand.commandName == ProgressCommand.NAME) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ import com.google.gson.Gson
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
class KobaltHub(val dependencyData: DependencyData) {
|
class KobaltHub(val dependencyData: RemoteDependencyData) {
|
||||||
val args = Args()
|
val args = Args()
|
||||||
|
|
||||||
fun runCommand(n: Int) : String {
|
fun runCommand(n: Int) : String {
|
||||||
|
@ -35,8 +35,8 @@ class KobaltHub(val dependencyData: DependencyData) {
|
||||||
|
|
||||||
fun main(argv: Array<String>) {
|
fun main(argv: Array<String>) {
|
||||||
Kobalt.init(MainModule(Args(), KobaltSettings.readSettingsXml()))
|
Kobalt.init(MainModule(Args(), KobaltSettings.readSettingsXml()))
|
||||||
val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
|
val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
|
||||||
val json = KobaltHub(dependencyData).runCommand(1)
|
val json = KobaltHub(dependencyData).runCommand(1)
|
||||||
val dd = Gson().fromJson(json, DependencyData.GetDependenciesData::class.java)
|
val dd = Gson().fromJson(json, RemoteDependencyData.GetDependenciesData::class.java)
|
||||||
println("Data2: $dd")
|
println("Data2: $dd")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,16 @@ import com.beust.kobalt.api.IClasspathDependency
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.app.BuildFileCompiler
|
import com.beust.kobalt.app.BuildFileCompiler
|
||||||
import com.beust.kobalt.internal.DynamicGraph
|
import com.beust.kobalt.internal.DynamicGraph
|
||||||
|
import com.beust.kobalt.internal.GraphUtil
|
||||||
import com.beust.kobalt.internal.PluginInfo
|
import com.beust.kobalt.internal.PluginInfo
|
||||||
import com.beust.kobalt.internal.TaskManager
|
import com.beust.kobalt.internal.TaskManager
|
||||||
import com.beust.kobalt.internal.build.BuildFile
|
import com.beust.kobalt.internal.build.BuildFile
|
||||||
import com.beust.kobalt.maven.DependencyManager
|
import com.beust.kobalt.maven.DependencyManager
|
||||||
|
import com.beust.kobalt.maven.MavenId
|
||||||
import com.beust.kobalt.maven.dependency.FileDependency
|
import com.beust.kobalt.maven.dependency.FileDependency
|
||||||
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.Versions
|
||||||
import com.beust.kobalt.misc.log
|
import com.beust.kobalt.misc.log
|
||||||
import com.google.inject.Inject
|
import com.google.inject.Inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -24,7 +27,7 @@ interface IProgressListener {
|
||||||
fun onProgress(progress: Int? = null, message: String? = null)
|
fun onProgress(progress: Int? = null, message: String? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class DependencyData @Inject constructor(val executors: KobaltExecutors, val dependencyManager: DependencyManager,
|
class RemoteDependencyData @Inject constructor(val executors: KobaltExecutors, val dependencyManager: DependencyManager,
|
||||||
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val pluginInfo: PluginInfo,
|
val buildFileCompilerFactory: BuildFileCompiler.IFactory, val pluginInfo: PluginInfo,
|
||||||
val taskManager: TaskManager) {
|
val taskManager: TaskManager) {
|
||||||
|
|
||||||
|
@ -61,16 +64,47 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
||||||
val d = node.value
|
val d = node.value
|
||||||
val dep = dependencyManager.create(d.id)
|
val dep = dependencyManager.create(d.id)
|
||||||
return DependencyData(d.id, scope, dep.jarFile.get().absolutePath,
|
return DependencyData(d.id, scope, dep.jarFile.get().absolutePath,
|
||||||
node.children.map { toDependencyData2(scope, it) })
|
children = node.children.map { toDependencyData2(scope, it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun compileDependenciesGraph(project: Project, name: String): List<DependencyData> {
|
fun compileDependenciesGraph(project: Project, name: String): List<DependencyData> {
|
||||||
val depLambda = { dep : IClasspathDependency -> dep.directDependencies() }
|
val depLambda = IClasspathDependency::directDependencies
|
||||||
val result =
|
val result =
|
||||||
(DynamicGraph.Companion.transitiveClosureGraph(pluginDependencies, depLambda) +
|
(DynamicGraph.Companion.transitiveClosureGraph(pluginDependencies, depLambda) +
|
||||||
DynamicGraph.Companion.transitiveClosureGraph(project.compileDependencies, depLambda) +
|
DynamicGraph.Companion.transitiveClosureGraph(project.compileDependencies, depLambda) +
|
||||||
DynamicGraph.Companion.transitiveClosureGraph(project.compileProvidedDependencies, depLambda))
|
DynamicGraph.Companion.transitiveClosureGraph(project.compileProvidedDependencies, depLambda))
|
||||||
.map { toDependencyData2("compile", it)}
|
.map { toDependencyData2("compile", it)}
|
||||||
|
|
||||||
|
fun mapOfLatestVersions(l: List<DependencyData>) : Map<String, String> {
|
||||||
|
fun p(l: List<DependencyData>, latestVersions: HashMap<String, String>) {
|
||||||
|
l.forEach {
|
||||||
|
if (it.id.contains("squareup:okio")) {
|
||||||
|
println("DONOTCOMMIT")
|
||||||
|
}
|
||||||
|
val mid = MavenId.create(it.id)
|
||||||
|
val shortId = mid.artifactId + ":" + mid.artifactId
|
||||||
|
val currentLatest = latestVersions[shortId]
|
||||||
|
if (currentLatest == null) latestVersions[shortId] = mid.version!!
|
||||||
|
else mid.version?.let { v ->
|
||||||
|
if (Versions.toLongVersion(currentLatest) < Versions.toLongVersion(v)) {
|
||||||
|
latestVersions[shortId] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p(it.children, latestVersions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = hashMapOf<String, String>()
|
||||||
|
p(l, result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
val map = mapOfLatestVersions(result)
|
||||||
|
GraphUtil.map(result, { d: DependencyData -> d.children },
|
||||||
|
{d: DependencyData ->
|
||||||
|
val mid = MavenId.create(d.id)
|
||||||
|
val shortId = mid.artifactId + ":" + mid.artifactId
|
||||||
|
val version = map[shortId]
|
||||||
|
d.isLatest = version == mid.version
|
||||||
|
})
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,15 +157,13 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
||||||
//
|
//
|
||||||
log(2, "Returning dependencies:")
|
log(2, "Returning dependencies:")
|
||||||
|
|
||||||
fun displayDependencies(header: String, dd: List<DependencyData>) {
|
|
||||||
log(2, " $header:")
|
|
||||||
if (dd.any()) log(2, " " + dd.map { it.id }.toSortedSet().joinToString("\n "))
|
|
||||||
}
|
|
||||||
|
|
||||||
projectDatas.forEach {
|
projectDatas.forEach {
|
||||||
log(2, " Project: " + it.name)
|
log(2, " Project: " + it.name)
|
||||||
displayDependencies("compileDependencies", it.compileDependencies)
|
GraphUtil.displayGraph(it.compileDependencies,
|
||||||
displayDependencies("testDependencies", it.testDependencies)
|
{dd: DependencyData -> dd.children },
|
||||||
|
{dd: DependencyData, indent: String ->
|
||||||
|
println(indent + dd.id + " " + (if (! dd.isLatest) "(old)" else ""))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetDependenciesData(projectDatas, allTasks, projectResult.taskResult.errorMessage)
|
return GetDependenciesData(projectDatas, allTasks, projectResult.taskResult.errorMessage)
|
||||||
|
@ -142,8 +174,9 @@ class DependencyData @Inject constructor(val executors: KobaltExecutors, val dep
|
||||||
// use these same classes.
|
// use these same classes.
|
||||||
//
|
//
|
||||||
|
|
||||||
class DependencyData(val id: String, val scope: String, val path: String,
|
class DependencyData(val id: String, val scope: String, val path: String, var isLatest: Boolean = true,
|
||||||
val children: List<DependencyData> = emptyList())
|
val children: List<DependencyData> = emptyList())
|
||||||
|
|
||||||
data class TaskData(val name: String, val description: String, val group: String) {
|
data class TaskData(val name: String, val description: String, val group: String) {
|
||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
}
|
}
|
|
@ -72,17 +72,17 @@ class SparkServer(val initCallback: (String) -> List<Project>, val cleanUpCallba
|
||||||
val result =
|
val result =
|
||||||
if (buildFile != null) {
|
if (buildFile != null) {
|
||||||
try {
|
try {
|
||||||
val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
|
val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
|
||||||
val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
||||||
|
|
||||||
dependencyData.dependenciesDataFor(buildFile, args)
|
dependencyData.dependenciesDataFor(buildFile, args)
|
||||||
} catch(ex: Exception) {
|
} catch(ex: Exception) {
|
||||||
DependencyData.GetDependenciesData(errorMessage = ex.message)
|
RemoteDependencyData.GetDependenciesData(errorMessage = ex.message)
|
||||||
} finally {
|
} finally {
|
||||||
cleanUpCallback()
|
cleanUpCallback()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DependencyData.GetDependenciesData(
|
RemoteDependencyData.GetDependenciesData(
|
||||||
errorMessage = "buildFile wasn't passed in the query parameter")
|
errorMessage = "buildFile wasn't passed in the query parameter")
|
||||||
}
|
}
|
||||||
cleanUpCallback()
|
cleanUpCallback()
|
||||||
|
@ -143,7 +143,7 @@ class GetDependenciesHandler : WebSocketListener {
|
||||||
// Get the dependencies for the requested build file and send progress to the web
|
// Get the dependencies for the requested build file and send progress to the web
|
||||||
// socket for each project
|
// socket for each project
|
||||||
try {
|
try {
|
||||||
val dependencyData = getInstance(DependencyData::class.java)
|
val dependencyData = getInstance(RemoteDependencyData::class.java)
|
||||||
val args = getInstance(Args::class.java)
|
val args = getInstance(Args::class.java)
|
||||||
|
|
||||||
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
val allProjects = projectFinder.initForBuildFile(BuildFile(Paths.get(buildFile), buildFile),
|
||||||
|
@ -157,16 +157,16 @@ class GetDependenciesHandler : WebSocketListener {
|
||||||
} catch(ex: Throwable) {
|
} catch(ex: Throwable) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
val errorMessage = ex.stackTrace.map { it.toString() }.joinToString("\n<p>")
|
val errorMessage = ex.stackTrace.map { it.toString() }.joinToString("\n<p>")
|
||||||
DependencyData.GetDependenciesData(errorMessage = errorMessage)
|
RemoteDependencyData.GetDependenciesData(errorMessage = errorMessage)
|
||||||
} finally {
|
} finally {
|
||||||
SparkServer.cleanUpCallback()
|
SparkServer.cleanUpCallback()
|
||||||
eventBus.unregister(busListener)
|
eventBus.unregister(busListener)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DependencyData.GetDependenciesData(
|
RemoteDependencyData.GetDependenciesData(
|
||||||
errorMessage = "buildFile wasn't passed in the query parameter")
|
errorMessage = "buildFile wasn't passed in the query parameter")
|
||||||
}
|
}
|
||||||
sendWebsocketCommand(s.remote, DependencyData.GetDependenciesData.NAME, result)
|
sendWebsocketCommand(s.remote, RemoteDependencyData.GetDependenciesData.NAME, result)
|
||||||
s.close()
|
s.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//
|
//
|
||||||
// val projects = initCallback(buildFile)
|
// val projects = initCallback(buildFile)
|
||||||
// val result = try {
|
// val result = try {
|
||||||
// val dependencyData = Kobalt.INJECTOR.getInstance(DependencyData::class.java)
|
// val dependencyData = Kobalt.INJECTOR.getInstance(RemoteDependencyData::class.java)
|
||||||
// val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
// val args = Kobalt.INJECTOR.getInstance(Args::class.java)
|
||||||
//
|
//
|
||||||
// val dd = dependencyData.dependenciesDataFor(buildFile, args)
|
// val dd = dependencyData.dependenciesDataFor(buildFile, args)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue