SlideShare a Scribd company logo
1 of 53
Download to read offline
Gradle Dependency
Management when Multi
Module
김규하
Why?
playServicesAnalytics = "com.google.android.gms:play-services-analytics:$analyticsVersion"
playServicesAds = "com.google.android.gms:play-services-ads:$adsVersion"
appboy = 'com.appboy:android-sdk-ui-x:$appboyVersion'
twitter = 'com.twitter.sdk.android:twitter:$twitterVersion'
facebook = 'com.facebook.android:facebook-android-sdk:$facebookVersion'
fresco = "com.facebook.fresco:fresco:$frescoVersion"
frescoStetho = "com.facebook.fresco:stetho:$frescoVersion"
frescoAnimatedGif = "com.facebook.fresco:animated-gif:$frescoVersion"
frescoImagepipelineOkhttp = "com.facebook.fresco:imagepipeline-okhttp3:$frescoVersion"
naver = 'com.naver.nid:naveridlogin-android-sdk:$naverVersion'
bottomDialogs ='com.github.javiersantos:BottomDialogs:$bottomDialogsVersion''
crashlytics ='com.crashlytics.sdk.android:crashlytics:$crashlyticsVersion'
dagger2 ="com.google.dagger:dagger:$daggerVersion"
dagger2Compiler ="com.google.dagger:dagger-compiler:$daggerVersion"
eventbus ='org.greenrobot:eventbus:$eventbusVersion'
glide = "com.github.bumptech.glide:glide:$glideVersion"
glideOkHttp = "com.github.bumptech.glide:okhttp3-integration:$glideVersion"
glideCompiler ="com.github.bumptech.glide:compiler:$glideVersion"
gson ='com.google.code.gson:gson:$gsonVersion'
gsonConverter ="com.squareup.retrofit2:converter-gson:$retrofitVersion"
kotlin = "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
kotlinReflect = "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
kotlinJdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
licensesDialog ='de.psdev.licensesdialog:licensesdialog:$licensesDIalogVersion'
materialShowcaseView ='com.github.lezhin:MaterialShowcaseView:$materialShowcaseVersion'
mockito ='org.mockito:mockito-core:$mockitoVersion'
okhttp3 ="com.squareup.okhttp3:okhttp:$okhttpVersion"
okhttp3Interceptor ="com.squareup.okhttp3:logging-interceptor:$okhttpVersion"
.... 40 more
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
A Module
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
C Module
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
B Module
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
.
.
.
.
.
No!!
Extra Properties?
All extra properties must be defined through the "ext" namespace. Once an extra property has been defined, it is available
directly on the owning object (in the below case the Project, Task, and sub-projects respectively) and can be read and updated.
Only the initial declaration that needs to be done via the namespace.
buildscript {
dependencies {
apply from: “dependencies.gradle”
…
}
}
allprojects { … }
subprojects { … }
task clean(type: Delete) { … }
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
implementation ‘(org.jetbrains.kotlin:kotlin-stdlib-jdk7):(1.3.21)’
implementation '(androidx.appcompat:appcompat):(1.0.2)'
implementation '(androidx.core:core-ktx):(1.0.1)'
implementation '(androidx.constraintlayout:constraintlayout):(1.1.3)'
testImplementation '(junit:junit):(4.12)'
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21
androidx.appcompat:appcompat:1.0.2
androidx.core:core-ktx:1.0.1
androidx.constraintlayout:constraintlayout:1.1.3
junit:junit:4.12
ext {
…
...
}
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21
androidx.appcompat:appcompat:1.0.2
androidx.core:core-ktx:1.0.1
androidx.constraintlayout:constraintlayout:1.1.3
junit:junit:4.12
ext {
… // versions
… // paths
}
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21
androidx.appcompat:appcompat:1.0.2
androidx.core:core-ktx:1.0.1
androidx.constraintlayout:constraintlayout:1.1.3
junit:junit:4.12
ext {
kotlinVersion = '1.3.21'
appcompatVersion = '1.0.2'
coreVersion = '1.0.1'
constraintLayoutVersion = '1.1.3'
junitVersion = '4.12'
… // paths
}
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21
androidx.appcompat:appcompat:1.0.2
androidx.core:core-ktx:1.0.1
androidx.constraintlayout:constraintlayout:1.1.3
junit:junit:4.12
ext {
… // versions
kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion"
androidCoreLibrary = "androidx.core:core-ktx:$coreVersion"
constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion"
junitLibrary = "junit:junit:$junitVersion"
}
implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.junitLibrary
}
A Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
C Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
B Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
.
.
.
.
.
END?
No!!
ext {
kotlinVersion = '1.3.21'
appcompatVersion = '1.0.2'
coreVersion = '1.0.1'
constraintLayoutVersion = '1.1.3'
jUnitVersion = '4.12'
kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion"
androidCoreLibrary = "androidx.core:core-ktx:$coreVersion"
constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion"
junitLibrary = "junit:junit:$junitVersion"
}
ext {
kotlinVersion = '1.3.21'
appcompatVersion = '1.0.2'
coreVersion = '1.0.1'
constraintLayoutVersion = '1.1.3'
jUnitVersion = '4.12'
kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion"
androidCoreLibrary = "androidx.core:core-ktx:$coreVersion"
constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion"
jUnitLibrary = "junit:junit:$jUnitVersion"
}
A Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
C Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
B Module
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.jUnitLibrary
}
.
.
.
.
.
A Module
dependencies {
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
testImplementation rootProject.ext.jUnitLibrary
}
C Module
dependencies {
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
testImplementation rootProject.ext.jUnitLibrary
}
B Module
dependencies {
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
testImplementation rootProject.ext.jUnitLibrary
}
.
.
.
.
.
a….?
buildscript {
dependencies {
apply from: "dependencies_version.gradle"
…
}
}
allprojects { … }
subprojects {
dependencies {
apply from: “$rootProject.rootDir/dependencies_group.gradle”
apply from: “$rootProject.rootDir/dependencies.gradle”
…
}
}
task clean(type: Delete) { … }
ext {
kotlinVersion = '1.3.21'
appcompatVersion = '1.0.2'
coreVersion = '1.0.1'
constraintLayoutVersion = '1.1.3'
jUnitVersion = '4.12'
kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion"
androidCoreLibrary = "androidx.core:core-ktx:$coreVersion"
constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion"
junitLibrary = "junit:junit:$junitVersion"
}
ext {
… // version
… // paths
}
ext.versions = [ … ] // in dependencies_version.gradle
ext.deps = [ … ] // in dependencies_group.gradle
ext {
kotlinVersion = '1.3.21'
appcompatVersion = '1.0.2'
coreVersion = '1.0.1'
constraintLayoutVersion = '1.1.3'
jUnitVersion = '4.12'
...
}
ext.versions = [
"kotlin" : "1.3.21",
"appcompat" : "1.0.2",
"core" : "1.0.1",
"constraintLayout": "1.1.3",
"junit" : "4.12"
]
ext {
…
kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion"
androidCoreLibrary = "androidx.core:core-ktx:$coreVersion"
constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion"
jUnitLibrary = "junit:junit:$jUnitVersion"
}
ext.deps = [
"kotlin" : [
"std": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin"
],
"android": [
"appcompat" : "androidx.appcompat:appcompat:$versions.appcompat",
"core" : "androidx.core:core-ktx:$versions.core",
"constraintLayout": "androidx.constraintlayout:constraintlayout:$versions.constraintLayout"
],
"test" : [
"junit": "junit:junit:$versions.junit"
]
]
def Group(Closure closure) {
closure.delegate = dependencies
return closure
}
ext {
...
}
def Group(Closure closure) { … }
ext {
kotlin = Group {
implementation deps.kotlin.std
}
android = Group {
implementation deps.android.appcompat
implementation deps.android.core
implementation deps.android.constraintLayout
}
test = Group {
testImplementation deps.test.junit
}
}
dependencies {
implementation rootProject.ext.kotlinStdLibrary
implementation rootProject.ext.appcompatLibrary
implementation rootProject.ext.androidCoreLibrary
implementation rootProject.ext.constraintLayoutLibrary
testImplementation rootProject.ext.junitLibrary
}
dependencies {
kotlin()
android()
test()
}
A Module
dependencies {
kotlin()
android()
test()
}
C Module
dependencies {
kotlin()
android()
test()
}
B Module
dependencies {
kotlin()
android()
test()
}
.
.
.
.
.
HMM….?
1. Groovy
2. Inconvenience
3. Complexity
Kotlin Gradle이
나왔다는데...
repositories {
jcenter()
}
plugins {
`kotlin-dsl`
}
ext.versions = [
"kotlin" : "1.3.21",
"appcompat" : "1.0.2",
"core" : "1.0.1",
"constraintLayout": "1.1.3",
"junit" : "4.12"
]
object Versions {
const val kotlin = "1.3.21"
const val appcompat = "1.0.2"
const val core = "1.0.1"
const val constraintLayout = "1.1.3"
const val junit = "4.12"
}
ext.deps = [
"kotlin" : [
"std": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin"
],
"android": [
"appcompat" : "androidx.appcompat:appcompat:$versions.appcompat",
"core" : "androidx.core:core-ktx:$versions.core",
"constraintLayout": "androidx.constraintlayout:constraintlayout:$versions.constraintLayout"
],
"test" : [
"junit": "junit:junit:$versions.junit"
]
]
object Groups {
const val std = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
const val core = "androidx.core:core-ktx:${Versions.core}"
const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}"
const val junit = "junit:junit:${Versions.junit}"
}
def Group(Closure closure) {
closure.delegate = dependencies
return closure
}
private fun DependencyHandler.implementation(
dependencyString: String
) {
add("implementation", dependencyString)
}
private fun DependencyHandler.testImplementation(
dependencyString: String
) {
add("testImplementation", dependencyString)
}
.
.
.
def Group(Closure closure) { … }
ext {
kotlin = Group {
implementation deps.kotlin.std
}
android = Group {
implementation deps.android.appcompat
implementation deps.android.core
implementation deps.android.constraintLayout
}
test = Group {
testImplementation deps.test.junit
}
}
import org.gradle.api.artifacts.dsl.DependencyHandler
fun DependencyHandler.kotlinGroup() {
implementation(Groups.std)
}
fun DependencyHandler.androidGroup() {
implementation(Groups.appcompat)
implementation(Groups.core)
implementation(Groups.constraintLayout)
}
fun DependencyHandler.testGroup() {
testImplementation(Groups.junit)
}
private fun DependencyHandler.implementation …
dependencies {
kotlinGroup()
androidGroup()
testGroup()
}
dependencies {
kotlin()
android()
test()
}
C Module
dependencies {
kotlinGroup()
androidGroup()
testGroup()
}
B Module
dependencies {
kotlinGroup()
androidGroup()
testGroup()
}
.
.
.
.
.
A Module
dependencies {
kotlinGroup()
androidGroup()
testGroup()
}
SO
1. Kotlin!!!
2. Convenience
3. Simple
감사합니다.

