diff --git a/ruler-cli/src/main/java/com/spotify/ruler/cli/RulerCli.kt b/ruler-cli/src/main/java/com/spotify/ruler/cli/RulerCli.kt index bc0ef5af..085496e3 100644 --- a/ruler-cli/src/main/java/com/spotify/ruler/cli/RulerCli.kt +++ b/ruler-cli/src/main/java/com/spotify/ruler/cli/RulerCli.kt @@ -24,6 +24,8 @@ import com.github.ajalt.clikt.parameters.options.required import com.github.ajalt.clikt.parameters.types.file import com.spotify.ruler.common.BaseRulerTask import com.spotify.ruler.common.FEATURE_NAME +import com.spotify.ruler.common.apk.ApkCreator +import com.spotify.ruler.common.apk.InjectedToolApkCreator import com.spotify.ruler.common.dependency.ArtifactResult import com.spotify.ruler.common.dependency.DependencyComponent import com.spotify.ruler.common.dependency.DependencyEntry @@ -38,8 +40,11 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import java.io.File +import java.util.logging.Level +import java.util.logging.Logger class RulerCli : CliktCommand(), BaseRulerTask { + private val logger = Logger.getLogger("Ruler") private val dependencyMap by option().file().required() private val rulerConfigJson by option().file().required() private val apkFile by option().file().required() @@ -47,6 +52,8 @@ class RulerCli : CliktCommand(), BaseRulerTask { private val mappingFile: File? by option().file() private val resourceMappingFile: File? by option().file() private val unstrippedNativeFiles: List by option().file().multiple() + private val aapt2Tool: File? by option().file() + override fun print(content: String) = echo(content) override fun provideMappingFile() = mappingFile @@ -60,7 +67,7 @@ class RulerCli : CliktCommand(), BaseRulerTask { val json = Json.decodeFromStream(rulerConfigJson.inputStream()) RulerConfig( projectPath = json.projectPath, - apkFilesMap = mapOf(FEATURE_NAME to listOf(apkFile)), + apkFilesMap = createApkFile(json.projectPath, json.deviceSpec!!), reportDir = reportDir, ownershipFile = json.ownershipFile?.let { File(it) }, staticDependenciesFile = json.staticComponentsPath?.let { File(it) }, @@ -100,8 +107,40 @@ class RulerCli : CliktCommand(), BaseRulerTask { override fun provideDependencies(): Map> = dependencies override fun run() { + logger.log(Level.INFO, """ + ~~~~~ Starting Ruler ~~~~~ + Using Dependency Map: ${dependencyMap.path} + Using Ruler Config: ${rulerConfigJson.path} + Using App File: ${apkFile.path} + Using Proguard Mapping File: ${mappingFile?.path} + Using Resource Mapping File: ${resourceMappingFile?.path} + Using AAPT2: ${aapt2Tool?.path} + Writing reports to: ${reportDir.path} + """.trimIndent()) super.run() } + + private fun createApkFile(projectPath: String, deviceSpec: DeviceSpec): Map> { + + val apkCreator = if (aapt2Tool != null) { + InjectedToolApkCreator(aapt2Tool!!.toPath()) + } else { + ApkCreator(File(projectPath)) + } + + return if (apkFile.extension == "apk") { + mapOf(FEATURE_NAME to listOf(apkFile)) + } else { + apkCreator.createSplitApks( + apkFile, + deviceSpec, + File(projectPath).resolve(File("tmp")).apply { + mkdir() + } + ) + } + } + } @Serializable diff --git a/ruler-cli/src/test/resources/rulerConfig.json b/ruler-cli/src/test/resources/rulerConfig.json index 1138759d..525b2da2 100644 --- a/ruler-cli/src/test/resources/rulerConfig.json +++ b/ruler-cli/src/test/resources/rulerConfig.json @@ -4,6 +4,12 @@ "variantName": "release", "versionName": "1.0.0" }, + "deviceSpec": { + "supportedAbis": ["arm64-v8a"], + "supportedLocales": ["en"], + "screenDensity": 480, + "sdkVersion": 27 + }, "defaultOwner": "main_activity", "omitFileBreakdown": false, "ownershipFile": "src/test/resources/test_ownership.yaml", diff --git a/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/apk/ApkCreator.kt b/ruler-common/src/main/java/com/spotify/ruler/common/apk/ApkCreator.kt similarity index 95% rename from ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/apk/ApkCreator.kt rename to ruler-common/src/main/java/com/spotify/ruler/common/apk/ApkCreator.kt index 2959348c..40110a0c 100644 --- a/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/apk/ApkCreator.kt +++ b/ruler-common/src/main/java/com/spotify/ruler/common/apk/ApkCreator.kt @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.spotify.ruler.plugin.apk +package com.spotify.ruler.common.apk import com.android.SdkConstants import com.android.build.gradle.internal.SdkLocator @@ -47,7 +47,7 @@ import java.util.concurrent.TimeUnit * * @param rootDir Root directory of the Gradle project, needed to look up the path of certain binaries. */ -class ApkCreator(private val rootDir: File) { +open class ApkCreator(private val rootDir: File) { private val rulerDebugKey = "rulerDebug.keystore" private val rulerKeystorePassword = "rulerpassword" @@ -91,7 +91,7 @@ class ApkCreator(private val rootDir: File) { } /** Finds and returns the location of the aapt2 executable. */ - private fun getAapt2Location(): Path { + open fun getAapt2Location(): Path { val sdkLocation = getAndroidSdkLocation() val sdkHandler = AndroidSdkHandler.getInstance(AndroidLocationsSingleton, sdkLocation) val progressIndicator = object : ProgressIndicatorAdapter() { /* No progress reporting */ } @@ -133,3 +133,7 @@ class ApkCreator(private val rootDir: File) { const val BASE_FEATURE_NAME = "base" } } + +class InjectedToolApkCreator(private val aapt2Tool: Path): ApkCreator(File("")) { + override fun getAapt2Location(): Path = aapt2Tool +} diff --git a/ruler-common/src/main/java/com/spotify/ruler/common/dependency/DependencySanitizer.kt b/ruler-common/src/main/java/com/spotify/ruler/common/dependency/DependencySanitizer.kt index 2bb11abc..14021f7a 100644 --- a/ruler-common/src/main/java/com/spotify/ruler/common/dependency/DependencySanitizer.kt +++ b/ruler-common/src/main/java/com/spotify/ruler/common/dependency/DependencySanitizer.kt @@ -58,9 +58,14 @@ class DependencySanitizer(private val classNameSanitizer: ClassNameSanitizer) { } } - /** Determines the correct component type for a given [entry]. */ + private val versionRegex = Regex("^\\d+\\.\\d+\\.\\d.*") + + /** + * Determines the correct component type for a given [entry]. + * Assuming that all external dependencies do have a version number in the format XX.XX.XX + * */ private fun getComponentType(entry: DependencyEntry): ComponentType = when { - entry.component.startsWith(':') -> ComponentType.INTERNAL - else -> ComponentType.EXTERNAL + versionRegex.containsMatchIn(entry.component.substringAfterLast(":","")) -> ComponentType.EXTERNAL + else -> ComponentType.INTERNAL } } diff --git a/ruler-gradle-plugin/src/main/resources/rulerDebug.keystore b/ruler-common/src/main/resources/rulerDebug.keystore similarity index 100% rename from ruler-gradle-plugin/src/main/resources/rulerDebug.keystore rename to ruler-common/src/main/resources/rulerDebug.keystore diff --git a/ruler-gradle-plugin/src/test/kotlin/com/spotify/ruler/plugin/ApkCreatorTest.kt b/ruler-common/src/test/kotlin/com/spotify/ruler/common/apk/ApkCreatorTest.kt similarity index 95% rename from ruler-gradle-plugin/src/test/kotlin/com/spotify/ruler/plugin/ApkCreatorTest.kt rename to ruler-common/src/test/kotlin/com/spotify/ruler/common/apk/ApkCreatorTest.kt index 7b5c9b86..23c11afe 100644 --- a/ruler-gradle-plugin/src/test/kotlin/com/spotify/ruler/plugin/ApkCreatorTest.kt +++ b/ruler-common/src/test/kotlin/com/spotify/ruler/common/apk/ApkCreatorTest.kt @@ -14,11 +14,10 @@ * limitations under the License. */ -package com.spotify.ruler.plugin +package com.spotify.ruler.common.apk import com.google.common.truth.Truth.assertThat import com.spotify.ruler.common.models.DeviceSpec -import com.spotify.ruler.plugin.apk.ApkCreator import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir import java.io.File diff --git a/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/RulerTask.kt b/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/RulerTask.kt index 021eb682..bdf0e34a 100644 --- a/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/RulerTask.kt +++ b/ruler-gradle-plugin/src/main/kotlin/com/spotify/ruler/plugin/RulerTask.kt @@ -16,7 +16,7 @@ package com.spotify.ruler.plugin -import com.spotify.ruler.plugin.apk.ApkCreator +import com.spotify.ruler.common.apk.ApkCreator import com.spotify.ruler.plugin.dependency.EntryParser import com.spotify.ruler.common.BaseRulerTask import com.spotify.ruler.common.dependency.DependencyComponent