If you're working on an Android project with multiple modules, you're probably familiar with the default build.gradle(.kts) file name for new modules. If you open the Now In Android project and search for build.gradle.kts
, every module inside of the project will appear. This can often be a confusing situation to be in because you then have to start to fuzzy search to get the exact build file you want. The problem also compounds as your project grows in size.
However, what if you want to use a different name for the build.gradle.kts
file, such as the name of the module? In this post, we'll show you how to write a custom Gradle function inside your settings.gradle.kts
that allows you to do just that.
To get started, you'll need to create a new Gradle function inside settings.gradle.kts
. Here is the function we will be adding:
fun includeModule(name: String) {
settings.include(name)
// `configureModuleWithProject` is yet to be defined
configureModuleWithProject(name, project(name))
}
This function takes in one parameter, the name of the module. Using the Now In Android project as a reference again, there are two modules we will be focusing on: :feature:interests
and :feature:topic
With our new function, we can include these modules inside of our settings.gradle.kts
via:
includeModule(":feature:topic")
includeModule(":feature:interests")
Now, onwards to define the crux of our custom function, configureFileWithProject
. This method will offer a lot of flexibility to fit within a multitude of Android projects, so the first thing we will want to do is break up the module name into its subsequent parts (which we're defining as logical modules/folders). We are doing this because we ultimately want to support multiple levels of nesting within our module structure. So for example, if we have :features:home:feed
as a module name, we want to support naming the build files within this module either features-feed.gradle.kts
or home-feed.gradle.kts
(or just feed.gradle.kts
) while still supporting leaving the file as build.gradle.kts
too.
We then need to check for each of the supported file names existing. From our earlier example of :features:home:feed
, we will need to:
check if
feed.gradle.kts
existsIf not, check if
home-feed.gradle.kts
existsIf not, check if
features-feed.gradle.kts
exists
With all of that being said, here is the implementation of configureModuleWithProject
:
fun configureModuleWithProject(
moduleName: String,
projectDescriptor: ProjectDescriptor,
) {
projectDescriptor.apply {
val name = moduleName.substringAfterLast(":")
/**
* Breakup the module name into its logical parts
*/
val thirdToLastModuleIndex = lastOrdinalIndexOf(moduleName, ':', 3)
val secondToLastModuleIndex = lastOrdinalIndexOf(moduleName, ':', 2)
val lastModuleIndex = lastOrdinalIndexOf(moduleName, ':', 1)
val directParentModule = moduleName.substring(secondToLastModuleIndex, lastModuleIndex).trim(':')
val thirdLevelParentModule = moduleName.substring(thirdToLastModuleIndex, lastModuleIndex).trim(':').replace(":","-")
// in the example :features:home:feed - check for just `feed.gradle.kts` first
buildFileName = "$name.gradle.kts"
if (!buildFile.exists()) {
// if that does not exist, check for `home-feed.gradle.kts`
buildFileName = "$directParentModule-$name.gradle.kts"
}
if (!buildFile.exists()) {
// if that does not exist, check for `features-feed.gradle.kts`
buildFileName = "$thirdLevelParentModule-$name.gradle.kts"
}
if (!buildFile.exists()) {
// if that does not exist, check for the default `build.gradle.kts`
buildFileName = "build.gradle.kts"
}
if (!buildFile.exists()) {
// if none of the above exist, throw an exception
throw GradleException("Build file: build.gradle, $name.gradle.kts, $directParentModule-$name.gradle.kts, or $thirdLevelParentModule-$name.gradle.kts does not exist. Cannot include module: $name")
}
}
}
Results
After adding our custom function to the Now In Android project, we can now see that the modules :features:interests
and :feature:topic
have its build file named interests.gradle.kts
and :feature-topic.gradle.kts
, which is less confusing to maintain in the long run.
In summary, if you want to use a different name for your build.gradle(.kts) files in your Android project, you can create a custom Gradle function that allows you to do just that.