1
0
Fork 0
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:
Cedric Beust 2017-02-01 20:47:00 -08:00
parent 2ebf932d21
commit 50b1ded7bb
10 changed files with 101 additions and 33 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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