ã¯ããã«
ããã«ã¡ã¯ãã¬ã·ãäºæ¥é¨ã§é·æã¤ã³ã¿ã¼ã³ä¸ã®æ¾æ¬ (@matsumo0922 ) ã§ããå
æ¥ãã®ããã°ã§ãå
¬éããéããã¯ãã¯ãããã§ã¯æ¥æ¬ã¨ã°ãã¼ãã«ã§ä½é¨ãçµ±ä¸ãã One Experience ã¨ããããã¸ã§ã¯ããè¡ã£ã¦ãã¾ãã
One Experience 以åã§ã¯ Android éçºã«ããã¦ãæ¥æ¬ã¨ã°ãã¼ãã«ã§ã³ã¼ããã¼ã¹ãç°ãªãããããã使ç¨ãã¦ããæè¡ãã©ã¤ãã©ãªãç°ãªãç¶æ
ã§ãããç¹ã«ã°ãã¼ãã«ã®ã³ã¼ããã¼ã¹ (ä»¥ä¸ global-android
ã¨å¼ã³ã¾ã) ã§ã¯ AGP ã®ãã¼ã¸ã§ã³ãä½ããå ã㦠groovy + buildSrc ã¨è¨ã£ãæ§ä¸ä»£ã®ãã«ããã¸ãã¯ãç¨ãã¦ãããããããã¸ã§ã¯ãã®é²è¡ã«æ¯éãããç¶æ
ã§ãããæ¬è¨äºã§ã¯ããããã®åé¡ãè¸ã¾ã One Experience ãããåæ»ã«é²ããããã«æ½ãããã«ããã¸ãã¯ã®æ¹åã«ã¤ãã¦ã話ããã¾ãã
TL;DR
global-android ã§ã¯æ§ä¸ä»£ã®ãã«ããã¸ãã¯ã使ã£ã¦ãããã One Experience ç¨ã®æ©è½éçºã«æ¯éãããç¶æ
ã ã£ã
ã©ã¤ãã©ãªç®¡çã VersionCatalog ã¸ãã¹ã¯ãªããã Kotlin DSL ã¸ç§»è¡ããã¨å
±ã«ãGradle Composite Build + Convention Plugins ãç¨ãã¦ãã«ããã¸ãã¯ã®å
±éåãè¡ã£ã
æçµçã«ãåã¢ã¸ã¥ã¼ã«ã® build.gradle.kts
ã¯é常ã«ç°¡æ½ã«ãªãã大æµã®ãã«ããã¸ãã¯ãå
±éåãããéçºãããå¹ççã«é²ããããããã«ãªã£ã
åé¡ç¹
global-android ã® Gradle ãã«ãã«ã¯ä»¥ä¸ã®ãããªåé¡ç¹ãããã¾ããã
dependencies.gradle ãç¨ããæåã®ã©ã¤ãã©ãª & ãã¼ã¸ã§ã³ç®¡ç
groovy ã§æ¸ããããã«ããã¸ãã¯
大éã«ã¢ã¸ã¥ã¼ã«ãããã«ãé¢ããããä¸é¨ãã¸ãã¯ãå
±éåããã¦ããªã
global-android ã§ã®ã©ã¤ãã©ãªç®¡ç
ã¾ããã©ã¤ãã©ãªã®ãã¼ã¸ã§ã³ç®¡çã«ã¤ãã¦ãä¸ã®ç»åã®ããã«ãglobal-android ã§ã¯ã©ã¤ãã©ãªã®å®ç¾©ï¼ãã¼ã¸ã§ã³ãå«ãï¼ã gradle ã® ExtraPropertyExtension
ãç¨ãã¦è¨è¿°ããåã¢ã¸ã¥ã¼ã«ã«é
å¸ãã¦ãã¾ããããã®ææ³ã®è©³ç´°ã«ã¤ãã¦ã¯å²æãã¾ããããæ³åã®éãã©ã¤ãã©ãªç®¡ç & ãã¼ã¸ã§ã³ç®¡çãè¤éã«ãªããã㤠IDE ã®æå©ãã renovate ã dependabot ã¨è¨ã£ããµã¼ãã¹ã使ããã¨ãã§ããªããããéçºè
ã®ä½é¨ãæªããã¦ãã¾ããã
次ã«ãã«ããã¸ãã¯ã«ã¤ãã¦ãglobal-android ã«ã¯ buildSrc ãå°å
¥ããã¦ãã¾ããããè¨è¿°ããã¦ããã®ã¯ CI/CD ã§ç¨ããããå
±éã¿ã¹ã¯ã®å®ç¾©ã®ã¿ã§ãããå®éã®ãã«ããã¸ãã¯ã¯åã¢ã¸ã¥ã¼ã«ã® .gradle
ãã¡ã¤ã«ã«åæ£ãã¦ãã¾ãããã¨ããã®ããbuildSrc ã¯ãã«ããã¸ãã¯ãè¨è¿°ããã®ã«æé©ãªå ´æã§ã¯ãããã®ã®ããã¹ã¦ã® gradle build ã®ããããã¹ã§ããããããããããã«ãã§ã³ã¼ããã³ã³ãã¤ã« & ãã§ãã¯ãè¡ã£ã¦ãã¾ãããã§ãããã¡ããåå以å¤ã¯ãã£ãã·ã¥ãç¨ãããã¾ãããglobal-android ã®ãããªå·¨å¤§ããã¸ã§ã¯ãã§ã¯ç¡è¦ã§ããªãã³ã¹ããçºçãã¾ããå ãã¦ãbuildSrc ã¸ã®å¤æ´ã¯ããã¸ã§ã¯ãå
¨ä½ã® classpath å¤æ´ãã¤ã¾ããã£ãã·ã¥ãç¡å¹ã«ãªãã¨ããæå³ãæã¤ãããbuildSrc ã¸ãã«ããã¸ãã¯ã追å ããã®ã¯æ
éã«ãªããããå¾ã¾ããã
$ find . -type f -name '*.gradle' -exec wc -l {} + | tail -n1 # ããã¸ã§ã¯ãå
¨ä½ã® Groovy ãã¡ã¤ã«ã®è¡æ°
3736 total
ããã§ãã©ã¤ãã©ãªã®ç®¡çã VersionCatalog ã«ç§»è¡ãã¤ã¤ã gradle ã® Conposite Build
㨠Convention Plugins
ã¨è¨ã£ãææ³ãç¨ãããã«ããã¸ãã¯ã®ã¿ãããã¸ã§ã¯ãããåé¢ãããã¨ã§ã³ã¹ãã®åæ¸ããã«ããã¸ãã¯ã®å
±éåãè¨ããã¨ã«ãã¾ããã
Composite Build ã¨ã¯
ä¸è¨ã§è¨ãã°ããããã¸ã§ã¯ãããåãé¢ããããã«ããã®ãã¨ã§ããComposite Build1 å
ã®å build 㯠include build
ã¨å¼ã°ããinclude build å士ã¯ãã¸ãã¯ãå
±æãããåå¥ã«æ§æ & å®è¡ããã¾ãã
Convention Plugins ãç¨ããããã¸ã§ã¯ãã®ä¾2
ä¸ã®ä¾ã§ã¯ my-app
㨠my-utils
ã Composite Build ãç¨ãã¦ä¸ã¤ã®ããã¸ã§ã¯ãã«ã¾ã¨ãã¦ãã¾ããmy-app
㯠my-utils
ã«ä¾åãæã¤ãã¨ãã§ãã¾ããããã®å ´åã®ä¾åã¯ãç´æ¥çãªä¾åãã«ã¯ãªãã¾ããããããã®ã¢ã¸ã¥ã¼ã«ã¯ include build ã§ãããããç´æ¥çã« my-utils
ãåç
§ãããã¨ã¯ã§ãããbuild ãéãã¦çæãããå®è¡å¯è½ãã¡ã¤ã«ï¼ãã¤ããªï¼ãåç
§ãããã¨ã«ãªãã¾ãããã®ãããbuildSrc ã®ãããªå®è¡é度ããã£ãã·ã¥ã®åé¡ãçºçãããã«ããããããã¸ãã¯ãè¨è¿°ãããã¨ãå¯è½ã«ãªãã¾ãã
Convention Plugins ã¨ã¯
Convention Plugins3 ã¨ã¯ãã«ããã¸ãã¯ã Gradle Plugin System ãç¨ãã¦å
±éåããPlugin ã¨ãã¦é
å¸ããææ³ã®ãã¨ãæãã¾ããPlugin ã®ä½ææ¹æ³ã«ã¤ãã¦ã¯ Standalone Gradle Plugin
㨠Precompiled Script Plugin
ãåå¨ãã¾ããããããã® Plugin ã®ä½ææ¹æ³ã«ã¤ãã¦ã¯å²æãã¾ãããä»å㯠Composite Build ã使ç¨ããé½åä¸ãç´æ¥ã¹ã¯ãªãããã¡ã¤ã«ãåç
§ã§ããªããããStandalone Gradle Plugin
ãç¨ãããã¨ã«ãã¾ããã
ã¾ã¨ããã¨ãComposite Build
ãç¨ãã¦ã¢ã¸ã¥ã¼ã«ãä½æãï¼build-logic
ã¢ã¸ã¥ã¼ã«ã¨ãã¾ãï¼ãä¸ã§ Convention Plugins
ãç¨ãã¦ãã«ããã¸ãã¯ãå
±éåãããã¨è¨ã£ãææ³ãåããã¨ã«ãã¾ããã
å®è£
æ§æ
æåã«ãæçµçãªãã£ã¬ã¯ããªæ§æã示ãã¾ãã
global-android/
âââ build-logic/
â âââ src/
â â âââ main/
â â âââ java/
â â âââ convention/
â â â âââ FeaturePlugin.kt
â â âââ primitive/
â â âââ ApplicationPlugin.kt
â â âââ ComposePlugin.kt
â â âââ CommonPlugin.kt
â â âââ FlavorPlugin.kt
â âââ build.gradle.kts
â âââ settings.gradle.kts
âââ cookpad/
âââ ...
大ã¾ãã«ã¯ä¸è¬çãªã¢ã¸ã¥ã¼ã«ã®æ§æã¨å¤ããããã¾ããããã ä¸ã¤æ³¨æãå¿
è¦ãªç¹ã¯ãbuild-logic
㯠cookpad
ã¢ã¸ã¥ã¼ã«ã« include build ããããããGradle çã«ã¯ä¸ã¤ã®ããã¸ã§ã¯ãã¨ãã¦æ±ãããã¨ãããã¨ã§ãããã®ãããç´ä¸ã« settings.gradle.kts
ãé
ç½®ãã¦ä¾åã®è§£æ±ºæ¹æ³ã Library Repository ã宣è¨ããå¿
è¦ãããã¾ããä»å㯠build-logic
å
㧠VersionCatalog ãç¨ãããããVersionCatalog ã®è¨è¿°ãå¿
è¦ã§ãã
src/
ãã£ã¬ã¯ããªä»¥ä¸ã« Plugin ãé
ç½®ãã¾ããã¯ãã¯ãããã§ã¯ãåä¸ã®æ©è½ãæ§æãæä¾ãã Plugin ã Primitive PluginãPrimitive Plugin ãã¾ã¨ãä¸è¬åãã Plugin ã Convention Plugin ã¨å¼ã¶ãã¨ã«ããããããã® Plugin ããã£ã¬ã¯ããªãåãã¦é
ç½®ãã¦ãã¾ãã
build-logic ã¢ã¸ã¥ã¼ã«ã®ä½æ
ã«ã¼ãç´ä¸ã« build-logic
ã¢ã¸ã¥ã¼ã«ãä½æãã¾ããã¢ã¸ã¥ã¼ã«ã®ä½ææ¹æ³ã¯åãã¾ããããAndroidStudioã®ã³ã³ããã¹ãã¡ãã¥ã¼ããä½æãã¦ãã¾ãã¨ãä¸è¦ãª proguard ãã¡ã¤ã«ãªã©ãçæãããããsettings.gradle.kts
ã«ã¢ã¸ã¥ã¼ã«ã¨ãã¦è¿½å ããããªã©ã®ãç¯ä»ãçºçããããããã¾ãããããã§ãã¾ãããåè¿°ã®éããbuild-logic
㯠Gradle çã«ã¯ä¸ã¤ã®ããã¸ã§ã¯ãã§ãããã settings.gradle.kts
ãé
ç½®ãã¦ãã ããã
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
// ã¢ããªããã¸ã§ã¯ãå´ã® VesionCatalog ãåç
§ãã
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
å
容ã¯é常ã®ããã¸ã§ã¯ãã® settings.gradle.kts
ã¨åæ§ã§ããContent Filtering ãªã©ã®è¨è¿°ãããã«è¡ãã¾ããä¸ã¤ä¾å¤çãªãã¨ã¯ VersionCatalog ãæ示çã«è¨è¿°ãã¦ãããã¨ã§ããæ¬æ¥ Gradle ã¯./gradle/libs.versions.toml
ã«ãã¡ã¤ã«ãé
ç½®ããã¦ããã¨èªåçã« libs
ã¨ããååã§æ¡å¼µããããã£ãçæãã¾ãããbuild-logic
ããè¦ãã° toml ãã¡ã¤ã«ã¯ ../gradle/libs.versions.toml
ã«é
ç½®ããã¦ãããããæ示çã«è¨è¿°ããå¿
è¦ãããã¾ãããã¡ãããbuild-logic
åºæã® toml ãã¡ã¤ã«ãå¥éç¨æããå ´åã¯ãã®è¨è¿°ã¯å¿
è¦ããã¾ããã
build.gradle.kts
ã«ã¤ãã¦ããé常ã®ããã¸ã§ã¯ãã¨ãªããå¤ããã¾ããã
plugins {
`kotlin-dsl`
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
implementation(libs.android.gradlePlugin)
implementation(libs.kotlin.gradlePlugin)
}
æ¡å¼µé¢æ°ã®ä½æ
build-logic
å
ã§ã¯ VersionCatalog ã®æ¡å¼µããããã£ãç¨æããã¦ããªãã£ãããimplementation()
ã api()
ã¨è¨ã£ã DSL ãç¨æããã¦ããªããããèªåã§å®è£
ããå¿
è¦ãããã¾ãã
// VersionCatalog ãåå¾ããããã®æ¡å¼µããããã£
internal val Project.libs: VersionCatalog
get() = extensions.getByType<VersionCatalogsExtension>().named("libs")
internal fun VersionCatalog.version(name: String): String {
return findVersion(name).get().requiredVersion
}
internal fun VersionCatalog.library(name: String): MinimalExternalModuleDependency {
return findLibrary(name).get().get()
}
internal fun VersionCatalog.plugin(name: String): PluginDependency {
return findPlugin(name).get().get()
}
internal fun VersionCatalog.bundle(name: String): Provider<ExternalModuleDependencyBundle> {
return findBundle(name).get()
}
// é常ã®ã©ã¤ãã©ãªã implementation ããããã®æ¡å¼µé¢æ°
internal fun DependencyHandlerScope.implementation(artifact: Project) {
add("implementation", artifact)
}
// bundle ãªã©ã implementation ããããã®æ¡å¼µé¢æ°
internal fun DependencyHandlerScope.implementation(artifact: MinimalExternalModuleDependency) {
add("implementation", artifact)
}
// é常ã®ã©ã¤ãã©ãªã api ããããã®æ¡å¼µé¢æ°
...
å ãã¦ãPlugin å
㧠Extension ã便å©ã«å©ç¨ããããã®æ¡å¼µé¢æ°ãç¨æãã¦ããã¾ããGradle 7.1 ãã BaseAppModuleExtension
㨠LibraryExtension
ã®åºåºã¯ã©ã¹ã CommonExtension
ã«å¤æ´ããã¦ãããããå®è£
ãå
±éåã§ããããã«ãªã£ã¦ãã¾ãã
// é常㮠build.gradle.kts ã® android ãããã¯ã«ç¸å½
internal fun Project.androidExt(configure: BaseExtension.() -> Unit) {
(this as ExtensionAware).extensions.configure("android", configure)
}
// Android Project ã® build.gradle.kts ã®ã¹ã³ã¼ã
internal fun Project.commonExt(configure: CommonExtension<*, *, *, *, *, *>.() -> Unit) {
val plugin = if (isApplicationProject()) BaseAppModuleExtension::class.java else LibraryExtension::class.java
(this as ExtensionAware).extensions.configure(plugin, configure)
}
// ãã® Project ã Application Project ã§ãããå¤å®
internal fun Project.isApplicationProject(): Boolean {
return project.extensions.findByType(BaseAppModuleExtension::class.java) != null
}
// ãã® Project ã Library Project ã§ãããå¤å®
internal fun Project.isLibraryProject(): Boolean {
return project.extensions.findByType(LibraryExtension::class.java) != null
}
Plugin ã®å®è£
global-android ã§ã¯æçµçã«ä»¥ä¸ã®ãã㪠Plugin æ§æã«ãªã£ã¦ãã¾ãã
Convention Plugin
cookpad.convention.android.feature
Primitive Plugin
cookpad.primitive.android.application
cookpad.primitive.android.library
cookpad.primitive.android.compose
cookpad.primitive.android.flavor
cookpad.primitive.android.lint
cookpad.primitive.detekt
cookpad.primitive.common
Primitive Plugin ã§ã¯åä¸ã®æ©è½ãæ§æãæä¾ããä»ã® Primitive Plugin ã«ä¾åãããã¨ããªãããã«ããå¿
è¦ãããã¾ããConvention Plugin 㯠Primitive Plugin ãåç
§ãããã¨ã¯ã§ãã¾ããããã®éã¯ã§ãã¾ãããã¾ããConvention Plugin å士ã®åç
§ããªãããã«æ³¨æãã¦ãã ããã
global-android ã§ã® Plugin å®è£
ä¾ãããã¤ãæãã¦ããã¾ãã
FeaturePlugin
cookpad.convention.android.feature
㯠global-android ã«å¤§éã«åå¨ãã Feature ã¢ã¸ã¥ã¼ã«ãåç
§ãã Convention Plugin ã¨ãã¦å®è£
ããã¦ãã¾ããPrimitive Plugin ãçºããã ãã§ãªããã¢ã¸ã¥ã¼ã«ã®ä¾åé¢ä¿ãã©ã¤ãã©ãªã®ä¾åãããã§å®ç¾©ãããã¨ã«ãããFeature ã¢ã¸ã¥ã¼ã«ã¨ãã¦ã®å®è£
ãå¼·å¶ãããã¨ãå¯è½ã«ãªã£ã¦ãã¾ãã
package convention
class FeaturePlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
ããããããããã // å¿
è¦ãª Primitive Plugin ãè¨è¿°
apply("cookpad.primitive.android.library")
apply("cookpad.primitive.android.compose")
apply("cookpad.primitive.android.flavor")
apply("cookpad.primitive.android.lint")
apply("cookpad.primitive.common")
apply("cookpad.primitive.detekt")
}
dependencies {
ããããããããã // Feature ã¢ã¸ã¥ã¼ã«ãä¾åãã¹ãã¢ã¸ã¥ã¼ã«ãè¨è¿°
implementation(project(":core"))
implementation(project(":entity"))
implementation(project(":usecase"))
implementation(project(":repository"))
implementation(project(":view-components"))
// å
±éã®ã©ã¤ãã©ãªãªã©ãè¨è¿°
implementation(libs.bundle("kotlin"))
implementation(libs.bundle("koin"))
implementation(libs.library("androidx-appcompat"))
implementation(libs.library("google-material"))
testImplementation(libs.bundle("test"))
}
}
}
}
LibraryPlugin
cookpad.primitive.android.library
㯠Library ã¢ã¸ã¥ã¼ã«ãå©ç¨ãã Plugin ã§ããConvention Plugin ãããåç
§ããã¦ãã¾ããããã® Plugin ã§ã¯ targetSdkVersion
ã compileSdkVersion
ããã®ä»æ§ã
ãªãã«ããªãã·ã§ã³ãªã©ãè¨è¿°ãã¦ãã¾ããCommonExtension
ãå©ç¨ãã¦è¨å®ã§ããé
ç®ã¯ configureAndroid
ã¨ããé¢æ°ã«åãåºããApplicationPlugin
ã¨å
±éåãã¦ãã¾ãã
package primitive
class LibraryPlugin: Plugin<Project> {
override fun apply(target: Project) {
with(target) {
// LibraryPlugin 㯠"com.android.library" ã®ã¿ã apply
// ãã®ä»ã®æ©è½ãå¿
è¦ãªå ´åã¯å¥ã® Plugin ãä½æãã
pluginManager.apply("com.android.library")
extensions.configure<LibraryExtension> {
// Android Project ã«å¿
è¦ãªè¨å®
configureAndroid(this)
defaultConfig.targetSdk = libs.version("targetSdk").toInt()
buildFeatures.viewBinding = true
buildFeatures.buildConfig = true
}
}
}
}
internal fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) {
commonExtension.apply {
defaultConfig {
ããããããã// global-android ã§ã¯ minSdkVersion ã compileSdkVersion ãªã©ã VersionCatalog ã«è¨è¿°ãã¦ãã
minSdk = libs.version("minSdk").toInt()
compileSdk = libs.version("compileSdk").toInt()
}
testOptions {
animationsDisabled = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
encoding = "UTF-8"
}
packaging {
resources.excludes.addAll(
listOf(...)
)
}
}
}
FlavorPlugin
cookpad.primitive.android.flavor
㯠Build Flavor ãè¨å®ãã Plugin ã§ããå
æ¥ãã®ããã°ã«ãæ稿4 ãããéãã global-android ã§ã¯æ¥æ¬ã®ã³ã¼ããã¼ã¹ãçµ±åããéã« applicationId ãªã©ã®é½åä¸ã Build Flavor ãç¨ãã¦æ¥æ¬åããã«ããã°ãã¼ãã«åããã«ãã«åãæ¿ããæ¹å¼ãæ¡ç¨ãã¦ãã¾ãããããã°ç¨ãGlobal Productionç¨ãJP Production ç¨ãªã©ã¨è¤æ°ã®ãã«ãè¨å®ãåã¢ã¸ã¥ã¼ã«ã«è¨è¼ããã®ã¯æ¥µãã¦éå¹çã§ãããããPlugin ã«çºããããã«ãã¦ãã¾ãã
package primitive
class FlavorPlugin: Plugin<Project> {
override fun apply(target: Project) {
with(target) {
ãã // Build Flavor ãè¨å®
configureFlavors()
configureVariantFilter()
}
}
}
private fun Project.configureFlavors() {
androidExt {
// ã°ãã¼ãã«ã¨æ¥æ¬ã§ãã¼ã¸ã§ãã³ã°ãç°ãªããããããããã®ãã¼ã¸ã§ã³ãåå¾
val globalVersion = GlobalVersion.build(project)
val jpVersion = JpVersion.build(project)
flavorDimensions(Dimension.REGION, Dimension.DEPLOYMENT_TRACK)
productFlavors {
// Global ãªã¼ã¸ã§ã³ãè¨å®
create("global") {
dimension = Dimension.REGION
isDefault = true
}
// JP ãªã¼ã¸ã§ã³ãè¨å®
create("jp") {
dimension = Dimension.REGION
extra.apply {
set(ExtraKey.ApplicationId, "com.cookpad.android.activities")
set(ExtraKey.VersionCode, jpVersion.getVersionCode(project))
set(ExtraKey.VersionName, jpVersion.getVersionName(project))
}
}
// Production ãã©ãã¯ãè¨å®
create("production") {
dimension = Dimension.DEPLOYMENT_TRACK
isDefault = true
}
...
}
productFlavors.all {
if (isApplicationProject()) {
if (extra.has(ExtraKey.ApplicationId)) {
applicationId = extra[ExtraKey.ApplicationId].toString()
}
if (extra.has(ExtraKey.VersionCode)) {
versionCode = extra[ExtraKey.VersionCode].toString().toInt()
}
if (extra.has(ExtraKey.VersionName)) {
versionName = extra[ExtraKey.VersionName].toString()
}
...
}
}
}
}
private fun Project.configureVariantFilter() {
androidExt {
variantFilter {
if (flavors.map { it.name }.contains(Flavor.DEVELOPERS_SANDBOX)) {
ignore = true
}
}
}
}
Tips: KTS ãã¡ã¤ã«ãç¨ã㦠Convention Plugins ãä½ã
ä»å㯠org.gradle.Plugin
ãå®è£
ããææ³ãã¨ã£ã¦ãã¾ããã*.gradle.kts
ãã¡ã¤ã«ãç¨ã㦠Convention Plugins ãä½ãæ¹æ³ãåå¨ãã¾ãã
å®è£
ã¯é常ã«ç°¡å㧠my-convention-plugin.gradle.kts
ã¨è¨ã£ããã¡ã¤ã«ã build-logic
å
ã® src/
ãã£ã¬ã¯ããªã«é
ç½®ããã ãã§ããsrc/
å
ã«é
ç½®ããã *.gradle.kts
ãã¡ã¤ã«ã¯ Plugin ã¯ã©ã¹ã«ããªã³ã³ãã¤ã«ãããä¾ã®å ´å㯠my-convention-plugin
ã®é¨åã key ã¨ãã¦ä½¿ããã¨ãã§ããããã«ãªãã¾ããå ãã¦ãå¾è¿°ãã Plugin ã®ç»é²ãä¸è¦ã ã£ãããsettings.gradle.kts
ã®ãã¸ãã¯ãå
±éåã㦠Convention Plugins ã«ãããã¨ãã§ããããªã©ãæ§ã
ãªã¡ãªãããåå¨ãã¾ãã
é常ã®ãã«ããã¸ãã¯å
±éåã«ã¯é£½ããï¼ã¨ããæ¹ã¯ãkotlinx-rpc ã®ãªãã¸ããªã®ä¸ã§å
·ä½çãªå®è£
ä¾ãè¦ãã¾ãã®ã§ããã²åèã«ãã¦ãã ããã
github.com
Plugin ã®ç»é²
ä½æãã Plugin ã¯ã¹ã¿ã³ãã¢ãã¼ã³ã® JAR ãã¡ã¤ã«ã¨ãã¦ããªã³ã³ãã¤ã«ããã Binary Plugin ã§ãããããã¢ããªããã¸ã§ã¯ãããåç
§ããããã«ã¯ Gradle ã« Plugin ãç»é²ãã¦ãããå¿
è¦ãããã¾ãã
åè¿°ãã build-logic
ã® build.gradle.kts
å
ã§ä»¥ä¸ã®ããã«ã㦠Plugin ãç»é²ãã¾ã
gradlePlugin {
plugins {
// Convention Plugins
register("ConventionFeature") {
id = "cookpad.convention.android.feature"
implementationClass = "convention.FeaturePlugin"
}
// Primitive Plugins
register("PrimitiveApplication") {
id = "cookpad.primitive.android.application"
implementationClass = "primitive.ApplicationPlugin"
}
register("PrimitiveLibrary") {
id = "cookpad.primitive.android.library"
implementationClass = "primitive.LibraryPlugin"
}
...
}
}
Include Build ã®è¨å®
以ä¸ã§ build-logic
ã¢ã¸ã¥ã¼ã«ã®è¨è¿°ã¯ã»ã¼å®äºãããããæå¾ã«ã¢ããªããã¸ã§ã¯ãå´ã§ build-logic
ã include build ã¨ãã¦æå®ããå ãã¦ããã¾ã§è¨è¿°ãã Plugin ã«å®è£
ã移ãã¦ããã¾ãã
include build ã¨ãã¦æå®ããæ¹æ³ã¯ç°¡åã§ãã¢ããªããã¸ã§ã¯ãå´ã® settings.gradle.kts
ã«ä»¥ä¸ã®ããã«å¤æ´ãå ããã ãã§ããééã£ã¦é常ã®ã¢ã¸ã¥ã¼ã«ã¨åæ§ã« include
ããªãããã«æ°ãã¤ãã¦ãã ããã
pluginManagement {
includeBuild("build-logic") // build-logic ã¢ã¸ã¥ã¼ã«ã include build ãã
repositories {
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
}
}
æå¾ã«åã¢ã¸ã¥ã¼ã«ã® build.gradle
ã«è¨è¿°ãã¦ãããã«ããã¸ãã¯ã Plugin ã«ç§»è¡ãã¾ãã以ä¸ã®ç»åã¯ããã¢ã¸ã¥ã¼ã«ã® build.gradle
ã«ãã£ãè¨è¿°ã Plugin ã«ç§»è¡ããä¾ã§ãããµã¤ãºã®é¢ä¿ä¸ãç¹ã«è¤éãªãã¸ãã¯ãè¨è¿°ããã¦ããªãã¢ã¸ã¥ã¼ã«ã® build.gradle
ãä¾ã¨ãã¦ãã¾ãããbuild variant ã build flavor ãè¨è¿°ãã¦ããã¢ã¸ã¥ã¼ã«ã®å ´åãããã«å¤ãã®è¡æ°ãåæ¸ãããã¨ãã§ãã¾ãããã»ã¼å
¨ã¦ã®è¨è¿°ã Plugin ãç¨ãã¦å
±éåã§ãã¦ãããããæçµç㪠build.gradle.kts
ã®ã¢ã¸ã¥ã¼ã«åºæã®è¨è¿°ã¯ namespace
ã®ã¿ã¨ãªã£ã¦ãã¾ãã
ããã¢ã¸ã¥ã¼ã«ã® build.gradle.kts
ã¾ã¨ã
æçµçãªããã¸ã§ã¯ãå
¨ä½ã® build.gradle.kts
ã®è¡æ°ã¯ä»¥ä¸ã®ã¨ããã§ãã
$ find . -type f -name '*.gradle.kts' -exec wc -l {} + | tail -n1 # å
¨ä½ã®è¡æ°
1823 total
Gradle Composite Build + Convention Plugins ãç¨ãããã«ããã¸ãã¯ã®å
±éåã«ãããè¨è¿°éãååè¿ãåæ¸ãããã¨ãå¯è½ã¨ãªãã¾ããã
ãã®æ¹åã¯ç§ã One Experience ã®éçºã«æºããéã«ä¸çªæåã«è¡ã£ããã®ã§ããåè¿°ãã Build Flavor ã®è¨å®ã«å ããCIããªãªã¼ã¹ãªã©ã³ã¼ããã¼ã¹ãçµ±åãããã¨ã§ããã¸ã§ã¯ãã¨ãã¦ãããè¤éãªãã«ããã¸ãã¯ãæããããå¾ãªããªãã ããã¨äºæ³ããæ¬æ ¼çãªéçºã«å
¥ãåã«ä»åã®æ¹åãè¡ãã¾ãããå®éãããã¸ã§ã¯ããé²ããã«ããã£ã¦ä»åã話ããããããªè¤éãªãã¸ãã¯ã幾度ã¨ãªã追å ããã¦ãããä»åã®æ¹åããããã®ãã¸ãã¯ãããç°¡æ½ãã¤ç°¡æã«å°å
¥ãããã¨ãã§ããç¶æ
ã¨ãã¦ãã¾ããglobal-android ã®ãããªå·¨å¤§ãªããã¸ã§ã¯ãã§ãã«ããã¸ãã¯ã«æãå
¥ããã®ã¯é常ã«å°é£ã§ããããä»åã®æ¹åãéçºè
èªèº«ã®ä½é¨ãå¼ãã¦ã¯ One Experience ããã¸ã§ã¯ãå
¨ä½ã®é²è¡ã«ãåä¸ã«ã大ããè²¢ç®ãããã¨ãã§ããã¨èªè² ãã¦ãã¾ãã