More Related Content

Similar to Gradle dependency management when multi module

Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StoryKon Soulianidis
 
7 Ways to improve your gradle build
7 Ways to improve your gradle build7 Ways to improve your gradle build
7 Ways to improve your gradle buildTania Pinheiro
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Andres Almiray
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Andres Almiray
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesMichael Galpin
 
Native Android Development Practices
Native Android Development PracticesNative Android Development Practices
Native Android Development PracticesRoy Clarkson
 
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...Infinum
 
Fragments: Why, How, What For?
Fragments: Why, How, What For?Fragments: Why, How, What For?
Fragments: Why, How, What For?Brenda Cook
 
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)Kelly Shuster
 
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능GDG Korea
 
Invading the home screen
Invading the home screenInvading the home screen
Invading the home screenMatteo Bonifazi
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android AppsGil Irizarry
 
rssfeeds.classpathrssfeeds.project rssfeed .docx
rssfeeds.classpathrssfeeds.project  rssfeed  .docxrssfeeds.classpathrssfeeds.project  rssfeed  .docx
rssfeeds.classpathrssfeeds.project rssfeed .docxjoellemurphey
 
android level 3
android level 3android level 3
android level 3DevMix
 
DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsKyungmin Lee
 
Considerations with Writing JavaScript in your DotNetNuke site
Considerations with Writing JavaScript in your DotNetNuke siteConsiderations with Writing JavaScript in your DotNetNuke site
Considerations with Writing JavaScript in your DotNetNuke siteEngage Software
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)DroidConTLV
 
