Skip to content

Instantly share code, notes, and snippets.

@Tapchicoma
Last active March 27, 2019 15:47
Show Gist options
  • Save Tapchicoma/6710098d1e55767fbc35467727ba0e67 to your computer and use it in GitHub Desktop.
Save Tapchicoma/6710098d1e55767fbc35467727ba0e67 to your computer and use it in GitHub Desktop.
Gradle modularization tricks
// You can have shared configuration for modules
// For example, pure kotlin modules can shared following kotlin-library-bootstrap.gradle
//###
apply plugin: 'java-library'
apply plugin: 'kotlin'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
api libraries.kotlinStandardLibrary
testImplementation libraries.junit
}
//###
// Or android library module: android-library-bootstrap.gradle
//###
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
androidExtensions {
experimental = true
}
android {
compileSdkVersion CompileVersions.compileSdk
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
debug {
minifyEnabled false
debuggable true
}
release {
minifyEnabled false
}
}
testOptions {
animationsDisabled = true
execution 'ANDROID_TEST_ORCHESTRATOR'
}
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
api libraries.kotlinStandardLibrary
testImplementation libraries.junit
androidTestImplementation libraries.testRunner
androidTestUtil libraries.testOrchestrator
}
//###
// Then in main project build.gradle file add following:
//###
buildscript {
ext.bootstrap = [
kotlinLibrary : "${project.rootDir}/config/kotlin-library-bootstrap.gradle",
androidLibrary : "${project.rootDir}/config/android-library-bootstrap.gradle"
]
}
//###
// Then in any module you can use now following line
//###
apply from: bootstrap.androidLibrary
//###
// or
//###
apply from: bootstrap.kotlinLibrary
//
// Put all you dependencies into one file: dependencies.gradle
//###
ext.versions = [
compileSdkVersion : 28,
targetSdkVersion : 28,
minSdkVersion : 21,
gradle : '4.10.2',
// gradle plugins
androidGradlePlugin : '3.2.1',
// libraries
archComponents : '1.1.1',
]
ext.gradlePlugins = [
android : "com.android.tools.build:gradle:$versions.androidGradlePlugin",
]
ext.libraries = [
archComponentsCommon : "android.arch.lifecycle:common-java8:$versions.archComponents",
archComponentsViewModel : "android.arch.lifecycle:viewmodel:$versions.archComponents",
archComponentsExt : "android.arch.lifecycle:extensions:$versions.archComponents",
archComponentsCompiler : "android.arch.lifecycle:compiler:$versions.archComponents",
archComponentsTesting : "android.arch.core:core-testing:$versions.archComponents",
]
//###
// Add In main project build.gradle file
//###
buildscript {
apply from: 'dependencies.gradle'
classpath gradlePlugins.android // Here is used dependency definintion defined in
}
apply from: 'dependencies.gradle'
//###
// Then in module build.gradle you also can use it
//###
dependencies {
implementation libraries.archComponentsCommon
}
//###
// Create a module-limitation.gradle file with following content
//###
def limitModuleUsage(Project moduleProject, String allowOnlyInModules) {
rootProject.subprojects { subProject ->
subProject.configurations.all {
allDependencies.withType(ProjectDependency.class) {
if (it.dependencyProject == moduleProject &&
!subProject.path.startsWith(allowOnlyInModules)) {
throw new GradleException("$subProject should not have as a depenency $moduleProject!")
}
}
}
}
}
// Exporting method
ext.limitUsageToModules = this.&limitUsageToModules
//###
// Add this file to bootstrap files
//###
apply from: "${project.rootDir}/config/module-limitation.gradle"
//###
// Then in the module build file you can use following:
//###
limitUsageToModules(project, ":core")
//###
// Add following to project settings.gradle to dynamically add all modules from rootDir
// This version assumes that module has build.gradle file
// Define dirs pattern to skip traversing
def skipDirs = ~/^(build|…*|src|out|config)/
def preDir = {
if (skipDirs.matcher(it.name).matches()) return FileVisitResult.SKIP_SUBTREE
}
def getProjectName(String dir) {
return (dir - (rootDir.toString() + '/')).replaceAll('/', ':')
}
rootDir.traverse(type: FileType.DIRECTORIES, preDir: preDir) { dir->
String dstr = dir.toString()
if (new File(dstr + '/build.gradle').exists()) {
logger.info("Including module from ${dstr}")
include getProjectName(dstr)
}
}
// Add following to project settings.gradle to dynamically add all modules from rootDir
// This version assumes that module has not a standard build.gradle file.
// For example, module that are in feature/login directory should have feature-login.gradle file
import groovy.io.FileType
import groovy.io.FileVisitResult
// Define dirs pattern to skip traversing
def skipDirs = ~/^(build|\..*|src|out|config)/
def preDir = {
if (skipDirs.matcher(it.name).matches()) return FileVisitResult.SKIP_SUBTREE
}
def getProjectName(String dir) {
return (dir - (rootDir.toString() + '/')).replaceAll('/', ':')
}
def getProjectBuildFile(String dir) {
return ((dir - (rootDir.toString() + '/')).replaceAll('/', '-')) + '.gradle'
}
rootDir.traverse(type: FileType.DIRECTORIES, preDir: preDir) { dir->
String dstr = dir.toString()
if (new File(dstr + '/' + getProjectBuildFile(dstr)).exists()) {
def projectName = getProjectName(dstr)
logger.info("Including module from ${dstr} with project name: ${projectName}")
include projectName
project(':' + projectName).buildFileName = getProjectBuildFile(dstr)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment