The idea is to be able to add libraries to a project without actually modifying the code. This is mainly to be able to generate builds as per requirements. While I could achieve this with buildFlavors, I wanted the flexibility of being able to do this for any number of libraries.
Basically its something like this,
What I need is to add these libraries to the Base App and generate builds as per requirements.
For this, I created the following task. For the moment I am just trying with local modules already registered in settings.gradle
file, but not added to the project
val myArg: String by project
//use task in this way - gradlew addDependencyAndGenerateBuilds -PmyArg dependency name
tasks.register("addDependencyAndGenerateBuilds"){
doLast {
if(project.hasProperty("myArg")){
dependencies.implementation(dependencies.project(":$myArg"))
}
finalizedBy("clean", "build")
}
}
Now if I run this task - ./gradlew addDependencyAndGenerateBuilds -PmyArg libraryA
, I get the following error,
Task 'libraryA' not found in root project
What I need is for this libraryA
to be added to the base app and new builds generated accordingly.
Turns out there was an issue with run task command. There needs to be an =
between myArg
and libraryA
.
The full command is like this,
./gradlew addDependencyAndGenerateBuilds -PmyArg=libraryA
While this fixed the issue mentioned (i.e. Task libraryA not found..), it failed to build with some errors.
I then scrapped the whole idea and just added an extension method in the app gradle.
fun DependencyHandlerScope.addExtension(extensionsFilePath: String) {
val extensionsFile = File("${project.rootDir}", extensionsFilePath)
if (extensionsFile.exists()) {
val extensions = extensionsFile.readBytes().decodeToString()
val extensionsJson = Gson().fromJson(extensions, JsonObject::class.java)
if (extensionsJson.has("modules")) {
println("Adding module dependencies")
extensionsJson.getAsJsonArray("modules").forEach {
implementation(project(it.asString))
}
}
}
}
This is used in the dependencies block like this,
dependencies {
........
........
addExtension("extensions.json")
}
This method takes in a Json file containing a list of dependencies and then just adds them to the project. All one had to do is then edit this json file before generating a build.
To further simplify this, I just added a task that edits the json file,
val myArg: String by project
tasks.register("addNewExtension") {
doLast {
val extensionsFile = File(
"${project.rootDir}",
"extensions.json"
)
val extensionsJson = if (extensionsFile.exists()) {
val extensionsData = extensionsFile.readBytes().decodeToString()
Gson().fromJson(extensionsData, JsonObject::class.java)
} else {
JsonObject()
}
if (project.hasProperty("myArg")) {
val modules = extensionsJson.getAsJsonArray("modules") ?: JsonArray()
if (!modules.contains(JsonPrimitive(":$myArg"))) {
modules.add(":$myArg")
}
extensionsJson.add("modules", modules)
}
extensionsFile.delete()
extensionsFile.createNewFile()
extensionsFile.writeBytes(extensionsJson.toString().toByteArray())
}
}
You could then run - ./gradlew addNewExtension -PmyArg=libraryA
, followed by a ./gradlew build
.
This will then update the json, and then generate a new build with the library included.