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

Delete DependencyManager2.

This commit is contained in:
Cedric Beust 2017-02-02 11:18:36 -08:00
parent 6a5eb20d02
commit a66974c5cb
5 changed files with 28 additions and 230 deletions

View file

@ -3,7 +3,6 @@ package com.beust.kobalt.internal
import com.beust.kobalt.TaskResult import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.DependencyManager2
import com.beust.kobalt.maven.aether.Scope import com.beust.kobalt.maven.aether.Scope
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
@ -15,9 +14,7 @@ import java.util.*
/** /**
* Central place to compile files, used by plug-ins and non plug-ins. * Central place to compile files, used by plug-ins and non plug-ins.
*/ */
class CompilerUtils @Inject constructor(val files: KFiles, class CompilerUtils @Inject constructor(val files: KFiles, val dependencyManager: DependencyManager) {
val dependencyManager: DependencyManager,
val dependencyManager2: DependencyManager2) {
class CompilerResult(val successResults: List<TaskResult>, val failedResult: TaskResult?) class CompilerResult(val successResults: List<TaskResult>, val failedResult: TaskResult?)
@ -72,17 +69,8 @@ class CompilerUtils @Inject constructor(val files: KFiles,
: CompilerActionInfo { : CompilerActionInfo {
copyResources(project, context, SourceSet.of(isTest)) copyResources(project, context, SourceSet.of(isTest))
val fullClasspath = dependencyManager2.resolve(project, context, isTest, listOf(Scope.COMPILE, Scope.TEST)) val fullClasspath = dependencyManager.calculateDependencies(project, context,
scopes = listOf(Scope.COMPILE, Scope.TEST))
// if (project.name == "ktor-core" && isTest) {
// val contains = fullClasspath.filter{it.id.contains("json")}
// val fc1 =
// if (isTest) dependencyManager.testDependencies(project, context)
// else dependencyManager.dependencies(project, context)
//
// println("DONOTCOMMIT")
// val d2 = dependencyManager2.resolve(project, context, isTest, listOf(Scope.COMPILE, Scope.TEST))
// }
File(project.directory, buildDirectory.path).mkdirs() File(project.directory, buildDirectory.path).mkdirs()

View file

@ -9,9 +9,9 @@ import com.beust.kobalt.api.annotation.ExportedProjectProperty
import com.beust.kobalt.api.annotation.IncrementalTask import com.beust.kobalt.api.annotation.IncrementalTask
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.DependencyManager2
import com.beust.kobalt.maven.LocalRepo import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.maven.Md5 import com.beust.kobalt.maven.Md5
import com.beust.kobalt.maven.aether.Scope
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.error import com.beust.kobalt.misc.error
@ -30,7 +30,6 @@ open class JvmCompilerPlugin @Inject constructor(
open val localRepo: LocalRepo, open val localRepo: LocalRepo,
open val files: KFiles, open val files: KFiles,
open val dependencyManager: DependencyManager, open val dependencyManager: DependencyManager,
open val dependencyManager2: DependencyManager2,
open val executors: KobaltExecutors, open val executors: KobaltExecutors,
open val taskContributor : TaskContributor, open val taskContributor : TaskContributor,
val compilerUtils: CompilerUtils) val compilerUtils: CompilerUtils)
@ -88,9 +87,12 @@ open class JvmCompilerPlugin @Inject constructor(
context.pluginInfo.testRunnerContributors) context.pluginInfo.testRunnerContributors)
if (testContributor != null && testContributor.affinity(project, context) > 0) { if (testContributor != null && testContributor.affinity(project, context) > 0) {
// val td1 = dependencyManager.testDependencies(project, context) // val td1 = dependencyManager.testDependencies(project, context)
val testDependencies = dependencyManager2.resolve(project, context, isTest = true) val testDependencies = dependencyManager.calculateDependencies(project, context,
val compileDependencies = dependencyManager2.resolve(project, context, isTest = false) scopes = listOf(Scope.TEST))
return testContributor.run(project, context, configName, testDependencies + compileDependencies) val compileDependencies = dependencyManager.calculateDependencies(project, context,
scopes = listOf(Scope.COMPILE))
val allDependencies = (compileDependencies + testDependencies).toHashSet()
return testContributor.run(project, context, configName, allDependencies.toList())
} else { } else {
context.logger.log(project.name, 2, context.logger.log(project.name, 2,
"Couldn't find a test runner for project ${project.name}, did you specify dependenciesTest{}?") "Couldn't find a test runner for project ${project.name}, did you specify dependenciesTest{}?")

View file

@ -115,18 +115,25 @@ class DependencyManager @Inject constructor(val executors: KobaltExecutors, val
addAll(project.testDependencies) addAll(project.testDependencies)
} }
} }
return result return result.filter { ! it.optional }
} }
val allDependencies : Array<out List<IClasspathDependency>> = val allDependencies : Array<out List<IClasspathDependency>> =
if (project == null || passedDependencies.any()) passedDependencies if (project == null || passedDependencies.any()) passedDependencies
else arrayOf(filtersToDependencies(project, scopes)) else arrayOf(filtersToDependencies(project, scopes))
// Make sure that classes/ and test-classes/ are always at the top of this classpath,
// so that older versions of that project on the classpath don't shadow them
if (project != null && scopes.contains(Scope.TEST)) {
result.add(FileDependency(KFiles.makeOutputDir(project).path))
result.add(FileDependency(KFiles.makeOutputTestDir(project).path))
}
allDependencies.forEach { dependencies -> allDependencies.forEach { dependencies ->
result.addAll(transitiveClosure(dependencies, dependencyFilter, project?.name)) result.addAll(transitiveClosure(dependencies, dependencyFilter, project?.name))
} }
result.addAll(runClasspathContributors(project, context)) result.addAll(runClasspathContributors(project, context))
result.addAll(dependentProjectDependencies(project, context, dependencyFilter, scopes.contains(Scope.TEST))) result.addAll(dependentProjectDependencies(project, context, dependencyFilter, scopes))
// Dependencies get reordered by transitiveClosure() but since we just added a bunch of new ones, // Dependencies get reordered by transitiveClosure() but since we just added a bunch of new ones,
// we need to reorder them again in case we're adding dependencies that are already present // we need to reorder them again in case we're adding dependencies that are already present
@ -188,7 +195,7 @@ class DependencyManager @Inject constructor(val executors: KobaltExecutors, val
* their own dependencies * their own dependencies
*/ */
private fun dependentProjectDependencies(project: Project?, context: KobaltContext, private fun dependentProjectDependencies(project: Project?, context: KobaltContext,
dependencyFilter: DependencyFilter, isTest: Boolean): List<IClasspathDependency> { dependencyFilter: DependencyFilter, scopes: List<Scope>): List<IClasspathDependency> {
if (project == null) { if (project == null) {
return emptyList() return emptyList()
} else { } else {
@ -204,8 +211,9 @@ class DependencyManager @Inject constructor(val executors: KobaltExecutors, val
project.dependsOn.forEach { p -> project.dependsOn.forEach { p ->
maybeAddClassDir(KFiles.joinDir(p.directory, p.classesDir(context))) maybeAddClassDir(KFiles.joinDir(p.directory, p.classesDir(context)))
val isTest = scopes.contains(Scope.TEST)
if (isTest) maybeAddClassDir(KFiles.makeOutputTestDir(project).path) if (isTest) maybeAddClassDir(KFiles.makeOutputTestDir(project).path)
val otherDependencies = calculateDependencies(p, context, dependencyFilter, Scope.toScopes(isTest)) val otherDependencies = calculateDependencies(p, context, dependencyFilter, scopes)
result.addAll(otherDependencies) result.addAll(otherDependencies)
} }

View file

@ -1,199 +0,0 @@
package com.beust.kobalt.maven
import com.beust.kobalt.KobaltException
import com.beust.kobalt.api.*
import com.beust.kobalt.internal.DynamicGraph
import com.beust.kobalt.maven.aether.KobaltAether
import com.beust.kobalt.maven.aether.Scope
import com.beust.kobalt.maven.dependency.FileDependency
import com.beust.kobalt.misc.KFiles
import com.google.common.collect.ArrayListMultimap
import com.google.inject.Inject
import org.eclipse.aether.graph.DependencyFilter
import java.io.File
import java.util.*
class DependencyManager2 @Inject constructor(val aether: KobaltAether) {
/**
* Create an IClasspathDependency from a Maven id.
*/
fun createMaven(id: String, optional: Boolean) : IClasspathDependency = aether.create(id, optional)
/**
* Create an IClasspathDependency from a path.
*/
fun createFile(path: String) : IClasspathDependency = FileDependency(path)
/**
* Parse the id and return the correct IClasspathDependency
*/
fun create(id: String, optional: Boolean, projectDirectory: String?) : IClasspathDependency {
if (id.startsWith(FileDependency.PREFIX_FILE)) {
val path = if (projectDirectory != null) {
val idPath = id.substring(FileDependency.PREFIX_FILE.length)
if (! File(idPath).isAbsolute) {
// If the project directory is relative, we might not be in the correct directory to locate
// that file, so we'll use the absolute directory deduced from the build file path. Pick
// the first one that produces an actual file
val result = listOf(File(projectDirectory), Kobalt.context?.internalContext?.absoluteDir).map {
File(it, idPath)
}.firstOrNull {
it.exists()
}
result ?: throw KobaltException("Couldn't find $id")
} else {
File(idPath)
}
} else {
File(id.substring(FileDependency.PREFIX_FILE.length))
}
return createFile(path.path)
} else {
// Convert to a Kobalt id first (so that if it doesn't have a version, it gets translated to
// an Aether ranged id "[0,)")
return createMaven(MavenId.create(id).toId, optional)
}
}
/**
* Resolve the dependencies for the give project based on the scope filters.
*/
fun resolve(project: Project, context: KobaltContext, isTest: Boolean,
passedScopes : List<Scope> = emptyList(),
passedIds: List<IClasspathDependency> = emptyList()): List<IClasspathDependency> {
val result = hashSetOf<IClasspathDependency>()
val nonMavenDependencies = hashSetOf<IClasspathDependency>()
val actualScopes =
if (passedScopes.isEmpty())
if (isTest) listOf(Scope.TEST, Scope.COMPILE)
else listOf(Scope.COMPILE)
else passedScopes
val toDependencies = Scope.toDependencyLambda(actualScopes)
// Make sure that classes/ and test-classes/ are always at the top of this classpath,
// so that older versions of that project on the classpath don't shadow them
if (isTest) {
result.add(FileDependency(KFiles.makeOutputDir(project).path))
result.add(FileDependency(KFiles.makeOutputTestDir(project).path))
}
// Passed and direct ids
val ids = hashSetOf<IClasspathDependency>().apply {
addAll(passedIds)
addAll(toDependencies(project).filter { ! it.optional })
}
// Contributed id's
val contributedIds = runClasspathContributors(project, context)
contributedIds.forEach {
if (it.isMaven) ids.add(it)
else nonMavenDependencies.add(it)
}
// Dependent project id's
val dependentIds = dependentProjectDependencies(project, context, toDependencies)
dependentIds.forEach {
if (it.isMaven) ids.add(it)
else nonMavenDependencies.add(it)
}
//
// Now we have all the id's, resolve them
//
var i = 0
ids.forEach {
if (it.isMaven) {
result.add(it)
val resolved = aether.resolveAll(it.id, dependencyFilter = scopesToDependencyFilter(actualScopes))
.map { create(it, false, project.directory) }
i++
result.addAll(resolved)
} else {
result.add(it)
}
}
result.addAll(nonMavenDependencies)
return reorderDependencies(result)
}
private fun scopesToDependencyFilter(scopes: List<Scope>, includeOptional: Boolean = false): DependencyFilter {
return DependencyFilter { p0, p1 ->
if (p0.dependency.optional && ! includeOptional) return@DependencyFilter false
val result = scopes.any {
p0.dependency.scope == "" && scopes.contains(Scope.COMPILE) ||
p0.dependency.scope == it.scope
}
result
}
}
/**
* Reorder dependencies so that if an artifact appears several times, only the one with the higest version
* is included.
*/
private fun reorderDependencies(dependencies: Collection<IClasspathDependency>): List<IClasspathDependency> {
val result = arrayListOf<IClasspathDependency>()
val map : ArrayListMultimap<String, IClasspathDependency> = ArrayListMultimap.create()
// The multilist maps each artifact to a list of all the versions found
// (e.g. {org.testng:testng -> (6.9.5, 6.9.4, 6.1.1)}), then we return just the first one
dependencies.forEach {
map.put(it.shortId, it)
}
for (k in map.keySet()) {
val l = map.get(k)
Collections.sort(l, Collections.reverseOrder())
result.add(l[0])
}
return result
}
private fun runClasspathContributors(project: Project?, context: KobaltContext) :
Set<IClasspathDependency> {
val result = hashSetOf<IClasspathDependency>()
context.pluginInfo.classpathContributors.forEach { it: IClasspathContributor ->
result.addAll(it.classpathEntriesFor(project, context))
}
return result
}
/**
* If this project depends on other projects, we need to include their jar file and also
* their own dependencies
*/
private fun dependentProjectDependencies(project: Project?, context: KobaltContext,
toDependencies: (Project) -> List<IClasspathDependency>)
: List<IClasspathDependency> {
// Get the transitive closure of all the projects this project depends on
val transitiveProjects =
if (project == null) emptyList()
else DynamicGraph.transitiveClosure(project, Project::dependsOn)
val result = arrayListOf<IClasspathDependency>()
/**
* Add the class directories of projects depended upon
*/
fun maybeAddClassDir(classDir: String) {
// A project is allowed not to have any kobaltBuild/classes or test-classes directory if it doesn't have
// any sources
if (File(classDir).exists()) {
result.add(FileDependency(classDir))
}
}
transitiveProjects.filter { it.name != project?.name }.forEach { p ->
maybeAddClassDir(KFiles.joinDir(p.directory, p.classesDir(context)))
maybeAddClassDir(KFiles.makeOutputTestDir(p).path)
}
// And add all the transitive projects
result.addAll(transitiveProjects.flatMap { toDependencies(it) })
return result
}
}

View file

@ -16,7 +16,6 @@ import org.testng.annotations.Test
@Guice(modules = arrayOf(TestModule::class)) @Guice(modules = arrayOf(TestModule::class))
class DependencyManagerTest @Inject constructor(val dependencyManager: DependencyManager, class DependencyManagerTest @Inject constructor(val dependencyManager: DependencyManager,
val dependencyManager2: DependencyManager2,
val compilerFactory: BuildFileCompiler.IFactory) : BaseTest() { val compilerFactory: BuildFileCompiler.IFactory) : BaseTest() {
private fun assertContains(dependencies: List<IClasspathDependency>, vararg ids: String) { private fun assertContains(dependencies: List<IClasspathDependency>, vararg ids: String) {
@ -127,24 +126,24 @@ class DependencyManagerTest @Inject constructor(val dependencyManager: Dependenc
val project2 = compileResult.projects[1] val project2 = compileResult.projects[1]
Kobalt.context!!.let { context -> Kobalt.context!!.let { context ->
dependencyManager2.resolve(project2, context, isTest = false, dependencyManager.calculateDependencies(project2, context,
passedScopes = listOf(Scope.COMPILE)).let { dependencies -> scopes = listOf(Scope.COMPILE)).let { dependencies ->
assertContains(dependencies, ":klaxon:jar:0.27") assertContains(dependencies, ":klaxon:jar:0.27")
assertContains(dependencies, ":guice:") assertContains(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":jcommander:") assertDoesNotContain(dependencies, ":jcommander:")
assertDoesNotContain(dependencies, ":junit:") assertDoesNotContain(dependencies, ":junit:")
} }
dependencyManager2.resolve(project2, context, isTest = false, dependencyManager.calculateDependencies(project2, context,
passedScopes = listOf(Scope.RUNTIME)).let { dependencies -> scopes = listOf(Scope.RUNTIME)).let { dependencies ->
assertContains(dependencies, ":jcommander:") assertContains(dependencies, ":jcommander:")
assertDoesNotContain(dependencies, ":klaxon:jar:0.27") assertDoesNotContain(dependencies, ":klaxon:jar:0.27")
assertDoesNotContain(dependencies, ":guice:") assertDoesNotContain(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":junit:") assertDoesNotContain(dependencies, ":junit:")
} }
dependencyManager2.resolve(project2, context, isTest = false, dependencyManager.calculateDependencies(project2, context,
passedScopes = listOf(Scope.COMPILE, Scope.RUNTIME)).let { dependencies -> scopes = listOf(Scope.COMPILE, Scope.RUNTIME)).let { dependencies ->
assertContains(dependencies, ":klaxon:") assertContains(dependencies, ":klaxon:")
assertContains(dependencies, ":jcommander:") assertContains(dependencies, ":jcommander:")
assertContains(dependencies, ":guice:") assertContains(dependencies, ":guice:")