@@ -115,21 +115,27 @@ internal object PatchCommand : Runnable {
115
115
this .outputFilePath = outputFilePath?.absoluteFile
116
116
}
117
117
118
- @CommandLine.Option (
119
- names = [" -i" , " --install" ],
120
- description = [" Serial of the ADB device to install to. If not specified, the first connected device will be used." ],
121
- // Empty string to indicate that the first connected device should be used.
122
- fallbackValue = " " ,
123
- arity = " 0..1" ,
124
- )
125
- private var deviceSerial: String? = null
126
-
127
- @CommandLine.Option (
128
- names = [" --mount" ],
129
- description = [" Install the patched APK file by mounting." ],
130
- showDefaultValue = ALWAYS ,
131
- )
132
- private var mount: Boolean = false
118
+ @ArgGroup(exclusive = false , multiplicity = " 0..1" )
119
+ internal var installation: Installation ? = null
120
+
121
+ internal class Installation {
122
+ @CommandLine.Option (
123
+ names = [" -i" , " --install" ],
124
+ required = true ,
125
+ description = [" Serial of the ADB device to install to. If not specified, the first connected device will be used." ],
126
+ fallbackValue = " " , // Empty string is used to select the first of connected devices.
127
+ arity = " 0..1" ,
128
+ )
129
+ internal var deviceSerial: String? = null
130
+
131
+ @CommandLine.Option (
132
+ names = [" --mount" ],
133
+ required = false ,
134
+ description = [" Install the patched APK file by mounting." ],
135
+ showDefaultValue = ALWAYS ,
136
+ )
137
+ internal var mount: Boolean = false
138
+ }
133
139
134
140
@CommandLine.Option (
135
141
names = [" --keystore" ],
@@ -245,11 +251,11 @@ internal object PatchCommand : Runnable {
245
251
keyStoreFilePath ? : outputFilePath.parentFile
246
252
.resolve(" ${outputFilePath.nameWithoutExtension} .keystore" )
247
253
248
- val installer = if (deviceSerial != null ) {
249
- val deviceSerial = deviceSerial!! .ifEmpty { null }
254
+ val installer = if (installation?. deviceSerial != null ) {
255
+ val deviceSerial = installation?. deviceSerial!! .ifEmpty { null }
250
256
251
257
try {
252
- if (mount) {
258
+ if (installation?. mount == true ) {
253
259
AdbRootInstaller (deviceSerial)
254
260
} else {
255
261
AdbInstaller (deviceSerial)
@@ -332,7 +338,7 @@ internal object PatchCommand : Runnable {
332
338
apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true ).apply {
333
339
patcherResult.applyTo(this )
334
340
}.let { patchedApkFile ->
335
- if (! mount) {
341
+ if (installation?. mount != true ) {
336
342
ApkUtils .signApk(
337
343
patchedApkFile,
338
344
outputFilePath,
@@ -355,7 +361,7 @@ internal object PatchCommand : Runnable {
355
361
356
362
// region Install.
357
363
358
- deviceSerial?.let {
364
+ installation?. deviceSerial?.let {
359
365
runBlocking {
360
366
when (val result = installer!! .install(Installer .Apk (outputFilePath, packageName))) {
361
367
RootInstallerResult .FAILURE -> logger.severe(" Failed to mount the patched APK file" )
0 commit comments