Getting started with building your own standalone Gradle plugin
Getting started with building your own standalone Gradle pluginGetting started with building your own standalone Gradle plugin
Getting started with building your own standalone Gradle plugintobiaspreuss
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Johnny Sung
 

Similar to Gradle dependency management when multi module (20)

Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle Story
 
7 Ways to improve your gradle build
7 Ways to improve your gradle build7 Ways to improve your gradle build
7 Ways to improve your gradle build
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
 
Native Android Development Practices
Native Android Development PracticesNative Android Development Practices
Native Android Development Practices
 
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...
Infinum Android Talks #14 - Data binding to the rescue... or not (?) by Krist...
 
Fragments: Why, How, What For?
Fragments: Why, How, What For?Fragments: Why, How, What For?
Fragments: Why, How, What For?
 
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
 
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
GKAC 2014 Nov. - 안드로이드 5.0의 새로운 기능
 
Invading the home screen
Invading the home screenInvading the home screen
Invading the home screen
 
Beginning Native Android Apps
Beginning Native Android AppsBeginning Native Android Apps
Beginning Native Android Apps
 
rssfeeds.classpathrssfeeds.project rssfeed .docx
rssfeeds.classpathrssfeeds.project  rssfeed  .docxrssfeeds.classpathrssfeeds.project  rssfeed  .docx
rssfeeds.classpathrssfeeds.project rssfeed .docx
 
