├── .config ├── dependencies-android-biz.toml ├── dependencies-android-common.toml └── dependencies-shared-common.toml ├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── jady │ │ │ └── app │ │ │ ├── MainActivity.kt │ │ │ ├── MainApplication.kt │ │ │ └── ui │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Theme.kt │ │ │ └── Type.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── jady │ └── app │ └── ExampleUnitTest.kt ├── build.gradle.kts ├── common └── common │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── res │ └── values │ ├── strings.xml │ └── styles.xml ├── framework └── utils │ ├── .gitignore │ ├── build.gradle.kts │ ├── proguard-rules.pro │ └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── jady │ │ └── utils │ │ └── Contexts.kt │ └── test │ └── java │ └── com │ └── jady │ └── utils │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── plugins ├── .gitignore ├── config-plugin │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── jady │ │ └── lib │ │ └── config │ │ ├── CommonConfigExtension.kt │ │ └── ConfigPlugin.kt ├── gradle.properties └── settings.gradle.kts └── settings.gradle.kts /.config/dependencies-android-biz.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | # build config 3 | minSdk = "21" 4 | targetSdk = "35" 5 | 6 | [libraries] 7 | 8 | [plugins] 9 | 10 | [bundles] 11 | -------------------------------------------------------------------------------- /.config/dependencies-android-common.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | # build config 3 | compileSdk = "34" 4 | java-major = "17" 5 | java = "17" 6 | # billing 7 | google-billing = "7.0.0" 8 | # plugin 9 | # https://maven.google.com/web/index.html?q=build#com.android.tools.build:gradle 10 | android-plugin = "8.5.0" 11 | android-tools-common = "31.5.1" 12 | google-services = "4.4.2" 13 | # https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md 14 | spotless = "7.0.0.BETA1" 15 | # androidx 16 | androidx-appcompat = "1.7.0" 17 | androidx-annotation = "1.8.1" 18 | androidx-lifecycle-common = "2.8.3" 19 | androidx-core = "1.13.1" 20 | androidx-collection = "1.4.1" 21 | androidx-fragment = "1.8.1" 22 | androidx-room = "2.6.1" 23 | androidx-hilt-compose = "1.2.0" 24 | androidx-cardview = "1.0.0" 25 | androidx-recyclerview = "1.3.2" 26 | androidx-swiperefreshlayout = "1.1.0" 27 | androidx-viewpager = "1.1.0-alpha01" 28 | androidx-viewpager2 = "1.1.0" 29 | androidx-transition-ktx = "1.5.0" 30 | androidx-media2 = "1.3.0" 31 | androidx-media3 = "1.3.1" 32 | androidx-multidex = "2.0.1" 33 | androidx-exifinterface = "1.3.7" 34 | androidx-localbroadcastmanager = "1.1.0" 35 | androidx-legacy-support-core-utils = "1.0.0" 36 | androidx-sqlite = "2.4.0" 37 | androidx-activity-compose = "1.9.0" 38 | exoplayer = "2.19.1" 39 | # firebase 40 | firebase-analytics = "22.0.1" 41 | firebase-messaging = "24.0.0" 42 | auto-service = "1.0.1" 43 | # appsflyer 44 | appsflyer-core = "6.9.0" 45 | appsflyer-google-referrer = "2.2" 46 | # ui 47 | androidx-constraintlayout = "2.1.4" 48 | material = "1.12.0" 49 | # other official library 50 | hilt = "2.43.2" 51 | # test 52 | junit = "4.13.2" 53 | androidx-test-core = "1.6.1" 54 | androidx-test-runner = "1.6.1" 55 | androidx-test-rules = "1.6.1" 56 | androidx-test-orchestrator = "1.5.0" 57 | androidx-test-ext = "1.2.1" 58 | androidx-test-espresso = "3.6.1" 59 | truth = "1.1.3" 60 | # third party 61 | mmkv = "1.2.14" 62 | hilt-compose-navigation-factory = "1.2.0" 63 | coil = "2.6.0" 64 | guava = "31.1-android" 65 | fastjson = "1.2.83" 66 | commons-io = "2.15.1" 67 | okhttp = "4.10.0" 68 | 69 | [libraries] 70 | # androidx 71 | androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } 72 | androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime", version.ref = "androidx-lifecycle-common" } 73 | androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle-common" } 74 | androidx-lifecycle-livedata-ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidx-lifecycle-common" } 75 | androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidx-lifecycle-common" } 76 | androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle-common" } 77 | androidx-lifecycle-viewmodel-savedstate = { module = "androidx.lifecycle:lifecycle-viewmodel-savedstate", version.ref = "androidx-lifecycle-common" } 78 | androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle-common" } 79 | androidx-lifecycle-reactivestreams-ktx = { module = "androidx.lifecycle:lifecycle-reactivestreams-ktx", version.ref = "androidx-lifecycle-common" } 80 | androidx-lifecycle-service = { module = "androidx.lifecycle:lifecycle-service", version.ref = "androidx-lifecycle-common" } 81 | androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "androidx-lifecycle-common" } 82 | androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" } 83 | androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } 84 | androidx-collection = { module = "androidx.collection:collection", version.ref = "androidx-collection" } 85 | androidx-collection-ktx = { module = "androidx.collection:collection-ktx", version.ref = "androidx-collection" } 86 | androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx-fragment" } 87 | androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "androidx-room" } 88 | androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" } 89 | androidx-cardview = { module = "androidx.cardview:cardview", version.ref = "androidx-cardview" } 90 | androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "androidx-recyclerview" } 91 | androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" } 92 | androidx-viewpager = { module = "androidx.viewpager:viewpager", version.ref = "androidx-viewpager" } 93 | androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "androidx-viewpager2" } 94 | androidx-transition-ktx = { module = "androidx.transition:transition-ktx", version.ref = "androidx-transition-ktx" } 95 | androidx-media2 = { module = "androidx.media2:media2-session", version.ref = "androidx-media2" } 96 | androidx-media3-session = { module = "androidx.media3:media3-session", version.ref = "androidx-media3" } 97 | androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "androidx-media3" } 98 | androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "androidx-media3" } 99 | androidx-media3-datasource-cronet = { module = "androidx.media3:media3-datasource-cronet", version.ref = "androidx-media3" } 100 | androidx-media3-datasource-okhttp = { module = "androidx.media3:media3-datasource-okhttp", version.ref = "androidx-media3" } 101 | androidx-multidex = { module = "androidx.multidex:multidex", version.ref = "androidx-multidex" } 102 | androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "androidx-exifinterface" } 103 | androidx-localbroadcastmanager = { module = "androidx.localbroadcastmanager:localbroadcastmanager", version.ref = "androidx-localbroadcastmanager" } 104 | androidx-legacy-support-core-utils = { module = "androidx.legacy:legacy-support-core-utils", version.ref = "androidx-legacy-support-core-utils" } 105 | androidx-sqlite = { module = "androidx.sqlite:sqlite", version.ref = "androidx-sqlite" } 106 | androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } 107 | # Firebase 108 | firebase-analytics = { module = "com.google.firebase:firebase-analytics", version.ref = "firebase-analytics" } 109 | firebase-messaging = { module = "com.google.firebase:firebase-messaging", version.ref = "firebase-messaging" } 110 | # ExoPlayer 111 | exoplayer-core = { module = "com.google.android.exoplayer:exoplayer-core", version.ref = "exoplayer" } 112 | exoplayer-ui = { module = "com.google.android.exoplayer:exoplayer-ui", version.ref = "exoplayer" } 113 | exoplayer-extension-mediasession = { module = "com.google.android.exoplayer:extension-mediasession", version.ref = "exoplayer" } 114 | exoplayer-extension-cronet = { module = "com.google.android.exoplayer:extension-cronet", version.ref = "exoplayer" } 115 | # ui 116 | constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" } 117 | material = { module = "com.google.android.material:material", version.ref = "material" } 118 | # billing 119 | google-billing = { module = "com.android.billingclient:billing-ktx", version.ref = "google-billing" } 120 | # plugin dependencies 121 | plugin-source-android = { module = "com.android.tools.build:gradle", version.ref = "android-plugin" } 122 | plugin-source-android-common = { module = "com.android.tools:common", version.ref = "android-tools-common" } 123 | plugin-source-android-ddmlib = { module = "com.android.tools.ddms:ddmlib", version.ref = "android-tools-common" } 124 | plugin-source-spotless = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" } 125 | auto-service = { module = "com.google.auto.service:auto-service", version.ref = "auto-service" } 126 | # hilt 127 | hilt-runtime = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } 128 | hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } 129 | hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "androidx-hilt-compose" } 130 | hilt-compose-navigation-factory = { module = "net.lachlanmckee:hilt-compose-navigation-factory", version.ref = "hilt-compose-navigation-factory" } 131 | hilt-compose-navigation-factory-compiler = { module = "net.lachlanmckee:hilt-compose-navigation-factory-compiler", version.ref = "hilt-compose-navigation-factory" } 132 | # test 133 | junit = { module = "junit:junit", version.ref = "junit" } 134 | androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-ext" } 135 | androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test-core" } 136 | androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" } 137 | androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-test-rules" } 138 | androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "androidx-fragment" } 139 | espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-test-espresso" } 140 | espresso-intents = { module = "androidx.test.espresso:espresso-intents", version.ref = "androidx-test-espresso" } 141 | espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-test-espresso" } 142 | androidx-orchestrator = { module = "androidx.test:orchestrator", version.ref = "androidx-test-orchestrator" } 143 | hilt-androidTesting = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" } 144 | truth = { module = "com.google.truth:truth", version.ref = "truth" } 145 | # third party 146 | mmkv = { module = "com.tencent:mmkv-static", version.ref = "mmkv" } 147 | coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } 148 | guava = { module = "com.google.guava:guava", version.ref = "guava" } 149 | fastjson = { module = "com.alibaba:fastjson", version.ref = "fastjson" } 150 | commons-io = { module = "commons-io:commons-io", version.ref = "commons-io" } 151 | # appsflyer 152 | appsflyer-core = { module = "com.appsflyer:af-android-sdk", version.ref = "appsflyer-core" } 153 | appsflyer-google-referrer = { module = "com.android.installreferrer:installreferrer", version.ref = "appsflyer-google-referrer" } 154 | 155 | [plugins] 156 | android-application = { id = "com.android.application", version.ref = "android-plugin" } 157 | android-library = { id = "com.android.library", version.ref = "android-plugin" } 158 | java-library = { id = "org.gradle.java-library" } 159 | spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } 160 | hilt-android = { id = "dagger.hilt.android.plugin", version.ref = "hilt" } 161 | google-services = { id = "com.google.gms.google-services", version.ref = "google-services" } 162 | 163 | [bundles] 164 | hilt-navigation = ["hilt-navigation-compose", "hilt-compose-navigation-factory"] 165 | hilt-compiler = ["hilt-compiler", "hilt-compose-navigation-factory-compiler"] 166 | -------------------------------------------------------------------------------- /.config/dependencies-shared-common.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | config-plugin = "0.1.30" 3 | # https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin 4 | # https://github.com/JetBrains/kotlin/releases 5 | kotlin = "2.0.10" 6 | # https://plugins.gradle.org/m2/org/gradle/kotlin/gradle-kotlin-dsl-plugins/,通过这里的 pom 文件查看对应的 kotlin 版本 7 | # kotlin-dsl 4.1.3 -> kotlin 1.9.10 8 | # kotlin-dsl 4.2.1 -> kotlin 1.9.20 9 | # kotlin-dsl 4.3.0 -> kotlin 1.9.22 10 | # kotlin-dsl 4.4.0 -> kotlin 1.9.23 11 | # kotlin-dsl 4.5.0 -> kotlin 1.9.24 12 | # https://plugins.gradle.org/plugin/org.gradle.kotlin.kotlin-dsl 13 | # https://github.com/gradle/gradle/blob/master/build-logic/kotlin-dsl/build.gradle.kts 14 | kotlin-dsl = "4.5.0" 15 | # https://github.com/Kotlin/kotlinx.serialization/releases 16 | kotlin-serialization = "1.7.0" 17 | # https://github.com/Kotlin/kotlinx-datetime/releases 18 | kotlin-datetime = "0.6.0" 19 | # https://github.com/Kotlin/kotlinx.coroutines/releases 20 | kotlin-coroutines = "1.9.0-RC" 21 | # 主版本:https://github.com/ktorio/ktor/releases 22 | # wasm 版本:https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental/io/ktor/ktor-client/ 23 | ktor = "2.3.12" 24 | # compose 25 | # https://maven.google.com/web/index.html?q=bom#androidx.compose:compose-bom 26 | compose-bom = "2024.06.00" 27 | # https://maven.google.com/web/index.html?q=compose#androidx.compose.runtime:runtime 28 | compose-common = "1.6.8" 29 | # https://maven.google.com/web/index.html?q=compose#androidx.compose.material3:material3 30 | compose-material3 = "1.2.1" 31 | # https://maven.google.com/web/index.html?q=compiler#androidx.compose.compiler:compiler 32 | compose-androidx-compiler = "1.5.14" 33 | # https://github.com/JetBrains/compose-multiplatform/releases 34 | # https://central.sonatype.com/artifact/org.jetbrains.compose/org.jetbrains.compose.gradle.plugin/versions 35 | # 跟 kotlin 兼容性列表:https://github.com/JetBrains/compose-multiplatform/blob/master/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatibility.kt 36 | compose-plugin = "1.6.11" 37 | # https://maven.google.com/web/index.html?q=paging#androidx.paging:paging-compose 38 | compose-paging = "3.3.1" 39 | # https://maven.google.com/web/index.html?q=navigation#androidx.navigation:navigation-common-ktx 40 | compose-navigation = "2.7.7" 41 | # https://github.com/google/accompanist/releases 42 | accompanist = "0.34.0" 43 | # https://maven.google.com/web/index.html?q=constraintlayout#androidx.constraintlayout:constraintlayout-compose 44 | compose-constraintlayout = "1.0.1" 45 | # https://maven.google.com/web/index.html?q=annotation#androidx.annotation:annotation 46 | androidx-annotation = "1.8.1" 47 | # ksp 版本列表 https://github.com/google/ksp/releases?page=1 48 | ksp = "2.0.10-1.0.24" 49 | # plugins 50 | # https://central.sonatype.com/artifact/com.vanniktech.maven.publish/com.vanniktech.maven.publish.gradle.plugin 51 | # https://github.com/vanniktech/gradle-maven-publish-plugin/releases 52 | maven-publish = "0.29.0" 53 | # https://plugins.gradle.org/plugin/com.gradle.plugin-publish 54 | gradle-publish = "1.2.1" 55 | # https://github.com/cashapp/molecule/releases 56 | molecule = "2.0.0" 57 | # koin https://insert-koin.io/docs/setup/koin 58 | # https://mvnrepository.com/artifact/io.insert-koin/koin-core 59 | koin = "4.0.0-RC1" 60 | koin-compose = "4.0.0-RC1" 61 | koin-ktor = "4.0.0-RC1" 62 | # https://mvnrepository.com/artifact/io.insert-koin/koin-ksp-compiler 63 | # https://mvnrepository.com/artifact/io.insert-koin/koin-annotations 64 | koin-annotations = "1.4.0-RC3" 65 | # https://kermit.touchlab.co/docs/ 66 | # https://search.maven.org/search?q=g:co.touchlab%20a:kermit 67 | kermit = "2.0.3" 68 | # https://github.com/cashapp/sqldelight/releases 69 | # https://cashapp.github.io/sqldelight/2.0.0/ 70 | sqldelight = "2.0.2" 71 | # https://github.com/russhwolf/multiplatform-settings/releases 72 | multiplatform-settings = "1.1.1" 73 | # https://github.com/ctripcorp/mmkv-kotlin/releases 74 | mmkv = "1.2.12" 75 | # https://square.github.io/okio/changelog/ 76 | okio = "3.9.0" 77 | # https://github.com/ltttttttttttt/VirtualReflection/releases 78 | virtual-reflection = "1.2.1" 79 | # https://github.com/Skeptick/libres 80 | libres = "1.2.2" 81 | # https://github.com/touchlab/Stately/releases 82 | stately = "2.0.7" 83 | 84 | [libraries] 85 | # plugin source 86 | plugin-source-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } 87 | plugin-source-compose = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose-plugin" } 88 | plugin-source-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" } 89 | plugin-source-maven-publish = { module = "com.vanniktech.maven.publish:com.vanniktech.maven.publish.gradle.plugin", version.ref = "maven-publish" } 90 | plugin-source-kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } 91 | # kotlin 92 | kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } 93 | kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } 94 | kotlin-script-runtime = { module = "org.jetbrains.kotlin:kotlin-script-runtime", version.ref = "kotlin" } 95 | kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" } 96 | kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlin-datetime" } 97 | kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 98 | # kotin coroutines 99 | kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } 100 | kotlin-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlin-coroutines" } 101 | kotlin-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlin-coroutines" } 102 | # androidx 103 | androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" } 104 | # ktor 105 | # 目前 maven 发布插件不支持 bom, 暂停使用 106 | ktor-bom = { module = "io.ktor:ktor-bom", version.ref = "ktor" } 107 | ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } 108 | ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } 109 | ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } 110 | ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" } 111 | ktor-client-auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" } 112 | ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } 113 | ktor-client-encoding = { module = "io.ktor:ktor-client-encoding", version.ref = "ktor" } 114 | ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } 115 | ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } 116 | ktor-client-resources = { module = "io.ktor:ktor-client-resources", version.ref = "ktor" } 117 | ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" } 118 | # ios 119 | ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } 120 | # js 121 | ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } 122 | # macOS / Windows / Linux 123 | ktor-client-curl = { module = "io.ktor:ktor-client-curl", version.ref = "ktor" } 124 | ktor-client-jvm = { module = "io.ktor:ktor-client-jvm", version.ref = "ktor" } 125 | # koin 126 | koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } 127 | koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin-compose" } 128 | koin-ktor = { module = "io.insert-koin:koin-ktor", version.ref = "koin-ktor" } 129 | koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koin-annotations" } 130 | koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" } 131 | koin-ksp-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koin-annotations" } 132 | # kermit 133 | kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } 134 | # sqldelight 135 | sqldelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } 136 | sqldelight-native = { module = "app.cash.sqldelight:native-driver", version.ref = "sqldelight" } 137 | sqldelight-sqlite = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } 138 | sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" } 139 | sqldelight-paging = { module = "app.cash.sqldelight:androidx-paging3-extensions", version.ref = "sqldelight" } 140 | sqldelight-primitive = { module = "app.cash.sqldelight:primitive-adapters", version.ref = "sqldelight" } 141 | # multiplatform-settings 142 | multiplatform-settings-core = { module = "com.russhwolf:multiplatform-settings", version.ref = "multiplatform-settings" } 143 | # mmkv kotlin 144 | mmkv = { module = "com.ctrip.flight.mmkv:mmkv-kotlin", version.ref = "mmkv" } 145 | # compose 146 | # bom platform mapping: https://developer.android.com/jetpack/compose/bom/bom-mapping 147 | # 目前 maven 发布插件不支持 bom, 暂停使用 148 | compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose-bom" } 149 | compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose-common" } 150 | compose-animation-android = { module = "androidx.compose.animation:animation-android", version.ref = "compose-common" } 151 | compose-animation-core = { module = "androidx.compose.animation:animation-core", version.ref = "compose-common" } 152 | compose-animation-core-android = { module = "androidx.compose.animation:animation-core-android", version.ref = "compose-common" } 153 | compose-animation-graphics = { module = "androidx.compose.animation:animation-graphics", version.ref = "compose-common" } 154 | compose-animation-graphics-android = { module = "androidx.compose.animation:animation-graphics-android", version.ref = "compose-common" } 155 | compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose-common" } 156 | compose-foundation-android = { module = "androidx.compose.foundation:foundation-android", version.ref = "compose-common" } 157 | compose-foundation-layout = { module = "androidx.compose.foundation:foundation-layout", version.ref = "compose-common" } 158 | compose-foundation-layout-android = { module = "androidx.compose.foundation:foundation-layout-android", version.ref = "compose-common" } 159 | compose-material = { module = "androidx.compose.material:material", version.ref = "compose-common" } 160 | compose-material-android = { module = "androidx.compose.material:material-android", version.ref = "compose-common" } 161 | compose-material-icons-core = { module = "androidx.compose.material:material-icons-core", version.ref = "compose-common" } 162 | compose-material-icons-core-android = { module = "androidx.compose.material:material-icons-core-android", version.ref = "compose-common" } 163 | compose-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose-common" } 164 | compose-material-icons-extended-android = { module = "androidx.compose.material:material-icons-extended-android", version.ref = "compose-common" } 165 | compose-material-ripple = { module = "androidx.compose.material:material-ripple", version.ref = "compose-common" } 166 | compose-material-ripple-android = { module = "androidx.compose.material:material-ripple-android", version.ref = "compose-common" } 167 | compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material3" } 168 | compose-material3-window-size = { module = "androidx.compose.material3:material3-window-size-class", version.ref = "compose-material3" } 169 | compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose-common" } 170 | compose-runtime-android = { module = "androidx.compose.runtime:runtime-android", version.ref = "compose-common" } 171 | compose-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata", version.ref = "compose-common" } 172 | compose-runtime-rxjava2 = { module = "androidx.compose.runtime:runtime-rxjava2", version.ref = "compose-common" } 173 | compose-runtime-rxjava3 = { module = "androidx.compose.runtime:runtime-rxjava3", version.ref = "compose-common" } 174 | compose-runtime-saveable = { module = "androidx.compose.runtime:runtime-saveable", version.ref = "compose-common" } 175 | compose-runtime-saveable-android = { module = "androidx.compose.runtime:runtime-saveable-android", version.ref = "compose-common" } 176 | compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose-common" } 177 | compose-ui-android = { module = "androidx.compose.ui:ui-android", version.ref = "compose-common" } 178 | compose-ui-android-stubs = { module = "androidx.compose.ui:ui-android-stubs", version.ref = "compose-common" } 179 | compose-ui-geometry = { module = "androidx.compose.ui:ui-geometry", version.ref = "compose-common" } 180 | compose-ui-geometry-android = { module = "androidx.compose.ui:ui-geometry-android", version.ref = "compose-common" } 181 | compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "compose-common" } 182 | compose-ui-graphics-android = { module = "androidx.compose.ui:ui-graphics-android", version.ref = "compose-common" } 183 | compose-ui-test = { module = "androidx.compose.ui:ui-test", version.ref = "compose-common" } 184 | compose-ui-test-android = { module = "androidx.compose.ui:ui-test-android", version.ref = "compose-common" } 185 | compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "compose-common" } 186 | compose-ui-test-junit4-android = { module = "androidx.compose.ui:ui-test-junit4-android", version.ref = "compose-common" } 187 | compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "compose-common" } 188 | compose-ui-text = { module = "androidx.compose.ui:ui-text", version.ref = "compose-common" } 189 | compose-ui-text-android = { module = "androidx.compose.ui:ui-text-android", version.ref = "compose-common" } 190 | compose-ui-text-google-fonts = { module = "androidx.compose.ui:ui-text-google-fonts", version.ref = "compose-common" } 191 | compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose-common" } 192 | compose-ui-tooling-android = { module = "androidx.compose.ui:ui-tooling-android", version.ref = "compose-common" } 193 | compose-ui-tooling-data = { module = "androidx.compose.ui:ui-tooling-data", version.ref = "compose-common" } 194 | compose-ui-tooling-data-android = { module = "androidx.compose.ui:ui-tooling-data-android", version.ref = "compose-common" } 195 | compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose-common" } 196 | compose-ui-tooling-preview-android = { module = "androidx.compose.ui:ui-tooling-preview-android", version.ref = "compose-common" } 197 | compose-ui-unit = { module = "androidx.compose.ui:ui-unit", version.ref = "compose-common" } 198 | compose-ui-unit-android = { module = "androidx.compose.ui:ui-unit-android", version.ref = "compose-common" } 199 | compose-ui-util = { module = "androidx.compose.ui:ui-util", version.ref = "compose-common" } 200 | compose-ui-util-android = { module = "androidx.compose.ui:ui-util-android", version.ref = "compose-common" } 201 | compose-ui-viewbinding = { module = "androidx.compose.ui:ui-viewbinding", version.ref = "compose-common" } 202 | # other library for compose 203 | compose-paging = { module = "androidx.paging:paging-compose", version.ref = "compose-paging" } 204 | compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "compose-navigation" } 205 | compose-flowLayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" } 206 | compose-constraintlayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "compose-constraintlayout" } 207 | compose-navigation-animiaton = { module = "com.google.accompanist:accompanist-navigation-animation", version.ref = "accompanist" } 208 | compose-placeholder = { module = "com.google.accompanist:accompanist-placeholder-material", version.ref = "accompanist" } 209 | compose-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } 210 | # ksp 211 | ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } 212 | # molecule 213 | molecule = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" } 214 | okio = { module = "com.squareup.okio:okio", version.ref = "okio" } 215 | virtual-reflection = { module = "com.github.ltttttttttttt:VirtualReflection", version.ref = "virtual-reflection" } 216 | # libres 217 | plugin-source-libres = { module = "io.github.skeptick.libres:gradle-plugin", version.ref = "libres" } 218 | libres-compose = { module = "io.github.skeptick.libres:libres-compose", version.ref = "libres" } 219 | stately-common = { module = "co.touchlab:stately-common", version.ref = "stately" } 220 | stately-concurrent-collections = { module = "co.touchlab:stately-concurrent-collections", version.ref = "stately" } 221 | 222 | [plugins] 223 | config-plugin = { id = "io.github.jadyli.config-plugin", version.ref = "config-plugin" } 224 | # kotlin 225 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 226 | kotlin-dsl = { id = "org.gradle.kotlin.kotlin-dsl", version.ref = "kotlin-dsl" } 227 | kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } 228 | kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } 229 | kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } 230 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 231 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 232 | kotlin-native-cocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" } 233 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } 234 | jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } 235 | ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } 236 | gradle-publish = { id = "com.gradle.plugin-publish", version.ref = "gradle-publish" } 237 | maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "maven-publish" } 238 | libres = { id = "io.github.skeptick.libres", version.ref = "libres" } 239 | 240 | [bundles] 241 | test = ["compose-ui-test-junit4", "compose-ui-test-manifest"] 242 | compose-core = ["compose-ui-tooling", "compose-material", "compose-material3"] 243 | compose-navigation = ["compose-navigation", "compose-navigation-animiaton"] 244 | compose-jetpack = ["compose-paging"] 245 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | /local-repo/ 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [中文版](https://juejin.cn/post/7041958178682044447) 2 | 3 | Most projects today are structured with multiple modules. Every time a new module is added, it's quite bothersome to copy and paste common extension attributes such as `minSdk`, `targetSdk` etc. A better approach would be to manage them through a common plugin. 4 | 5 | ## 1 Plugin Usage 6 | 7 | Refer to the build configuration files in this repository for plugin usage. 8 | 9 | ### 1.1 Adding dependencies 10 | 11 | The plugin has already been published to the Gradle Plugin Repository: [config-plugin](https://plugins.gradle.org/plugin/io.github.jadyli.config-plugin). 12 | 13 | **Method One:** 14 | 15 | ```kotlin 16 | // Root directory build.gradle.kts file 17 | buildscript { 18 | repositories { 19 | gradlePluginPortal() 20 | } 21 | 22 | dependencies { 23 | classpath("io.github.jadyli:config-plugin:0.1.23") 24 | } 25 | } 26 | ``` 27 | 28 | **Method Two (Recommended):** 29 | 30 | ```kotlin 31 | // Root directory settings.gradle.kts file 32 | pluginManagement { 33 | repositories { 34 | gradlePluginPortal() 35 | } 36 | resolutionStrategy { 37 | eachPlugin { 38 | when (requested.id.id) { 39 | "io.github.jadyli.config-plugin" -> { 40 | useModule("io.github.jadyli:config-plugin:0.1.23") 41 | } 42 | } 43 | } 44 | } 45 | } 46 | ``` 47 | 48 | ### 1.2 Applying the plugin and configuring parameters 49 | 50 | Refer to this repository's build.gradle.kts and apply the plugin in either the root directory or the module build file. 51 | 52 | ```kotlin 53 | // Method One (recommended), can be written as alias(libs.plugins.config.plugin) with version catalog 54 | plugins { 55 | id("io.github.jadyli.config-plugin") 56 | } 57 | 58 | // Method Two 59 | apply(plugin = "io.github.jadyli.config-plugin") 60 | ``` 61 | 62 | Then configure your parameters: 63 | 64 | ```kotlin 65 | extensions.configure { 66 | version { 67 | minSdk = bizLibs.versions.minSdk.get().toInt() 68 | targetSdk = bizLibs.versions.targetSdk.get().toInt() 69 | compileSdk = libs.versions.compileSdk.get().toInt() 70 | java = libs.versions.java.asProvider().get().toInt() 71 | kotlin = sharedLibs.versions.kotlin.asProvider().get() 72 | composeCompiler = sharedLibs.versions.compose.compiler.get() 73 | } 74 | vectorDrawableSupportLibrary = true 75 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 76 | } 77 | ``` 78 | 79 | After using the plugin, a library configuration file would be much simpler, only needing to add some module-required plugins and dependencies (the following example uses toml). 80 | 81 | ```kotlin 82 | @file:Suppress("UnstableApiUsage") 83 | 84 | @Suppress("DSL_SCOPE_VIOLATION") 85 | plugins { 86 | alias(libs.plugins.android.library) 87 | alias(libs.plugins.hilt.android) 88 | } 89 | 90 | dependencies { 91 | // official library 92 | implementation(libs.bundles.compose.core) 93 | implementation(libs.hilt.runtime) 94 | kapt(libs.bundles.hilt.compiler) 95 | 96 | // other module 97 | api(projects.framework.utils) 98 | } 99 | ``` 100 | 101 | ## 2 Dependency Management 102 | 103 | Official documentation on Gradle Shared Dependencies: [https://docs.gradle.org/current/userguide/platforms.html](https://docs.gradle.org/current/userguide/platforms.html) 104 | 105 | Toml Official website: [https://toml.io/en/](https://toml.io/en/) 106 | 107 | ### 2.1 Version Catalog 108 | 109 | Previously, there was no unified way to manage dependencies. Some used a properties file in the project settings (like creating a dependencies.gradle file), others created a plugin project to hold all dependencies. The advantage of this method is that the plugin can be shared across multiple projects and used as variables when fetching, version catalog is similar to this plugin, except the version catalog defines dependencies in a universal toml format file. 110 | 111 | ```kotlin 112 | [versions] 113 | # build config 114 | compileSdk = "31" 115 | # official library 116 | kotlin = "1.6.0" 117 | compose = "1.1.0-beta04" 118 | androidx-appcompat = "1.4.0" 119 | 120 | [libraries] 121 | # official library 122 | appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } 123 | androidx-activity-compose = "androidx.activity:activity-compose:1.4.0" 124 | compose-material = { module = "androidx.compose.material3:material3", version = "1.0.0-alpha02" } 125 | commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } } 126 | 127 | [plugins] 128 | android-application = { id = "com.android.application", version.ref = "android-plugin" } 129 | 130 | [bundles] 131 | compose-core = ["androidx-activity-compose", "compose-uiTooling", "compose-material"] 132 | ``` 133 | 134 | In summary: 135 | 136 | 1. Gradle supports four types of nodes: 137 | 1. `[versions]` is used to define version numbers, which must be strings. 138 | 2. `[libraries]` is used to define dependencies, the supported format can be referred from the example above 139 | 3. `[plugins]` is used to define plugins 140 | 4. `[bundles]` is used to define dependency groups 141 | 2. Version numbers support specifying single versions and version ranges. The specific rules can be referred to the comments of [VersionConstraint](https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/VersionConstraint.html) class, or refer to [Declaring Rich Versions](https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints). Here's a simple explanation: 142 | 1. Version ranges are represented by intervals. `(`, `)` represents an open interval, `[`, `]` represents a closed interval. `[` on the right side of the interval is equivalent to `)`, for example `[1, 2[` is equivalent to 143 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | plugins { 5 | alias(androidCommonLibs.plugins.android.application) 6 | alias(sharedCommonLibs.plugins.kotlin.android) 7 | alias(androidCommonLibs.plugins.hilt.android) 8 | alias(sharedCommonLibs.plugins.kotlin.kapt) 9 | } 10 | 11 | android { 12 | namespace = "com.jady.app" 13 | defaultConfig { 14 | applicationId = "com.jady.app.composing" 15 | versionCode = 1 16 | versionName = "1.0" 17 | 18 | splits { 19 | abi { 20 | isEnable = true 21 | reset() 22 | include("x86", "armeabi-v7a", "arm64-v8a") 23 | isUniversalApk = false 24 | } 25 | } 26 | } 27 | } 28 | 29 | dependencies { 30 | // official library 31 | implementation(androidCommonLibs.hilt.runtime) 32 | implementation(sharedCommonLibs.kotlin.stdlib) 33 | implementation(sharedCommonLibs.kotlin.coroutines.core) 34 | implementation(androidCommonLibs.androidx.lifecycle.runtime.ktx) 35 | implementation(androidCommonLibs.androidx.appcompat) 36 | implementation(sharedCommonLibs.bundles.compose.core) 37 | 38 | kapt(androidCommonLibs.bundles.hilt.compiler) 39 | 40 | // other module 41 | implementation(projects.common.common) 42 | 43 | // test 44 | testImplementation(androidCommonLibs.junit) 45 | } 46 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/jady/app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.animation.ExperimentalAnimationApi 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.material3.MaterialTheme 9 | import androidx.compose.material3.Surface 10 | import androidx.compose.material3.Text 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.ui.Modifier 13 | import androidx.compose.ui.tooling.preview.Preview 14 | import com.jady.app.ui.theme.MyApplicationTheme 15 | import dagger.hilt.android.AndroidEntryPoint 16 | 17 | /** 18 | * @author jady 19 | * @since 2021-12-15, 周三, 0:13 20 | * email: 1257984872@qq.com 21 | */ 22 | @ExperimentalAnimationApi 23 | @AndroidEntryPoint 24 | class MainActivity : ComponentActivity() { 25 | override fun onCreate(savedInstanceState: Bundle?) { 26 | super.onCreate(savedInstanceState) 27 | setContent { 28 | MyApplicationTheme { 29 | // A surface container using the 'background' color from the theme 30 | Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { 31 | Greeting("Android") 32 | } 33 | } 34 | } 35 | } 36 | } 37 | 38 | @Composable 39 | fun Greeting(name: String) { 40 | Text(text = "Hello $name!") 41 | } 42 | 43 | @Preview(showBackground = true) 44 | @Composable 45 | fun DefaultPreview() { 46 | MyApplicationTheme { 47 | Greeting("Android") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/jady/app/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import com.jady.utils.application 6 | import dagger.hilt.android.HiltAndroidApp 7 | 8 | 9 | /** 10 | * @author jady 11 | * @since 2021-12-14, 周二, 23:53 12 | * email: 1257984872@qq.com 13 | */ 14 | @HiltAndroidApp 15 | class MainApplication : Application() { 16 | override fun attachBaseContext(base: Context?) { 17 | super.attachBaseContext(base) 18 | application = this 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/jady/app/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple80 = Color(0xFFD0BCFF) 6 | val PurpleGrey80 = Color(0xFFCCC2DC) 7 | val Pink80 = Color(0xFFEFB8C8) 8 | 9 | val Purple40 = Color(0xFF6650a4) 10 | val PurpleGrey40 = Color(0xFF625b71) 11 | val Pink40 = Color(0xFF7D5260) 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/jady/app/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app.ui.theme 2 | 3 | import android.app.Activity 4 | import android.os.Build 5 | import androidx.compose.foundation.isSystemInDarkTheme 6 | import androidx.compose.material3.MaterialTheme 7 | import androidx.compose.material3.darkColorScheme 8 | import androidx.compose.material3.dynamicDarkColorScheme 9 | import androidx.compose.material3.dynamicLightColorScheme 10 | import androidx.compose.material3.lightColorScheme 11 | import androidx.compose.runtime.Composable 12 | import androidx.compose.runtime.SideEffect 13 | import androidx.compose.ui.graphics.toArgb 14 | import androidx.compose.ui.platform.LocalContext 15 | import androidx.compose.ui.platform.LocalView 16 | import androidx.core.view.ViewCompat 17 | 18 | private val DarkColorScheme = darkColorScheme( 19 | primary = Purple80, 20 | secondary = PurpleGrey80, 21 | tertiary = Pink80 22 | ) 23 | 24 | private val LightColorScheme = lightColorScheme( 25 | primary = Purple40, 26 | secondary = PurpleGrey40, 27 | tertiary = Pink40 28 | 29 | /* Other default colors to override 30 | background = Color(0xFFFFFBFE), 31 | surface = Color(0xFFFFFBFE), 32 | onPrimary = Color.White, 33 | onSecondary = Color.White, 34 | onTertiary = Color.White, 35 | onBackground = Color(0xFF1C1B1F), 36 | onSurface = Color(0xFF1C1B1F), 37 | */ 38 | ) 39 | 40 | @Composable 41 | fun MyApplicationTheme( 42 | darkTheme: Boolean = isSystemInDarkTheme(), 43 | // Dynamic color is available on Android 12+ 44 | dynamicColor: Boolean = true, 45 | content: @Composable () -> Unit 46 | ) { 47 | val colorScheme = when { 48 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 49 | val context = LocalContext.current 50 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 51 | } 52 | darkTheme -> DarkColorScheme 53 | else -> LightColorScheme 54 | } 55 | val view = LocalView.current 56 | if (!view.isInEditMode) { 57 | SideEffect { 58 | (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb() 59 | ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme 60 | } 61 | } 62 | 63 | MaterialTheme( 64 | colorScheme = colorScheme, 65 | typography = Typography, 66 | content = content 67 | ) 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/jady/app/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app.ui.theme 2 | 3 | import androidx.compose.material3.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | bodyLarge = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | lineHeight = 24.sp, 16 | letterSpacing = 0.5.sp 17 | ) 18 | /* Other default text styles to override 19 | titleLarge = TextStyle( 20 | fontFamily = FontFamily.Default, 21 | fontWeight = FontWeight.Normal, 22 | fontSize = 22.sp, 23 | lineHeight = 28.sp, 24 | letterSpacing = 0.sp 25 | ), 26 | labelSmall = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Medium, 29 | fontSize = 11.sp, 30 | lineHeight = 16.sp, 31 | letterSpacing = 0.5.sp 32 | ) 33 | */ 34 | ) 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | composing 3 | MainActivity 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/test/java/com/jady/app/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.jady.app 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | import com.jady.lib.config.CommonConfigExtension 4 | import com.jady.lib.config.CommonConfigExtension.Companion.DEFAULT_SPOTLESS_CONFIG_ACTION 5 | 6 | @Suppress("DSL_SCOPE_VIOLATION") 7 | plugins { 8 | alias(androidCommonLibs.plugins.android.application) apply false 9 | alias(androidCommonLibs.plugins.android.library) apply false 10 | alias(sharedCommonLibs.plugins.kotlin.android) apply false 11 | alias(sharedCommonLibs.plugins.kotlin.kapt) apply false 12 | alias(sharedCommonLibs.plugins.jetbrains.compose) apply false 13 | alias(sharedCommonLibs.plugins.compose.compiler) apply false 14 | alias(sharedCommonLibs.plugins.config.plugin) apply false 15 | } 16 | 17 | val androidLibs = androidCommonLibs 18 | val bizLibs = androidBizLibs 19 | val sharedLibs = sharedCommonLibs 20 | subprojects { 21 | apply(plugin = sharedLibs.plugins.config.plugin.get().pluginId) 22 | extensions.configure { 23 | version { 24 | minSdk = bizLibs.versions.minSdk.get().toInt() 25 | targetSdk = bizLibs.versions.targetSdk.get().toInt() 26 | compileSdk = androidLibs.versions.compileSdk.get().toInt() 27 | java = androidLibs.versions.java.asProvider().get().toInt() 28 | kotlin = sharedLibs.versions.kotlin.asProvider().get() 29 | } 30 | spotless(DEFAULT_SPOTLESS_CONFIG_ACTION) 31 | vectorDrawableSupportLibrary = true 32 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/common/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /build 3 | -------------------------------------------------------------------------------- /common/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | plugins { 5 | alias(androidCommonLibs.plugins.android.library) 6 | alias(sharedCommonLibs.plugins.kotlin.android) 7 | alias(androidCommonLibs.plugins.hilt.android) 8 | alias(sharedCommonLibs.plugins.kotlin.kapt) 9 | } 10 | 11 | android { 12 | namespace = "com.jady.common" 13 | } 14 | 15 | dependencies { 16 | // official library 17 | implementation(sharedCommonLibs.bundles.compose.core) 18 | implementation(androidCommonLibs.hilt.runtime) 19 | kapt(androidCommonLibs.bundles.hilt.compiler) 20 | 21 | // other module 22 | api(projects.framework.utils) 23 | } 24 | -------------------------------------------------------------------------------- /common/common/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /common/common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/common/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common/common/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /framework/utils/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /build 3 | -------------------------------------------------------------------------------- /framework/utils/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | plugins { 5 | alias(androidCommonLibs.plugins.android.library) 6 | alias(sharedCommonLibs.plugins.kotlin.android) 7 | } 8 | 9 | android { 10 | namespace = "com.jady.utils" 11 | } 12 | 13 | dependencies { 14 | implementation(sharedCommonLibs.bundles.compose.core) 15 | // test 16 | testCompileOnly(androidCommonLibs.junit) 17 | } 18 | -------------------------------------------------------------------------------- /framework/utils/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /framework/utils/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /framework/utils/src/main/java/com/jady/utils/Contexts.kt: -------------------------------------------------------------------------------- 1 | package com.jady.utils 2 | 3 | import android.app.Application 4 | 5 | /** 6 | * @author jady 7 | * @since 2021-12-15, 周三, 0:17 8 | * email: 1257984872@qq.com 9 | */ 10 | lateinit var application: Application 11 | -------------------------------------------------------------------------------- /framework/utils/src/test/java/com/jady/utils/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.jady.utils 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.injected.testOnly=false 2 | fawkes.buildscan.key=android_missevan 3 | # AndroidX 4 | android.useAndroidX=true 5 | android.defaults.buildfeatures.viewbinding=true 6 | kotlin.experimental.tryNext=false 7 | #MPP 8 | kotlin.mpp.stability.nowarn=true 9 | kotlin.mpp.enableCInteropCommonization=true 10 | kotlin.mpp.androidSourceSetLayoutVersion=2 11 | kotlin.native.ignoreDisabledTargets=true 12 | kotlin.mpp.applyDefaultHierarchyTemplate=false 13 | kotlin.js.ir.output.granularity=whole-program 14 | ksp.incremental=false 15 | ksp.useKSP2=false 16 | kotlin.build.report.file.output_dir=kotlin-reports 17 | kotlin.mpp.keepMppDependenciesIntactInPoms=false 18 | kotlin.internal.mpp.createDefaultMultiplatformPublications=true 19 | systemProp.https.protocols=TLSv1.1,TLSv1.2 20 | #Compose 21 | org.jetbrains.compose.experimental.uikit.enabled=true 22 | org.jetbrains.compose.experimental.jscanvas.enabled=true 23 | org.jetbrains.compose.experimental.macos.enabled=true 24 | compose.ios.resources.sync=false 25 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jadyli/config-plugin/5e6f58b0f108fa9b9f9aa8c3c1fa75fdd7540cb4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https://services.gradle.org/distributions/gradle-8.9-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /plugins/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /build 3 | /.gradle/ 4 | -------------------------------------------------------------------------------- /plugins/config-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /build 3 | /.gradle/ 4 | -------------------------------------------------------------------------------- /plugins/config-plugin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | @Suppress("DSL_SCOPE_VIOLATION") 4 | plugins { 5 | alias(sharedCommonLibs.plugins.kotlin.dsl) 6 | alias(sharedCommonLibs.plugins.gradle.publish) 7 | } 8 | 9 | group = "io.github.jadyli" 10 | version = sharedCommonLibs.versions.config.plugin.get() 11 | 12 | gradlePlugin { 13 | website.set("https://github.com/Jadyli/config-plugin") 14 | vcsUrl.set("https://github.com/Jadyli/config-plugin.git") 15 | plugins.register("config") { 16 | id = "io.github.jadyli.config-plugin" 17 | implementationClass = "com.jady.lib.config.ConfigPlugin" 18 | displayName = "Common config plugin for Android" 19 | description = "A plugin help you to config android extension" 20 | tags.addAll("android", "config") 21 | } 22 | } 23 | 24 | publishing { 25 | repositories { 26 | maven { 27 | setUrl("../../local-repo") 28 | name = "localRepo" 29 | } 30 | } 31 | } 32 | 33 | kotlin { 34 | jvmToolchain { 35 | languageVersion.set(JavaLanguageVersion.of(17)) 36 | } 37 | } 38 | 39 | java { 40 | toolchain { 41 | languageVersion.set(JavaLanguageVersion.of(17)) 42 | } 43 | } 44 | 45 | dependencies { 46 | implementation(androidCommonLibs.plugin.source.android) 47 | implementation(sharedCommonLibs.plugin.source.kotlin) 48 | implementation(sharedCommonLibs.plugin.source.compose) 49 | implementation(sharedCommonLibs.plugin.source.libres) 50 | implementation(sharedCommonLibs.plugin.source.ksp) 51 | implementation(sharedCommonLibs.plugin.source.maven.publish) 52 | implementation(androidCommonLibs.plugin.source.spotless) 53 | compileOnly(gradleApi()) 54 | } 55 | -------------------------------------------------------------------------------- /plugins/config-plugin/src/main/kotlin/com/jady/lib/config/CommonConfigExtension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2024 BiliBili Inc. 3 | */ 4 | 5 | package com.jady.lib.config 6 | 7 | import com.diffplug.gradle.spotless.FormatExtension 8 | import com.diffplug.gradle.spotless.JavaExtension 9 | import com.diffplug.gradle.spotless.KotlinExtension 10 | import com.diffplug.gradle.spotless.KotlinGradleExtension 11 | import com.diffplug.gradle.spotless.SpotlessExtension 12 | import org.gradle.api.Action 13 | import org.gradle.api.artifacts.MinimalExternalModuleDependency 14 | import org.gradle.api.provider.Provider 15 | 16 | /** 17 | * @author jady 18 | * @since 2023/09/04 20/26 19 | * email: 1257984872@qq.com 20 | */ 21 | abstract class CommonConfigExtension { 22 | var vectorDrawableSupportLibrary = false 23 | var testInstrumentationRunner: String? = null 24 | 25 | internal var version = VersionExtension() 26 | internal var spotlessAction: Action? = null 27 | 28 | fun version(closure: Action) { 29 | closure.execute(version) 30 | } 31 | 32 | fun spotless(closure: Action) { 33 | spotlessAction = closure 34 | } 35 | 36 | companion object { 37 | val DEFAULT_SPOTLESS_CONFIG_ACTION = object : Action { 38 | override fun execute(extension: SpotlessExtension) { 39 | extension.run { 40 | format("misc", object : Action { 41 | override fun execute(extension: FormatExtension) { 42 | extension.run { 43 | target("*.md", ".gitignore") 44 | trimTrailingWhitespace() 45 | endWithNewline() 46 | } 47 | } 48 | }) 49 | java(object : Action { 50 | override fun execute(extension: JavaExtension) { 51 | extension.run { 52 | removeUnusedImports() 53 | indentWithSpaces(4) 54 | toggleOffOn() 55 | } 56 | } 57 | }) 58 | kotlin(object : Action { 59 | override fun execute(extension: KotlinExtension) { 60 | extension.run { 61 | target("**/*.kt") 62 | targetExclude( 63 | "**/copyright.kt", 64 | ) 65 | ktlint("1.0.1") 66 | .editorConfigOverride( 67 | mapOf( 68 | "indent_size" to 4, 69 | "max-linelength" to 140, 70 | "ktlint_standard_discouraged-comment-location" to "disabled", 71 | "ktlint_standard_spacing-between-declarations-with-comments" to "disabled", 72 | "ktlint_function_naming_ignore_when_annotated_with" to "Composable", 73 | "spacing-between-declarations-with-annotations" to "disabled", 74 | "spacing-between-declarations-with-comments" to "disabled", 75 | "multiline-if-else" to "disabled", 76 | "ij_kotlin_allow_trailing_comma_on_call_site" to false, 77 | "ij_kotlin_allow_trailing_comma" to false 78 | ) 79 | ) 80 | trimTrailingWhitespace() 81 | endWithNewline() 82 | toggleOffOn() 83 | } 84 | } 85 | }) 86 | kotlinGradle(object : Action { 87 | override fun execute(extension: KotlinGradleExtension) { 88 | extension.run { 89 | target("**/*.kts") 90 | ktlint("1.0.1") 91 | .editorConfigOverride( 92 | mapOf( 93 | "indent_size" to 4, 94 | "max-linelength" to 140, 95 | "ktlint_function_naming_ignore_when_annotated_with" to "Composable", 96 | "spacing-between-declarations-with-annotations" to "disabled", 97 | "spacing-between-declarations-with-comments" to "disabled", 98 | "multiline-if-else" to "disabled", 99 | "ij_kotlin_allow_trailing_comma_on_call_site" to false, 100 | "ij_kotlin_allow_trailing_comma" to false 101 | ) 102 | ) 103 | trimTrailingWhitespace() 104 | endWithNewline() 105 | } 106 | } 107 | }) 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | data class VersionExtension( 115 | var minSdk: Int = 21, 116 | var targetSdk: Int = 30, 117 | var compileSdk: Int = 33, 118 | var java: Int = 11, 119 | var kotlin: String = "2.0.0", 120 | ) 121 | 122 | data class KspCompiler( 123 | var isMultiplatform: Boolean, 124 | var onlyUseInCommon: Boolean, 125 | var dependency: Provider 126 | ) 127 | 128 | data class MavenExtension(var mavenRepository: MavenRepository? = null, var pom: PomExtension? = null) 129 | 130 | data class MavenRepository( 131 | var name: String = "", 132 | var releaseUrl: String = "", 133 | var snapshotUrl: String = releaseUrl, 134 | var userName: String? = null, 135 | var password: String? = null 136 | ) 137 | 138 | data class PomExtension( 139 | var repoUrl: String = "", 140 | var httpsConnection: String = "", 141 | var gitConnection: String = "", 142 | var developerName: String = "" 143 | ) 144 | -------------------------------------------------------------------------------- /plugins/config-plugin/src/main/kotlin/com/jady/lib/config/ConfigPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015-2024 BiliBili Inc. 3 | */ 4 | 5 | package com.jady.lib.config 6 | 7 | import com.android.build.gradle.AppPlugin 8 | import com.android.build.gradle.BaseExtension 9 | import com.android.build.gradle.LibraryExtension 10 | import com.android.build.gradle.LibraryPlugin 11 | import com.android.build.gradle.internal.dsl.BaseAppModuleExtension 12 | import com.diffplug.gradle.spotless.SpotlessExtension 13 | import com.diffplug.gradle.spotless.SpotlessPlugin 14 | import com.google.devtools.ksp.gradle.KspExtension 15 | import com.google.devtools.ksp.gradle.KspTaskMetadata 16 | import com.vanniktech.maven.publish.MavenPublishBaseExtension 17 | import com.vanniktech.maven.publish.MavenPublishBasePlugin 18 | import io.github.skeptick.libres.plugin.LibresResourcesGenerationTask 19 | import io.github.skeptick.libres.plugin.ResourcesPlugin 20 | import io.github.skeptick.libres.plugin.ResourcesPluginExtension 21 | import org.gradle.api.Action 22 | import org.gradle.api.JavaVersion 23 | import org.gradle.api.NamedDomainObjectContainer 24 | import org.gradle.api.Plugin 25 | import org.gradle.api.Project 26 | import org.gradle.api.artifacts.dsl.DependencyHandler 27 | import org.gradle.api.artifacts.dsl.RepositoryHandler 28 | import org.gradle.api.artifacts.repositories.MavenArtifactRepository 29 | import org.gradle.api.plugins.ExtensionAware 30 | import org.gradle.api.publish.PublishingExtension 31 | import org.gradle.api.publish.maven.MavenPom 32 | import org.gradle.api.publish.maven.MavenPomDeveloper 33 | import org.gradle.api.publish.maven.MavenPomDeveloperSpec 34 | import org.gradle.api.publish.maven.MavenPomScm 35 | import org.gradle.api.publish.tasks.GenerateModuleMetadata 36 | import org.gradle.kotlin.dsl.configure 37 | import org.gradle.kotlin.dsl.getByType 38 | import org.gradle.kotlin.dsl.getValue 39 | import org.gradle.kotlin.dsl.getting 40 | import org.gradle.kotlin.dsl.typeOf 41 | import org.gradle.kotlin.dsl.withType 42 | import org.jetbrains.compose.ComposeExtension 43 | import org.jetbrains.compose.ComposePlugin 44 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi 45 | import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions 46 | import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions 47 | import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions 48 | import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension 49 | import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension 50 | import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension 51 | import org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs 52 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 53 | import java.io.File 54 | 55 | /** 56 | * @author jady 57 | * @since 2021-12-15, 周三, 0:5 58 | * email: 1257984872@qq.com 59 | */ 60 | private const val TARGET_NAME_IOS_X64 = "iosX64" 61 | private const val TARGET_NAME_IOS_ARM64 = "iosArm64" 62 | private const val TARGET_NAME_IOS_SIMULATOR_ARM64 = "iosSimulatorArm64" 63 | private const val TARGET_NAME_DESKTOP = "desktop" 64 | private const val TARGET_NAME_ANDROID = "android" 65 | private const val TARGET_NAME_JS = "js" 66 | private const val TARGET_NAME_WASM_JS = "wasmJs" 67 | 68 | class ConfigPlugin : Plugin { 69 | override fun apply(project: Project) { 70 | project.run { 71 | val commonConfigExtension = extensions.create("config", CommonConfigExtension::class.java) 72 | afterEvaluate { 73 | commonConfigExtension.spotlessAction?.let { 74 | pluginManager.apply(SpotlessPlugin::class.java) 75 | it.execute(extensions.getByType(SpotlessExtension::class.java)) 76 | } 77 | plugins.forEach { plugin -> 78 | when (plugin) { 79 | is LibraryPlugin -> configureLibraryPlugin(commonConfigExtension) 80 | is AppPlugin -> configureAppPlugin(commonConfigExtension) 81 | is ResourcesPlugin -> { 82 | project.tasks.findByName("prepareKotlinIdeaImport") 83 | ?.dependsOn(project.tasks.withType(LibresResourcesGenerationTask::class.java)) 84 | } 85 | else -> {} 86 | } 87 | } 88 | } 89 | } 90 | } 91 | 92 | private fun Project.configureAppPlugin(configExtension: CommonConfigExtension) { 93 | extensions.getByType().run { 94 | configCommonExtension(this@configureAppPlugin, configExtension) 95 | defaultConfig.proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 96 | buildTypes { 97 | getByName("release").run { 98 | isShrinkResources = true 99 | isMinifyEnabled = true 100 | } 101 | } 102 | } 103 | } 104 | 105 | private fun Project.configureLibraryPlugin(configExtension: CommonConfigExtension) { 106 | extensions.getByType().run { 107 | configCommonExtension(this@configureLibraryPlugin, configExtension) 108 | defaultConfig { 109 | consumerProguardFiles("proguard-rules.pro") 110 | proguardFiles("proguard-rules.pro") 111 | } 112 | } 113 | } 114 | 115 | private fun BaseExtension.configCommonExtension(project: Project, commonConfigExtension: CommonConfigExtension) { 116 | setCompileSdkVersion(commonConfigExtension.version.compileSdk) 117 | val javaMajor = commonConfigExtension.version.java 118 | val javaVersion = JavaVersion.toVersion(javaMajor) 119 | val javaVersionString = javaVersion.toString() 120 | val hasComposePlugin = project.plugins.hasPlugin(ComposePlugin::class.java) 121 | defaultConfig.run { 122 | minSdk = commonConfigExtension.version.minSdk 123 | targetSdk = commonConfigExtension.version.targetSdk 124 | testInstrumentationRunner = commonConfigExtension.testInstrumentationRunner 125 | vectorDrawables.useSupportLibrary = commonConfigExtension.vectorDrawableSupportLibrary 126 | } 127 | 128 | @Suppress("deprecation") 129 | lintOptions.run { 130 | isAbortOnError = false 131 | isCheckReleaseBuilds = false 132 | File("lint.xml").takeIf { it.exists() }?.let { 133 | lintConfig = it 134 | } 135 | } 136 | 137 | val extensions = (this as ExtensionAware).extensions 138 | val kotlinExtension = extensions.findByName("kotlin") as? KotlinTopLevelExtension 139 | kotlinExtension?.jvmToolchain(javaMajor) 140 | val kotlinOptions = extensions.findByName("kotlinOptions") as? KotlinJvmOptions 141 | kotlinOptions?.setKotlinOptions(javaVersionString, hasComposePlugin) 142 | 143 | buildFeatures.apply { 144 | if (hasComposePlugin) { 145 | compose = true 146 | } 147 | buildConfig = true 148 | } 149 | 150 | project.tasks.findByName("kaptGenerateStubs")?.configure { 151 | compilerOptions.setKotlinCommonCompilerOptions(hasComposePlugin) 152 | } 153 | project.tasks.withType().forEach { 154 | it.kotlinOptions.setKotlinOptions(javaVersionString, hasComposePlugin) 155 | } 156 | 157 | sourceSets.run { 158 | getByName("main").run { 159 | if (kotlinExtension != null) { 160 | manifest.srcFile("src/androidMain/AndroidManifest.xml") 161 | res.srcDirs("src/androidMain/res") 162 | kotlin.srcDirs("src/androidMain/kotlin", "src/commonMain/kotlin") 163 | resources.srcDirs("src/commonMain/resources") 164 | } else { 165 | res.srcDirs("src/main/res") 166 | java.srcDirs("src/main/java", "src/main/kotlin") 167 | kotlin.srcDirs("src/main/java", "src/main/kotlin") 168 | } 169 | jniLibs.srcDirs("libs") 170 | } 171 | getByName("debug").run { 172 | kotlin.srcDir("build/generated/ksp/android/androidDebug/kotlin") 173 | } 174 | getByName("release").run { 175 | kotlin.srcDir("build/generated/ksp/android/androidRelease/kotlin") 176 | } 177 | } 178 | 179 | packagingOptions.run { 180 | resources { 181 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 182 | } 183 | } 184 | 185 | testOptions.run { 186 | unitTests.isIncludeAndroidResources = true 187 | unitTests.all { test -> 188 | test.jvmArgs("-noverify") 189 | } 190 | } 191 | 192 | compileOptions.run { 193 | with(javaVersion) { 194 | sourceCompatibility = this 195 | targetCompatibility = this 196 | } 197 | } 198 | } 199 | 200 | private fun KotlinJvmOptions.setKotlinOptions(javaVersion: String, useCompose: Boolean) { 201 | jvmTarget = javaVersion 202 | setKotlinCommonCompilerOptions(useCompose) 203 | } 204 | } 205 | 206 | fun KotlinCommonCompilerOptions.setKotlinCommonCompilerOptions(useCompose: Boolean) { 207 | freeCompilerArgs.addAll(getCompilerArgs(useCompose)) 208 | } 209 | 210 | fun KotlinCommonOptions.setKotlinCommonCompilerOptions(useCompose: Boolean) { 211 | freeCompilerArgs += getCompilerArgs(useCompose) 212 | } 213 | 214 | private fun getCompilerArgs(useCompose: Boolean = true) = arrayListOf( 215 | "-opt-in=kotlin.ExperimentalStdlibApi", 216 | "-opt-in=kotlin.RequiresOptIn", 217 | "-opt-in=kotlin.contracts.ExperimentalContracts", 218 | "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", 219 | "-Xcontext-receivers", 220 | "-Xskip-prerelease-check", 221 | "-Xexpect-actual-classes" 222 | ).apply { 223 | if (useCompose) { 224 | add("-opt-in=androidx.compose.foundation.ExperimentalFoundationApi") 225 | } 226 | } 227 | 228 | fun > U.configureSourceSet( 229 | sourceSetName: String, 230 | configuration: T.() -> Unit 231 | ): T { 232 | return getOrCreate(sourceSetName).apply(configuration) 233 | } 234 | 235 | fun > U.getOrCreate(sourceSetName: String) = findByName(sourceSetName) ?: create(sourceSetName) 236 | 237 | fun > U.getSourceSet(sourceSetName: String, configuration: (T.() -> Unit)? = null) = 238 | getByName(sourceSetName).apply { configuration?.invoke(this) } 239 | 240 | fun > U.createSourceSet(sourceSetName: String, configuration: (T.() -> Unit)? = null) = 241 | create(sourceSetName).apply { configuration?.invoke(this) } 242 | 243 | fun Project.applyMavenPlugin(closure: Action) { 244 | pluginManager.apply(MavenPublishBasePlugin::class.java) 245 | val maven = MavenExtension().apply { closure.execute(this) } 246 | extensions.findByType(PublishingExtension::class.java)?.run { 247 | maven.mavenRepository?.let { repo -> 248 | repositories(object : Action { 249 | override fun execute(handler: RepositoryHandler) { 250 | handler.maven(object : Action { 251 | override fun execute(mavenArtifactRepository: MavenArtifactRepository) { 252 | mavenArtifactRepository.run { 253 | name = repo.name 254 | url = if (version.toString().endsWith("SNAPSHOT")) { 255 | uri(repo.snapshotUrl) 256 | } else { 257 | uri(repo.releaseUrl) 258 | } 259 | credentials { 260 | username = repo.userName 261 | password = repo.password 262 | } 263 | } 264 | } 265 | }) 266 | } 267 | }) 268 | } 269 | } 270 | extensions.findByType(MavenPublishBaseExtension::class.java)?.run { 271 | maven.pom?.let { pom -> 272 | pom(object : Action { 273 | override fun execute(mavenPom: MavenPom) { 274 | mavenPom.run { 275 | name.set(project.name) 276 | description.set("Module of $name") 277 | url.set(pom.repoUrl) 278 | scm(object : Action { 279 | override fun execute(mavenPomScm: MavenPomScm) { 280 | mavenPomScm.run { 281 | connection.set(pom.httpsConnection) 282 | developerConnection.set(pom.gitConnection) 283 | url.set(pom.repoUrl) 284 | } 285 | } 286 | }) 287 | developers(object : Action { 288 | override fun execute(mavenPomDeveloperSpec: MavenPomDeveloperSpec) { 289 | mavenPomDeveloperSpec.run { 290 | developer(object : Action { 291 | override fun execute(mavenPomDeveloper: MavenPomDeveloper) { 292 | mavenPomDeveloper.run { 293 | name.set(pom.developerName) 294 | } 295 | } 296 | }) 297 | } 298 | } 299 | }) 300 | } 301 | } 302 | }) 303 | } 304 | } 305 | tasks.withType { 306 | enabled = true 307 | } 308 | } 309 | 310 | fun Project.applyLibResPlugin(closure: Action) { 311 | pluginManager.apply(ResourcesPlugin::class.java) 312 | closure.execute(project.extensions.getByType(ResourcesPluginExtension::class.java)) 313 | } 314 | 315 | @OptIn(ExperimentalKotlinGradlePluginApi::class) 316 | fun KotlinMultiplatformExtension.configKMPPlugin( 317 | project: Project, 318 | javaVersion: Int, 319 | applyDefaultTargets: Boolean 320 | ) { 321 | jvmToolchain(javaVersion) 322 | if (applyDefaultTargets) { 323 | androidTarget { 324 | publishLibraryVariants("release") 325 | } 326 | jvm("desktop") 327 | iosX64() 328 | iosArm64() 329 | iosSimulatorArm64() 330 | } 331 | compilerOptions(object : Action { 332 | override fun execute(options: KotlinCommonCompilerOptions) { 333 | options.setKotlinCommonCompilerOptions(true) 334 | } 335 | }) 336 | cocoapodsExtensionOrNull?.configCocoapods(project) 337 | configKMPSourceSets(project) 338 | } 339 | 340 | private val KotlinMultiplatformExtension.cocoapodsExtensionOrNull: CocoapodsExtension? 341 | get() = (this as ExtensionAware).extensions.findByType(CocoapodsExtension::class.java) 342 | 343 | private fun CocoapodsExtension.configCocoapods(project: Project) { 344 | name = project.name 345 | version = "1.0.0" 346 | ios.deploymentTarget = "14.1" 347 | homepage = "https://github.com" 348 | summary = "$name module" 349 | license = "Apache License 2.0" 350 | 351 | val preferDir = File(project.rootDir.path + "/iosApp/Podfile") 352 | podfile = if (preferDir.exists()) preferDir else File(project.rootDir.parentFile.path + "/iosApp/Podfile") 353 | framework { 354 | baseName = project.name 355 | isStatic = true 356 | } 357 | } 358 | 359 | private fun KotlinMultiplatformExtension.configKMPSourceSets(project: Project) { 360 | sourceSets.run { 361 | val compose = project.extensions.findByType(typeOf())?.dependencies 362 | val commonMain by getting { 363 | kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") 364 | project.tasks.withType { 365 | kotlin.srcDir(destinationDirectory) 366 | } 367 | dependencies { 368 | compose?.run { 369 | api(runtime) 370 | api(foundation) 371 | api(material) 372 | api(material3) 373 | api(components.resources) 374 | } 375 | } 376 | } 377 | val jvmCommonMain = configureSourceSet("jvmCommonMain") { 378 | dependsOn(commonMain) 379 | dependencies { 380 | compose?.run { 381 | api(uiTooling) 382 | } 383 | } 384 | } 385 | val jsWasmMain = configureSourceSet("jsWasmMain") { 386 | dependsOn(commonMain) 387 | } 388 | val iosMain = configureSourceSet("iosMain") { 389 | dependsOn(commonMain) 390 | } 391 | targets.names.forEach { 392 | when (it) { 393 | TARGET_NAME_IOS_X64 -> { 394 | val iosX64Main by getting { 395 | kotlin.srcDir("build/generated/ksp/iosX64/iosX64Main/kotlin") 396 | dependsOn(iosMain) 397 | } 398 | } 399 | TARGET_NAME_IOS_ARM64 -> { 400 | val iosArm64Main by getting { 401 | kotlin.srcDir("build/generated/ksp/iosArm64/iosArm64Main/kotlin") 402 | dependsOn(iosMain) 403 | } 404 | } 405 | TARGET_NAME_IOS_SIMULATOR_ARM64 -> { 406 | val iosSimulatorArm64Main by getting { 407 | kotlin.srcDir("build/generated/ksp/iosSimulatorArm64/iosSimulatorArm64Main/kotlin") 408 | dependsOn(iosMain) 409 | } 410 | } 411 | TARGET_NAME_DESKTOP -> { 412 | val desktopMain by getting { 413 | kotlin.srcDir("build/generated/ksp/desktop/desktopMain/kotlin") 414 | dependsOn(jvmCommonMain) 415 | dependencies { 416 | compose?.run { 417 | api(desktop.common) 418 | } 419 | } 420 | } 421 | } 422 | TARGET_NAME_ANDROID -> { 423 | val androidMain by getting { 424 | dependsOn(jvmCommonMain) 425 | } 426 | } 427 | TARGET_NAME_JS -> { 428 | val jsMain by getting { 429 | kotlin.srcDir("build/generated/ksp/js/jsMain/kotlin") 430 | dependsOn(jsWasmMain) 431 | } 432 | } 433 | TARGET_NAME_WASM_JS -> { 434 | val wasmJsMain by getting { 435 | kotlin.srcDir("build/generated/ksp/wasm/wasmJsMain/kotlin") 436 | dependsOn(jsWasmMain) 437 | } 438 | } 439 | } 440 | } 441 | } 442 | } 443 | 444 | fun DependencyHandler.addKspDependencies(kspCompilerList: List) { 445 | println("ksp: $kspCompilerList") 446 | kspCompilerList.forEach { (isMultiplatform, onlyUseInCommon, dependency) -> 447 | if (!isMultiplatform) { 448 | add("ksp", dependency) 449 | } else { 450 | if (onlyUseInCommon) { 451 | add("kspCommonMainMetadata", dependency) 452 | } else { 453 | add("kspDesktop", dependency) 454 | add("kspAndroid", dependency) 455 | add("kspIosX64", dependency) 456 | add("kspIosArm64", dependency) 457 | add("kspIosSimulatorArm64", dependency) 458 | } 459 | } 460 | } 461 | } 462 | 463 | fun KspExtension.configKspExtension() { 464 | arg("KOIN_CONFIG_CHECK", "true") 465 | } 466 | -------------------------------------------------------------------------------- /plugins/gradle.properties: -------------------------------------------------------------------------------- 1 | android.injected.testOnly=false 2 | fawkes.buildscan.key=android_missevan 3 | # AndroidX 4 | android.useAndroidX=true 5 | android.defaults.buildfeatures.viewbinding=true 6 | kotlin.experimental.tryNext=false 7 | #MPP 8 | kotlin.mpp.stability.nowarn=true 9 | kotlin.mpp.enableCInteropCommonization=true 10 | kotlin.mpp.androidSourceSetLayoutVersion=2 11 | kotlin.native.ignoreDisabledTargets=true 12 | kotlin.mpp.applyDefaultHierarchyTemplate=false 13 | kotlin.js.ir.output.granularity=whole-program 14 | ksp.incremental=false 15 | ksp.useKSP2=false 16 | kotlin.build.report.file.output_dir=kotlin-reports 17 | kotlin.mpp.keepMppDependenciesIntactInPoms=false 18 | kotlin.internal.mpp.createDefaultMultiplatformPublications=true 19 | systemProp.https.protocols=TLSv1.1,TLSv1.2 20 | #Compose 21 | org.jetbrains.compose.experimental.uikit.enabled=true 22 | org.jetbrains.compose.experimental.jscanvas.enabled=true 23 | org.jetbrains.compose.experimental.macos.enabled=true 24 | compose.ios.resources.sync=false 25 | -------------------------------------------------------------------------------- /plugins/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 4 | pluginManagement { 5 | repositories { 6 | gradlePluginPortal() 7 | mavenCentral() 8 | google() 9 | maven { setUrl("https://jitpack.io") } 10 | maven { setUrl("./local-repo/") } 11 | } 12 | } 13 | dependencyResolutionManagement { 14 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 15 | repositories { 16 | mavenCentral() 17 | google() 18 | maven { setUrl("https://maven.pkg.jetbrains.space/public/p/compose/dev") } 19 | maven { setUrl("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental") } 20 | maven { setUrl("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev") } 21 | maven { setUrl("https://jitpack.io") } 22 | } 23 | versionCatalogs { 24 | create("androidCommonLibs") { from(files("${rootDir.path}/../.config/dependencies-android-common.toml")) } 25 | create("androidBizLibs") { from(files("${rootDir.path}/../.config/dependencies-android-biz.toml")) } 26 | create("sharedCommonLibs") { from(files("${rootDir.path}/../.config/dependencies-shared-common.toml")) } 27 | } 28 | } 29 | 30 | rootProject.name = "plugins" 31 | 32 | include(":config-plugin") 33 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 4 | pluginManagement { 5 | repositories { 6 | gradlePluginPortal() 7 | mavenCentral() 8 | google() 9 | maven { setUrl("https://jitpack.io") } 10 | maven { setUrl("./local-repo/") } 11 | } 12 | resolutionStrategy { 13 | eachPlugin { 14 | when (requested.id.id) { 15 | "com.android.application" -> { 16 | useModule("com.android.tools.build:gradle:${requested.version}") 17 | } 18 | "com.android.library" -> { 19 | useModule("com.android.tools.build:gradle:${requested.version}") 20 | } 21 | "org.gradle.kotlin.kotlin-dsl" -> { 22 | useModule("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${requested.version}") 23 | } 24 | "org.jetbrains.kotlin.android" -> { 25 | useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") 26 | } 27 | "dagger.hilt.android.plugin" -> { 28 | useModule("com.google.dagger:hilt-android-gradle-plugin:${requested.version}") 29 | } 30 | "io.github.jadyli.config-plugin" -> { 31 | useModule("io.github.jadyli:config-plugin:${requested.version}") 32 | } 33 | } 34 | } 35 | } 36 | } 37 | dependencyResolutionManagement { 38 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 39 | repositories { 40 | mavenCentral() 41 | google() 42 | maven { setUrl("https://jitpack.io") } 43 | } 44 | versionCatalogs { 45 | create("androidCommonLibs") { from(files("${rootDir.path}/.config/dependencies-android-common.toml")) } 46 | create("androidBizLibs") { from(files("${rootDir.path}/.config/dependencies-android-biz.toml")) } 47 | create("sharedCommonLibs") { from(files("${rootDir.path}/.config/dependencies-shared-common.toml")) } 48 | } 49 | } 50 | 51 | rootProject.name = "config-plugin" 52 | include( 53 | ":app", 54 | ":common:common", 55 | ":framework:utils", 56 | ) 57 | includeBuild("plugins") 58 | --------------------------------------------------------------------------------