11import org.jetbrains.kotlin.gradle.dsl.JvmTarget
22
33plugins {
4- alias(libs.plugins.kotlin)
4+ alias(libs.plugins.kotlin.jvm)
5+ alias(libs.plugins.kotlin.compose)
56 alias(libs.plugins.kotlin.serialization)
7+ alias(libs.plugins.compose)
68 alias(libs.plugins.shadow)
79 application
810 `maven- publish`
@@ -11,10 +13,33 @@ plugins {
1113
1214group = " app.morphe"
1315
16+ // ============================================================================
17+ // JVM / Kotlin Configuration
18+ // ============================================================================
19+ kotlin {
20+ jvmToolchain {
21+ languageVersion.set(JavaLanguageVersion .of(17 ))
22+ vendor.set(JvmVendorSpec .ADOPTIUM )
23+ }
24+ compilerOptions {
25+ jvmTarget.set(JvmTarget .JVM_17 )
26+ }
27+ }
28+
29+ // ============================================================================
30+ // Application Entry Point
31+ // ============================================================================
32+ // Shadow JAR reads this for Main-Class manifest attribute.
33+ //
34+ // No args / double-click → GUI (Compose Desktop)
35+ // With args (terminal) → CLI (PicoCLI)
1436application {
15- mainClass = " app.morphe.cli.command.MainCommandKt "
37+ mainClass.set( " app.morphe.MorpheLauncherKt " )
1638}
1739
40+ // ============================================================================
41+ // Repositories
42+ // ============================================================================
1843repositories {
1944 mavenLocal()
2045 mavenCentral()
@@ -32,49 +57,71 @@ repositories {
3257 maven { url = uri(" https://jitpack.io" ) }
3358}
3459
35- val apkEditorLib by configurations.creating
36-
37- val strippedApkEditorLib by tasks.registering(org.gradle.jvm.tasks.Jar ::class ) {
38- archiveFileName.set(" APKEditor-cli.jar" )
39- duplicatesStrategy = DuplicatesStrategy .EXCLUDE
40- doFirst {
41- from(apkEditorLib.resolve().map { zipTree(it) })
42- }
43- exclude(
44- " org/xmlpull/**" ,
45- " antlr/**" ,
46- " org/antlr/**" ,
47- " com/beust/jcommander/**" ,
48- " javax/annotation/**" ,
49- " smali.properties" ,
50- " baksmali.properties"
51- )
52- }
53-
5460dependencies {
5561 api(libs.morphe.patcher)
62+ implementation(libs.arsclib)
5663 implementation(libs.morphe.library)
57- implementation(libs.kotlinx.coroutines.core)
58- implementation(libs.kotlinx.serialization.json)
5964 implementation(libs.picocli)
60- apkEditorLib(files(" $rootDir /libs/APKEditor-1.4.7.jar" ))
61- implementation(files(strippedApkEditorLib))
6265
66+ // -- Compose Desktop ---------------------------------------------------
67+ // Platform-independent: single JAR runs on all supported OSes.
68+ // Skiko auto-detects the OS at runtime and loads the correct native library.
69+ implementation(compose.desktop.macos_arm64)
70+ implementation(compose.desktop.macos_x64)
71+ implementation(compose.desktop.linux_x64)
72+ implementation(compose.desktop.linux_arm64)
73+ implementation(compose.desktop.windows_x64)
74+ implementation(compose.components.resources)
75+ @Suppress(" DEPRECATION" )
76+ implementation(compose.material3)
77+ implementation(compose.materialIconsExtended)
78+
79+ // -- Async / Serialization ---------------------------------------------
80+ implementation(libs.kotlinx.coroutines.core)
81+ implementation(libs.kotlinx.coroutines.swing)
82+ implementation(libs.kotlinx.serialization.json)
83+ // testImplementation(libs.kotlin.test)
84+ // }
85+
86+ // -- Networking (GUI) --------------------------------------------------
87+ implementation(libs.ktor.client.core)
88+ implementation(libs.ktor.client.cio)
89+ implementation(libs.ktor.client.content.negotiation)
90+ implementation(libs.ktor.serialization.kotlinx.json)
91+ implementation(libs.ktor.client.logging)
92+
93+ // -- DI / Navigation (GUI) ---------------------------------------------
94+ implementation(platform(libs.koin.bom))
95+ implementation(libs.koin.core)
96+ implementation(libs.koin.compose)
97+
98+ implementation(libs.voyager.navigator)
99+ implementation(libs.voyager.screenmodel)
100+ implementation(libs.voyager.koin)
101+ implementation(libs.voyager.transitions)
102+
103+ // -- APK Parsing (GUI) -------------------------------------------------
104+ implementation(libs.apk.parser)
105+
106+ // -- Testing -----------------------------------------------------------
63107 testImplementation(libs.kotlin.test)
64108 testImplementation(libs.junit.params)
109+ testImplementation(libs.mockk)
65110}
66111
67- kotlin {
68- compilerOptions {
69- jvmTarget.set(JvmTarget .JVM_11 )
112+ // ============================================================================
113+ // Tasks
114+ // ============================================================================
115+ tasks {
116+ jar {
117+ manifest {
118+ attributes(
119+ " Implementation-Title" to project.name,
120+ " Implementation-Version" to project.version
121+ )
122+ }
70123 }
71- }
72-
73- java {
74- targetCompatibility = JavaVersion .VERSION_11
75- }
76124
77- tasks {
78125 test {
79126 useJUnitPlatform()
80127 testLogging {
@@ -83,9 +130,15 @@ tasks {
83130 }
84131
85132 processResources {
86- expand(" projectVersion" to project.version)
133+ // Only expand properties files, not binary files like PNG/ICO
134+ filesMatching(" **/*.properties" ) {
135+ expand(" projectVersion" to project.version)
136+ }
87137 }
88138
139+ // -------------------------------------------------------------------------
140+ // Shadow JAR — the only distribution artifact
141+ // -------------------------------------------------------------------------
89142 shadowJar {
90143 exclude(
91144 " /prebuilt/linux/aapt" ,
@@ -95,14 +148,33 @@ tasks {
95148 minimize {
96149 exclude(dependency(" org.bouncycastle:.*" ))
97150 exclude(dependency(" app.morphe:morphe-patcher" ))
151+ // Ktor uses ServiceLoader
152+ exclude(dependency(" io.ktor:.*" ))
153+ // Koin uses reflection
154+ exclude(dependency(" io.insert-koin:.*" ))
155+ // Coroutines Swing provides Dispatchers.Main via ServiceLoader
156+ exclude(dependency(" org.jetbrains.kotlinx:kotlinx-coroutines-swing" ))
98157 }
158+
159+ mergeServiceFiles()
160+ }
161+
162+ distTar {
163+ duplicatesStrategy = DuplicatesStrategy .EXCLUDE
164+ }
165+
166+ distZip {
167+ duplicatesStrategy = DuplicatesStrategy .EXCLUDE
99168 }
100169
101170 publish {
102171 dependsOn(shadowJar)
103172 }
104173}
105174
175+ // ============================================================================
176+ // Publishing / Signing
177+ // ============================================================================
106178// Needed by gradle-semantic-release-plugin.
107179// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
108180
0 commit comments