android level 3
android level 3android level 3
android level 3
 
Android Data Binding
Android Data BindingAndroid Data Binding
Android Data Binding
 
DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android Applications
 
Considerations with Writing JavaScript in your DotNetNuke site
Considerations with Writing JavaScript in your DotNetNuke siteConsiderations with Writing JavaScript in your DotNetNuke site
Considerations with Writing JavaScript in your DotNetNuke site
 
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
Best Practices for Using Mobile SDKs - Lilach Wagner, SafeDK (AppLovin)
 
Getting started with building your own standalone Gradle plugin
Getting started with building your own standalone Gradle pluginGetting started with building your own standalone Gradle plugin
Getting started with building your own standalone Gradle plugin
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101
 

Recently uploaded

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 

Recently uploaded (20)

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 

Gradle dependency management when multi module

  • 1. Gradle Dependency Management when Multi Module 김규하
  • 3. playServicesAnalytics = "com.google.android.gms:play-services-analytics:$analyticsVersion" playServicesAds = "com.google.android.gms:play-services-ads:$adsVersion" appboy = 'com.appboy:android-sdk-ui-x:$appboyVersion' twitter = 'com.twitter.sdk.android:twitter:$twitterVersion' facebook = 'com.facebook.android:facebook-android-sdk:$facebookVersion' fresco = "com.facebook.fresco:fresco:$frescoVersion" frescoStetho = "com.facebook.fresco:stetho:$frescoVersion" frescoAnimatedGif = "com.facebook.fresco:animated-gif:$frescoVersion" frescoImagepipelineOkhttp = "com.facebook.fresco:imagepipeline-okhttp3:$frescoVersion" naver = 'com.naver.nid:naveridlogin-android-sdk:$naverVersion' bottomDialogs ='com.github.javiersantos:BottomDialogs:$bottomDialogsVersion'' crashlytics ='com.crashlytics.sdk.android:crashlytics:$crashlyticsVersion' dagger2 ="com.google.dagger:dagger:$daggerVersion" dagger2Compiler ="com.google.dagger:dagger-compiler:$daggerVersion" eventbus ='org.greenrobot:eventbus:$eventbusVersion' glide = "com.github.bumptech.glide:glide:$glideVersion" glideOkHttp = "com.github.bumptech.glide:okhttp3-integration:$glideVersion" glideCompiler ="com.github.bumptech.glide:compiler:$glideVersion" gson ='com.google.code.gson:gson:$gsonVersion' gsonConverter ="com.squareup.retrofit2:converter-gson:$retrofitVersion" kotlin = "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" kotlinReflect = "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" kotlinJdk8 = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" licensesDialog ='de.psdev.licensesdialog:licensesdialog:$licensesDIalogVersion' materialShowcaseView ='com.github.lezhin:MaterialShowcaseView:$materialShowcaseVersion' mockito ='org.mockito:mockito-core:$mockitoVersion' okhttp3 ="com.squareup.okhttp3:okhttp:$okhttpVersion" okhttp3Interceptor ="com.squareup.okhttp3:logging-interceptor:$okhttpVersion" .... 40 more
  • 4. implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12'
  • 5. A Module implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' C Module implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' B Module implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' . . . . .
  • 8. All extra properties must be defined through the "ext" namespace. Once an extra property has been defined, it is available directly on the owning object (in the below case the Project, Task, and sub-projects respectively) and can be read and updated. Only the initial declaration that needs to be done via the namespace.
  • 9.
  • 10.
  • 11. buildscript { dependencies { apply from: “dependencies.gradle” … } } allprojects { … } subprojects { … } task clean(type: Delete) { … }
  • 12. implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12'
  • 13. implementation ‘(org.jetbrains.kotlin:kotlin-stdlib-jdk7):(1.3.21)’ implementation '(androidx.appcompat:appcompat):(1.0.2)' implementation '(androidx.core:core-ktx):(1.0.1)' implementation '(androidx.constraintlayout:constraintlayout):(1.1.3)' testImplementation '(junit:junit):(4.12)'
  • 16. org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 androidx.appcompat:appcompat:1.0.2 androidx.core:core-ktx:1.0.1 androidx.constraintlayout:constraintlayout:1.1.3 junit:junit:4.12 ext { kotlinVersion = '1.3.21' appcompatVersion = '1.0.2' coreVersion = '1.0.1' constraintLayoutVersion = '1.1.3' junitVersion = '4.12' … // paths }
  • 17. org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 androidx.appcompat:appcompat:1.0.2 androidx.core:core-ktx:1.0.1 androidx.constraintlayout:constraintlayout:1.1.3 junit:junit:4.12 ext { … // versions kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion" androidCoreLibrary = "androidx.core:core-ktx:$coreVersion" constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" junitLibrary = "junit:junit:$junitVersion" }
  • 18. implementation ‘org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21’ implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.junitLibrary }
  • 19. A Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } C Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } B Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } . . . . .
  • 20. END?
  • 21. No!!
  • 22. ext { kotlinVersion = '1.3.21' appcompatVersion = '1.0.2' coreVersion = '1.0.1' constraintLayoutVersion = '1.1.3' jUnitVersion = '4.12' kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion" androidCoreLibrary = "androidx.core:core-ktx:$coreVersion" constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" junitLibrary = "junit:junit:$junitVersion" }
  • 23. ext { kotlinVersion = '1.3.21' appcompatVersion = '1.0.2' coreVersion = '1.0.1' constraintLayoutVersion = '1.1.3' jUnitVersion = '4.12' kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion" androidCoreLibrary = "androidx.core:core-ktx:$coreVersion" constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" jUnitLibrary = "junit:junit:$jUnitVersion" }
  • 24. A Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } C Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } B Module dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.jUnitLibrary } . . . . .
  • 25. A Module dependencies { implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary testImplementation rootProject.ext.jUnitLibrary } C Module dependencies { implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary testImplementation rootProject.ext.jUnitLibrary } B Module dependencies { implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary testImplementation rootProject.ext.jUnitLibrary } . . . . .
  • 27.
  • 28. buildscript { dependencies { apply from: "dependencies_version.gradle" … } } allprojects { … } subprojects { dependencies { apply from: “$rootProject.rootDir/dependencies_group.gradle” apply from: “$rootProject.rootDir/dependencies.gradle” … } } task clean(type: Delete) { … }
  • 29. ext { kotlinVersion = '1.3.21' appcompatVersion = '1.0.2' coreVersion = '1.0.1' constraintLayoutVersion = '1.1.3' jUnitVersion = '4.12' kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion" androidCoreLibrary = "androidx.core:core-ktx:$coreVersion" constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" junitLibrary = "junit:junit:$junitVersion" }
  • 30. ext { … // version … // paths } ext.versions = [ … ] // in dependencies_version.gradle ext.deps = [ … ] // in dependencies_group.gradle
  • 31. ext { kotlinVersion = '1.3.21' appcompatVersion = '1.0.2' coreVersion = '1.0.1' constraintLayoutVersion = '1.1.3' jUnitVersion = '4.12' ... } ext.versions = [ "kotlin" : "1.3.21", "appcompat" : "1.0.2", "core" : "1.0.1", "constraintLayout": "1.1.3", "junit" : "4.12" ]
  • 32. ext { … kotlinStdLibrary = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" appcompatLibrary = "androidx.appcompat:appcompat:$appcompatVersion" androidCoreLibrary = "androidx.core:core-ktx:$coreVersion" constraintLayoutLibrary = "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" jUnitLibrary = "junit:junit:$jUnitVersion" } ext.deps = [ "kotlin" : [ "std": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin" ], "android": [ "appcompat" : "androidx.appcompat:appcompat:$versions.appcompat", "core" : "androidx.core:core-ktx:$versions.core", "constraintLayout": "androidx.constraintlayout:constraintlayout:$versions.constraintLayout" ], "test" : [ "junit": "junit:junit:$versions.junit" ] ]
  • 33. def Group(Closure closure) { closure.delegate = dependencies return closure } ext { ... }
  • 34. def Group(Closure closure) { … } ext { kotlin = Group { implementation deps.kotlin.std } android = Group { implementation deps.android.appcompat implementation deps.android.core implementation deps.android.constraintLayout } test = Group { testImplementation deps.test.junit } }
  • 35. dependencies { implementation rootProject.ext.kotlinStdLibrary implementation rootProject.ext.appcompatLibrary implementation rootProject.ext.androidCoreLibrary implementation rootProject.ext.constraintLayoutLibrary testImplementation rootProject.ext.junitLibrary } dependencies { kotlin() android() test() }
  • 36. A Module dependencies { kotlin() android() test() } C Module dependencies { kotlin() android() test() } B Module dependencies { kotlin() android() test() } . . . . .
  • 40.
  • 41.
  • 43.
  • 44.
  • 45. ext.versions = [ "kotlin" : "1.3.21", "appcompat" : "1.0.2", "core" : "1.0.1", "constraintLayout": "1.1.3", "junit" : "4.12" ] object Versions { const val kotlin = "1.3.21" const val appcompat = "1.0.2" const val core = "1.0.1" const val constraintLayout = "1.1.3" const val junit = "4.12" }
  • 46. ext.deps = [ "kotlin" : [ "std": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlin" ], "android": [ "appcompat" : "androidx.appcompat:appcompat:$versions.appcompat", "core" : "androidx.core:core-ktx:$versions.core", "constraintLayout": "androidx.constraintlayout:constraintlayout:$versions.constraintLayout" ], "test" : [ "junit": "junit:junit:$versions.junit" ] ] object Groups { const val std = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}" const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}" const val core = "androidx.core:core-ktx:${Versions.core}" const val constraintLayout = "androidx.constraintlayout:constraintlayout:${Versions.constraintLayout}" const val junit = "junit:junit:${Versions.junit}" }
  • 47. def Group(Closure closure) { closure.delegate = dependencies return closure } private fun DependencyHandler.implementation( dependencyString: String ) { add("implementation", dependencyString) } private fun DependencyHandler.testImplementation( dependencyString: String ) { add("testImplementation", dependencyString) } . . .
  • 48. def Group(Closure closure) { … } ext { kotlin = Group { implementation deps.kotlin.std } android = Group { implementation deps.android.appcompat implementation deps.android.core implementation deps.android.constraintLayout } test = Group { testImplementation deps.test.junit } } import org.gradle.api.artifacts.dsl.DependencyHandler fun DependencyHandler.kotlinGroup() { implementation(Groups.std) } fun DependencyHandler.androidGroup() { implementation(Groups.appcompat) implementation(Groups.core) implementation(Groups.constraintLayout) } fun DependencyHandler.testGroup() { testImplementation(Groups.junit) } private fun DependencyHandler.implementation …
  • 50. C Module dependencies { kotlinGroup() androidGroup() testGroup() } B Module dependencies { kotlinGroup() androidGroup() testGroup() } . . . . . A Module dependencies { kotlinGroup() androidGroup() testGroup() }
  • 51. SO