diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 979c641d4..f27c86471 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -12,7 +12,7 @@ object Versions { val axmlParser = "1.0" val bugsnag = "3.6.1" - val androidGradleVersion = "8.0.2" + val androidGradleVersion = "8.4.2" val spek = "1.1.5" val junit5 = "5.6.0" @@ -66,6 +66,7 @@ object Libraries { val ktorAuth = "io.ktor:ktor-client-auth-jvm:${Versions.ktor}" val ktorApacheClient = "io.ktor:ktor-client-apache:${Versions.ktor}" val axmlParser = "com.shazam:axmlparser:${Versions.axmlParser}" + val apkSig = "com.android.tools.build:apksig:${Versions.androidGradleVersion}" val gson = "com.google.code.gson:gson:${Versions.gson}" val apacheCommonsText = "org.apache.commons:commons-text:${Versions.apacheCommonsText}" val apacheCommonsIO = "commons-io:commons-io:${Versions.apacheCommonsIO}" diff --git a/cli/build.gradle.kts b/cli/build.gradle.kts index 69ef122af..cb54f09f6 100644 --- a/cli/build.gradle.kts +++ b/cli/build.gradle.kts @@ -59,14 +59,14 @@ buildConfig { } sourceSets["main"].java { - srcDirs.add(File(buildDir, "gen")) + srcDirs.add(layout.buildDirectory.dir("gen").get().asFile) } // At the moment for non-Android projects you need to explicitly // mark the generated code for correct highlighting in IDE. idea { module { - sourceDirs = sourceDirs + file("${project.buildDir}/gen/buildconfig/src/main") - generatedSourceDirs = generatedSourceDirs + file("${project.buildDir}/gen/buildconfig/src/main") + sourceDirs = sourceDirs + project.layout.buildDirectory.dir("gen/buildconfig/src/main").get().asFile + generatedSourceDirs = generatedSourceDirs + project.layout.buildDirectory.dir("gen/buildconfig/src/main").get().asFile } } diff --git a/marathon-gradle-plugin/src/main/kotlin/com/malinskiy/marathon/ConfigurationFactory.kt b/marathon-gradle-plugin/src/main/kotlin/com/malinskiy/marathon/ConfigurationFactory.kt index 443ef9d92..262cee6cd 100644 --- a/marathon-gradle-plugin/src/main/kotlin/com/malinskiy/marathon/ConfigurationFactory.kt +++ b/marathon-gradle-plugin/src/main/kotlin/com/malinskiy/marathon/ConfigurationFactory.kt @@ -72,7 +72,7 @@ private fun createConfiguration( private fun getOutputDirectory(project: Project, extensionConfig: MarathonExtension): File = extensionConfig.baseOutputDir?.let { File(it) } - ?: project.buildDir.resolve("reports/marathon") + ?: project.layout.buildDirectory.dir("reports/marathon").get().asFile private fun createAndroidConfiguration( extension: MarathonExtension, diff --git a/vendor/vendor-android/base/build.gradle.kts b/vendor/vendor-android/base/build.gradle.kts index 56b00fa50..cbc706d39 100644 --- a/vendor/vendor-android/base/build.gradle.kts +++ b/vendor/vendor-android/base/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(Libraries.kotlinLogging) implementation(Libraries.dexTestParser) implementation(Libraries.axmlParser) + implementation(Libraries.apkSig) implementation(Libraries.jacksonAnnotations) implementation(Libraries.scalr) implementation(project(":core")) diff --git a/vendor/vendor-android/base/src/main/kotlin/com/malinskiy/marathon/android/executor/ApkFileHasher.kt b/vendor/vendor-android/base/src/main/kotlin/com/malinskiy/marathon/android/executor/ApkFileHasher.kt index f8f072a31..8d00d750b 100644 --- a/vendor/vendor-android/base/src/main/kotlin/com/malinskiy/marathon/android/executor/ApkFileHasher.kt +++ b/vendor/vendor-android/base/src/main/kotlin/com/malinskiy/marathon/android/executor/ApkFileHasher.kt @@ -1,40 +1,28 @@ package com.malinskiy.marathon.android +import com.android.apksig.ApkVerifier import com.malinskiy.marathon.io.FileHasher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.File -import java.nio.file.FileSystems -import java.nio.file.Files -import java.nio.file.Paths +import java.security.MessageDigest +import java.util.HexFormat /** * Extracts digest of APK contents from signature file */ class ApkFileHasher : FileHasher { - override suspend fun getHash(file: File): String = withContext(Dispatchers.IO) { - val zipFile = Paths.get(file.absolutePath) - - FileSystems.newFileSystem(zipFile, null as ClassLoader?) - .use { fileSystem -> - val certFile = fileSystem.getPath(SIGNATURE_FILE_PATH) - Files.newInputStream(certFile) - .use { - it - .bufferedReader() - .lineSequence() - .firstOrNull { line -> line.contains(DIGEST_MANIFEST_PROPERTY) } - ?.substringAfter(PROPERTY_DELIMITER) - ?.trim() - ?: throw IllegalArgumentException("Manifest digest not found") - } - } - } + val sha256digest = MessageDigest.getInstance("SHA-256") - private companion object { - private const val SIGNATURE_FILE_PATH = "META-INF/CERT.SF" - private const val DIGEST_MANIFEST_PROPERTY = "-Digest-Manifest: " - private const val PROPERTY_DELIMITER = ": " + override suspend fun getHash(file: File): String = withContext(Dispatchers.IO) { + val result = ApkVerifier.Builder(file).build().verify() + if (result.signerCertificates.isNotEmpty()) { + val certificate = result.signerCertificates.first() + // https://cs.android.com/android/platform/superproject/main/+/main:tools/apksig/src/apksigner/java/com/android/apksigner/ApkSignerTool.java;l=1151;drc=d5137445c0d4067406cb3e38aade5507ff2fcd16 + HexFormat.of().formatHex(sha256digest.digest(certificate.encoded)) + } else { + throw IllegalArgumentException("Certificate not found") + } } } diff --git a/vendor/vendor-ios/src/test/kotlin/com/malinskiy/marathon/ios/DerivedDataManagerSpek.kt b/vendor/vendor-ios/src/test/kotlin/com/malinskiy/marathon/ios/DerivedDataManagerSpek.kt index 45d6ec177..9ba52c8f2 100644 --- a/vendor/vendor-ios/src/test/kotlin/com/malinskiy/marathon/ios/DerivedDataManagerSpek.kt +++ b/vendor/vendor-ios/src/test/kotlin/com/malinskiy/marathon/ios/DerivedDataManagerSpek.kt @@ -53,6 +53,7 @@ object DerivedDataManagerSpek : Spek( "/root/.ssh/authorized_keys", BindMode.READ_WRITE ) + .withEnv("PASSWORD", "pass") .withExposedPorts(22, 873) container.start()