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

Fix optional dependencies problem.

This commit is contained in:
Cedric Beust 2017-02-01 12:58:59 -08:00
parent 38bb53387e
commit ae450e4cbc
15 changed files with 323 additions and 127 deletions

View file

@ -6,9 +6,11 @@ import com.beust.kobalt.TestModule
import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.app.BuildFileCompiler
import com.beust.kobalt.maven.aether.Filters
import com.beust.kobalt.maven.aether.Scope
import com.google.inject.Inject
import org.assertj.core.api.Assertions.assertThat
import org.eclipse.aether.util.filter.AndDependencyFilter
import org.testng.annotations.Guice
import org.testng.annotations.Test
@ -19,7 +21,17 @@ class DependencyManagerTest @Inject constructor(val dependencyManager: Dependenc
private fun assertContains(dependencies: List<IClasspathDependency>, vararg ids: String) {
ids.forEach { id ->
assertThat(dependencies.any { it.id.contains(id) }).isTrue()
if (! dependencies.any { it.id.contains(id) }) {
throw AssertionError("Couldn't find $id in $dependencies")
}
}
}
private fun assertDoesNotContain(dependencies: List<IClasspathDependency>, vararg ids: String) {
ids.forEach { id ->
if (dependencies.any { it.id.contains(id) }) {
throw AssertionError("$id should not be found in $dependencies")
}
}
}
@ -27,87 +39,118 @@ class DependencyManagerTest @Inject constructor(val dependencyManager: Dependenc
fun testScopeDependenciesShouldBeDownloaded() {
val testDeps = listOf(dependencyManager.create("org.testng:testng:6.9.11"))
val filter = AndDependencyFilter(Filters.EXCLUDE_OPTIONAL_FILTER, Filters.COMPILE_FILTER)
// Should only resolve to TestNG
dependencyManager.transitiveClosure(testDeps, listOf(Scope.COMPILE)).let { dependencies ->
dependencyManager.transitiveClosure(testDeps, filter).let { dependencies ->
assertThat(dependencies.any { it.id.contains(":jcommander:") }).isFalse()
assertContains(dependencies, ":testng:")
}
// Should resolve to TestNG and its dependencies
dependencyManager.transitiveClosure(testDeps, listOf(Scope.TEST)).let { dependencies ->
dependencyManager.transitiveClosure(testDeps).let { dependencies ->
assertContains(dependencies, ":jcommander:")
assertContains(dependencies, ":bsh:")
assertContains(dependencies, ":ant:")
assertContains(dependencies, ":ant-launcher:")
assertContains(dependencies, ":testng:")
}
}
@Test
fun honorRuntimeDependenciesBetweenProjects() {
Kobalt.context = null
val buildFileString = """
import com.beust.kobalt.*
val lib = project {
name = "lib"
val lib1 = project {
name = "lib1"
dependencies {
compile("org.testng:testng:6.9.11")
runtime("com.beust:jcommander:1.48")
compile("com.beust:klaxon:0.26",
"com.beust:jcommander:1.48")
}
}
val p = project(lib) {
name = "transitive"
val p = project(lib1) {
name = "transitive1"
}
"""
val compileResult = compileBuildFile(buildFileString, Args(), compilerFactory)
val compileResult = compileBuildFile(sharedBuildFile, Args(), compilerFactory)
val project2 = compileResult.projects[1]
val dependencies = dependencyManager.calculateDependencies(project2, Kobalt.context!!,
listOf(Scope.COMPILE, Scope.RUNTIME))
assertContains(dependencies, ":testng:")
assertContains(dependencies, ":jcommander:")
val dependencies = dependencyManager.calculateDependencies(project2, Kobalt.context!!, Filters.COMPILE_FILTER)
assertContains(dependencies, ":klaxon:")
assertContains(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":guave:")
}
val sharedBuildFile = """
import com.beust.kobalt.*
val lib2 = project {
name = "lib2"
dependencies {
// pick dependencies that don't have dependencies themselves, to avoid interferences
compile("com.beust:klaxon:0.27",
"com.google.inject:guice:4.0")
runtime("com.beust:jcommander:1.48")
compileOptional("junit:junit:4.12")
}
}
val p = project(lib2) {
name = "transitive2"
}
"""
@Test
fun honorRuntimeDependenciesBetweenProjects2() {
val buildFileString = """
import com.beust.kobalt.*
val lib = project {
name = "lib"
val lib2 = project {
name = "lib2"
dependencies {
compile("org.testng:testng:6.9.11")
// pick dependencies that don't have dependencies themselves, to avoid interferences
compile("com.beust:klaxon:0.27",
"com.google.inject:guice:4.0)
runtime("com.beust:jcommander:1.48")
}
}
val p = project(lib) {
name = "transitive"
val p = project(lib2) {
name = "transitive2"
}
"""
val compileResult = compileBuildFile(buildFileString, Args(), compilerFactory)
val compileResult = compileBuildFile(sharedBuildFile, Args(), compilerFactory)
val project2 = compileResult.projects[1]
dependencyManager2.resolve(project2, Kobalt.context!!, isTest = false,
passedScopeFilters = listOf(Scope.COMPILE, Scope.RUNTIME)).let { dependencies ->
assertThat(dependencies.size).isEqualTo(4)
assertContains(dependencies, ":testng:")
assertContains(dependencies, ":jcommander:")
}
Kobalt.context!!.let { context ->
dependencyManager2.resolve(project2, context, isTest = false,
passedScopes = listOf(Scope.COMPILE)).let { dependencies ->
assertContains(dependencies, ":klaxon:jar:0.27")
assertContains(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":jcommander:")
assertDoesNotContain(dependencies, ":junit:")
}
dependencyManager2.resolve(project2, Kobalt.context!!, isTest = false,
passedScopeFilters = listOf(Scope.COMPILE)).let { dependencies ->
assertThat(dependencies.size).isEqualTo(3)
assertContains(dependencies, ":testng:")
}
dependencyManager2.resolve(project2, context, isTest = false,
passedScopes = listOf(Scope.RUNTIME)).let { dependencies ->
assertContains(dependencies, ":jcommander:")
assertDoesNotContain(dependencies, ":klaxon:jar:0.27")
assertDoesNotContain(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":junit:")
}
dependencyManager2.resolve(project2, context, isTest = false,
passedScopes = listOf(Scope.COMPILE, Scope.RUNTIME)).let { dependencies ->
assertContains(dependencies, ":klaxon:")
assertContains(dependencies, ":jcommander:")
assertContains(dependencies, ":guice:")
assertDoesNotContain(dependencies, ":junit:")
}
dependencyManager2.resolve(project2, Kobalt.context!!, isTest = false,
passedScopeFilters = listOf(Scope.RUNTIME)).let { dependencies ->
assertThat(dependencies.size).isEqualTo(3)
assertContains(dependencies, ":jcommander:")
}
}

View file

@ -147,7 +147,7 @@ class DownloadTest @Inject constructor(
@Test
fun parentPomTest() {
// Resolve com.squareup.retrofit2:converter-moshi:2.0.0
// Resolve com.squareup.retrofit2:converter-moshi:1.1.0
// This id has a parent pom which defines moshi version to be 1.1.0. Make sure that this
// version is being fetched instead of moshi:1.2.0-SNAPSHOT (which gets discarded anyway
// since snapshots are not allowed to be returned when looking up a versionless id)

View file

@ -0,0 +1,55 @@
package com.beust.kobalt.misc
import com.beust.kobalt.TestModule
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.aether.Booter
import com.beust.kobalt.maven.aether.KobaltAether
import com.google.inject.Inject
import org.assertj.core.api.Assertions.assertThat
import org.eclipse.aether.artifact.DefaultArtifact
import org.eclipse.aether.collection.CollectRequest
import org.eclipse.aether.graph.Dependency
import org.eclipse.aether.repository.RemoteRepository
import org.eclipse.aether.resolution.DependencyRequest
import org.eclipse.aether.util.artifact.JavaScopes
import org.testng.annotations.Guice
import org.testng.annotations.Test
@Guice(modules = arrayOf(TestModule::class))
class AetherTest {
@Inject
lateinit var kobaltAether: KobaltAether
@Inject
lateinit var dependencyManager: DependencyManager
@Test
fun aetherShouldNotIncludeOptionalDependencies() {
val system = Booter.newRepositorySystem()
val session = Booter.newRepositorySystemSession(system)
val artifact = DefaultArtifact("com.squareup.retrofit2:converter-jackson:jar:2.1.0")
val collectRequest = CollectRequest().apply {
root = Dependency(artifact, JavaScopes.COMPILE)
repositories = listOf(
RemoteRepository.Builder("Maven", "default", "http://repo1.maven.org/maven2/").build()
)
}
val dependencyRequest = DependencyRequest(collectRequest, null)
val artifactResults = system.resolveDependencies(session, dependencyRequest).artifactResults
// Make sure that com.google.android is not included (it's an optional dependency of retrofit2)
assertThat(artifactResults.none { it.toString().contains("android") })
}
@Test
fun kobaltAetherShouldNotIncludeOptionalDependencies() {
val dep = kobaltAether.create("com.squareup.retrofit2:converter-jackson:jar:2.1.0", optional = false)
val closure = dependencyManager.transitiveClosure(listOf(dep))
// Make sure that com.google.android is not included (it's an optional dependency of retrofit2)
assertThat(closure.none { it.toString().contains("android") })
}
}