Pack a multi-module Gradle library into a single module
Asked Answered
S

2

7

I've split my pancakes Gradle-based library written in Kotlin into multiple modules: pancakes-core, pancakes-addon1, ..., pancakes-addonN. The addon ones include the core one.

Now, most users shouldn't care and will just want the default configuration with all the dependencies included. But they will have to write boilerplate:

dependencies {
    implementation("pancakes:pancakes-core")
    implementation("pancakes:pancakes-addon1")
    ...
    implementation("pancakes:pancakes-addonN")
}

This is a no-go for me. I'll probably have to merge all the modules, although I've just spent some time to branch off some replaceable features into their own modules.

Unless! There is a way to write something like the following:

project(":pancakes-simple") {
    dependencies {
        autoForwardedApi(":pancakes-core")
        autoForwardedApi(":pancakes-addon1")
        ...
        autoForwardedApi(":pancakes-addonN")
    }
}

Unfortunately, api is not enough.

Sedgewake answered 19/12, 2018 at 9:18 Comment(1)
In what way is it not enough?Lindesnes
S
2

java-library Gradle plugin is required for api dependencies to be forwarded from the current module. So that's how to pack all the modules into a single one:

  1. Add java-library plugin (and remove java) in all modules of the library
  2. Create a module like my :pancakes-simple that api-depends on all the other modules
Sedgewake answered 20/12, 2018 at 17:33 Comment(1)
Hello @Sedgewake , I followed your suggestion and you were right, I achieved to combine 3 of my modules and publish the combined module, to my Mavenlocal repo as one. But as I saw (correct me if I am wrong), I have to install (publish) to my MavenLocal repo (in my case) all other 3 modules in order to be able to use the combined one, successfully as a dependency in another project.Filigree
A
1

Yes it's possible and close to what you supposed it to look like.

Add a separate subproject, say, :pancakes-simple and configure its publishing as you did for your normal modules.

Then just add the dependencies that you want it to expose. If you are not using the java-library plugin, use the compile configuration:

project(":pancakes-simple") {
    dependencies {
        compile(":pancakes-core")
        compile(":pancakes-addon1")
        ...
        compile(":pancakes-addonN")
    }
}

Unlike implementation dependencies, these will be available on the consumer's compile classpath if they add a dependency on the pancakes-simple module.

With the java-library plugin, api dependencies should also work

Albrecht answered 19/12, 2018 at 10:36 Comment(2)
Use api instead of compile since compile is deprecated.Hodosh
So I should use replace java plugin with java-library, and everything will work with api?Sedgewake

© 2022 - 2024 — McMap. All rights reserved.