0

I'd like to separate the dependencies in my project by type, and am considering doing so in the following way:

// Implementation dependencies
dependencies {
    implementation("foo:bar:1") {
        because("reason 1")
    }

    implementation("foo:bar:2") {
        because("reason 2")
    }

    implementation("foo:bar:3") {
        because("reason 3")
    }
}

// Test implementation dependencies
dependencies {
    testImplementation("foo:bar:4") {
        because("reason 4")
    }

    testImplementation("foo:bar:5") {
        because("reason 5")
    }
}

Questions:

  1. I am able to build the project after structuring the build file in this way, but I don't see any authoritative material stating that specifying multiple dependencies blocks is formally supported. Does such material exist?

  2. Is there a more preferable way of separating dependencies by type than this? Preferably, I'd like to have a dependency-configuration (implementation, testImplementation, etc.) per module in order to document the reason for including each module, like the configuration above does.

Kevin
  • 2,617
  • 29
  • 35

2 Answers2

3

I don't see any authoritative material stating that specifying multiple dependencies blocks is formally supported. Does such material exist?

There doesn't need to be any material because the Gradle DSL (Groovy or Kotlin) isn't anything special or magical. It's simply sugar over the Gradle API.

Specifying multiple dependencies block is perfectly legal. If you were to de-sugar the Gradle DSL, invoking multiple dependencies blocks is actually just doing:

project.getDependencies().add("implementation", "foo:bar:1")
project.getDependencies().add("testImplementation", "foo:bar:4")

It's no different than simply calling the add(...) method on a List multiple times.

Is there a more preferable way of separating dependencies by type than this?

Create a library (project or subproject) that bundles dependencies together. This is easily accomplished with the Java Library Plugin. For example, for your test library:

dependencies {
    api("foo:bar:4") {
        because("reason 4")
    }
    api("foo:bar:5") {
        because("reason 5")
    }
}

Then simply consume the library in your main project:

dependencies {
    testImplementation(project(":my-test-library")) {
        because("bundles test libs")
    }
}
Cisco
  • 20,972
  • 5
  • 38
  • 60
0

There is no such support and I don't think is there is need also, but to achieve your requirements we can create an extension function just to differentiate the different dependencies. Anyway many Kotlin DSL is extension functions only so add something like below. just declare this in your buildSrc Dependencies.kts file or anywhere you like but should be accessible global.

// test
    fun Project.dependenciesTest(configuration: DependencyHandlerScope.() -> Unit) =
        DependencyHandlerScope.of(dependencies).configuration()

//app
    fun Project.dependenciesApp(configuration: DependencyHandlerScope.() -> Unit) =
        DependencyHandlerScope.of(dependencies).configuration()

now call something like this in the calling site.

dependenciesApp {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

dependenciesTest {
    testImplementation(AppDependencies.junit)
}
vikas kumar
  • 10,447
  • 2
  • 46
  • 52