diff --git a/app/src/debug/res/values-ru/strings.xml b/app/src/debug/res/values-ru/strings.xml index 682b552975..878fbcbef1 100644 --- a/app/src/debug/res/values-ru/strings.xml +++ b/app/src/debug/res/values-ru/strings.xml @@ -3,4 +3,4 @@ DebugTangem - \ No newline at end of file + diff --git a/app/src/debug_beta/res/values-ru/strings.xml b/app/src/debug_beta/res/values-ru/strings.xml index 3ae149049f..7fd995cb02 100644 --- a/app/src/debug_beta/res/values-ru/strings.xml +++ b/app/src/debug_beta/res/values-ru/strings.xml @@ -3,4 +3,4 @@ BetaTangem - \ No newline at end of file + diff --git a/app/src/debug_beta/res/values/strings.xml b/app/src/debug_beta/res/values/strings.xml index 3ae149049f..7fd995cb02 100644 --- a/app/src/debug_beta/res/values/strings.xml +++ b/app/src/debug_beta/res/values/strings.xml @@ -3,4 +3,4 @@ BetaTangem - \ No newline at end of file + diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index d5f3e649d4..c0b6c9cc13 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -1,6 +1,5 @@ - @@ -17,5 +16,4 @@ - diff --git a/buildSrc/src/main/java/ConfigFieldBuilder.kt b/buildSrc/src/main/java/ConfigFieldBuilder.kt deleted file mode 100644 index 596ae047d6..0000000000 --- a/buildSrc/src/main/java/ConfigFieldBuilder.kt +++ /dev/null @@ -1,36 +0,0 @@ -typealias ConfigFieldBuilder = (String, String, String) -> Unit - -class BuildConfigFieldFactory( - private val fields: List, - private val builder: ConfigFieldBuilder, -) { - fun create() { - fields.forEach { field -> builder(field.type, field.name, field.value) } - } -} - -/** - * Build config field - * - * @property type field type - * @property name field name - * @property value field value - */ -sealed class Field(val type: String, val name: String, val value: String) { - - class Environment(value: String) : Field(type = "String", name = "ENVIRONMENT", value = "\"$value\"") - - class TestActionEnabled(isEnabled: Boolean) : Field( - type = "Boolean", - name = "TEST_ACTION_ENABLED", - value = isEnabled.toString(), - ) - - class LogEnabled(isEnabled: Boolean) : Field(type = "Boolean", name = "LOG_ENABLED", value = isEnabled.toString()) - - class TesterMenuAvailability(isEnabled: Boolean) : Field( - type = "Boolean", - name = "TESTER_MENU_ENABLED", - value = isEnabled.toString(), - ) -} \ No newline at end of file diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml new file mode 100644 index 0000000000..8e68824663 --- /dev/null +++ b/gradle/dependencies.toml @@ -0,0 +1,201 @@ +# docs https://docs.gradle.org/current/userguide/platforms.html +# TODO: update versions refs https://tangem.atlassian.net/browse/AND-3195 + +[versions] +# region Classpath +androidGradlePlugin = "7.4.2" +firebaseCrashlytics = "2.9.4" +googleServices = "4.3.10" +kotlin = "1.8.10" +# endregion Classpath + +# region AndroidX +androidxActivityCompose = "1.5.0" +androidxAppCompat = "1.5.1" +androidxBrowser = "1.4.0" +androidxConstraintLayout = "2.1.4" +androidxCore = "1.9.0" +androidxFragment = "1.5.3" +androidxLifecycle = "2.5.1" +# endregion AndroidX + +# region Compose +compose-compiler = "1.4.3" +compose-runtime = "1.3.3" +compose-foundation = "1.3.1" +compose-material = "1.3.1" +compose-constraint = "1.0.1" +compose-navigation = "2.5.3" +compose-accompanist = "0.28.0" +# endregion Compose + +# region Other libraries +amplitude = "2.36.1" +appsflyer = "6.5.1" +armadillo = "0.9.0" +coil = "2.1.0" +compose-shimmer = "1.0.3" +coroutine = "1.5.2" +desugarJdkLibs = "1.1.5" +firebase = "26.0.0" +googleMaterialComponent = "1.6.1" +googlePlayCore = "1.10.3" +googlePlayCoreKtx = "1.8.1" +googlePlayServicesWallet = "19.1.0" +hilt = "2.44" +hilt-navigation = "1.0.0" +jodatime = "2.12.1" +krateSharedPref = "2.0.0" +kotsonGsonExt = "2.5.0" +lottie = "3.4.0" +moshi = "1.12.0" +okhttp = "4.9.3" +otaliastudiosCameraView = "2.6.3" +rekotlin = "1.0.4" +retrofit = "2.8.1" +retrofitMoshiConverter = "2.6.0" +shopifyBuySdk = "12.0.0" +spongycastleCryptoCore = "1.58.0.0" +timber = "4.7.1" +viewBindingDelegate = "1.5.6" +xmlShimmer = "1.1.3" +zendeskChat = "3.3.5" +zendeskMessaging = "5.2.4" +zxingQrBarcodeScanner = "1.9.8" +zxingQrCode = "3.3.3" +mviCore = "1.3.1" +kotlinSerialization = "1.4.1" +# endregion Other libraries + +# region Tangem +tangemBlockchainSdk = "develop-174" +# tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds + +tangemCardSdk = "develop-200" +# tangemCardSgk = "0.0.1" # Keep it! - used for local builds +# endregion Tangem + +# region Tools +detektComposeRules = "1.2.2" +detekt = "1.21.0" +# endregion Tools + +# region Testing +espresso = "3.4.0" +junit = "4.13.2" +truth = "1.1.3" +junitAndroidExt = "1.1.3" +# endregion Testing + +[plugins] +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } +firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlytics" } +google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" } +hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } + +[libraries] +# region Classpath +# Used for plugins +gradle-android = { module = "com.android.tools.build:gradle", version.ref = "androidGradlePlugin" } +gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +gradle-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } +gradle-firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebaseCrashlytics" } +# end region Classpath + +# region AndroidX +androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivityCompose" } +androidx-appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidxAppCompat" } +androidx-browser = { module = "androidx.browser:browser", version.ref = "androidxBrowser" } +androidx-constraintLayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidxConstraintLayout" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidxCore" } +androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "androidxFragment" } +lifecycle-common-java8 = { module = "androidx.lifecycle:lifecycle-common-java8", version.ref = "androidxLifecycle" } +lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidxLifecycle" } +lifecycle-viewModel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidxLifecycle" } +# region AndroidX + +# region Compose +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose-runtime" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose-runtime" } +compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose-runtime" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose-foundation" } +compose-material = { module = "androidx.compose.material:material", version.ref = "compose-material" } +compose-constraintLayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "compose-constraint" } +compose-shimmer = { module = "com.valentinilk.shimmer:compose-shimmer", version.ref = "compose-shimmer" } +compose-coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } +compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "compose-navigation" } +compose-navigation-hilt = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hilt-navigation" } +compose-accompanist-appCompatTheme = { module = "com.google.accompanist:accompanist-appcompat-theme", version.ref = "compose-accompanist" } +compose-accompanist-systemUiController = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "compose-accompanist" } +compose-accompanist-webView = { module = "com.google.accompanist:accompanist-webview", version.ref = "compose-accompanist" } +# endregion Compose + +# region Firebase +firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase" } +firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx" } +firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx" } +# endregion Firebase + +# region Tangem +tangem-blockchain = { module = "com.tangem:blockchain", version.ref = "tangemBlockchainSdk" } +tangem-card-android = { module = "com.tangem.tangem-sdk-kotlin:android", version.ref = "tangemCardSdk" } +tangem-card-core = { module = "com.tangem.tangem-sdk-kotlin:core", version.ref = "tangemCardSdk" } +# endregion Tangem + +# region Detekt +detekt-compose = { module = "ru.kode:detekt-rules-compose", version.ref = "detektComposeRules" } +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } +# ndregion Detekt + +# region Test +test-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } +test-junit = { module = "junit:junit", version.ref = "junit" } +test-junit-android = { module = "androidx.test.ext:junit", version.ref = "junitAndroidExt" } +test-truth = { module = "com.google.truth:truth", version.ref = "truth" } +# endregion Test + +# region Other +amplitude = { module = "com.amplitude:android-sdk", version.ref = "amplitude" } +appsflyer = { module = "com.appsflyer:af-android-sdk", version.ref = "appsflyer" } +armadillo = { module = "at.favre.lib:armadillo", version.ref = "armadillo" } +coil = { module = "io.coil-kt:coil", version.ref = "coil" } +kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutine" } +desugar = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugarJdkLibs" } +googlePlay-core = { module = "com.google.android.play:core", version.ref = "googlePlayCore" } +googlePlay-core-ktx = { module = "com.google.android.play:core-ktx", version.ref = "googlePlayCoreKtx" } +googlePlay-services-wallet = { module = "com.google.android.gms:play-services-wallet", version.ref = "googlePlayServicesWallet" } +hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } +hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "hilt" } +hilt-kapt = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } +hilt-navigation = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } +jodatime = { module = "joda-time:joda-time", version.ref = "jodatime" } +krateSharedPref = { module = "hu.autsoft:krate", version.ref = "krateSharedPref" } +kotsonGson = { module = "com.github.salomonbrys.kotson:kotson", version.ref = "kotsonGsonExt" } +lottie = { module = "com.airbnb.android:lottie", version.ref = "lottie" } +material = { module = "com.google.android.material:material", version.ref = "googleMaterialComponent" } +moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" } +moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } +okHttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } +okHttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } +otaliastudiosCameraView = { module = "com.otaliastudios:cameraview", version.ref = "otaliastudiosCameraView" } +shopify-buy = { module = "com.shopify.mobilebuysdk:buy3", version.ref = "shopifyBuySdk" } +spongecastle-core = { module = "com.madgag.spongycastle:core", version.ref = "spongycastleCryptoCore" } +reKotlin = { module = "org.rekotlin:rekotlin", version.ref = "rekotlin" } +retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } +retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofitMoshiConverter" } +timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } +viewBindingDelegate = { module = "com.github.kirich1409:viewbindingpropertydelegate-noreflection", version.ref = "viewBindingDelegate" } +xmlShimmer = { module = "com.github.skydoves:androidveil", version.ref = "xmlShimmer" } +zendesk-chat = { module = "com.zendesk:chat", version.ref = "zendeskChat" } +zendesk-messaging = { module = "com.zendesk:messaging", version.ref = "zendeskMessaging" } +zxing-qrBarcodeScanner = { module = "me.dm7.barcodescanner:zxing", version.ref = "zxingQrBarcodeScanner" } +zxing-qrCore = { module = "com.google.zxing:core", version.ref = "zxingQrCode" } +mviCore-watcher = { module = "com.github.badoo.mvicore:mvicore-diff", version.ref = "mviCore" } +kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinSerialization" } +# endregion Other diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9ee3ffb21f..ddde06c17d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Oct 21 13:51:19 MSK 2020 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +#Tue Mar 07 14:45:01 MSK 2023 +distributionBase = GRADLE_USER_HOME +distributionUrl = https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionPath = wrapper/dists +zipStorePath = wrapper/dists +zipStoreBase = GRADLE_USER_HOME diff --git a/plugins/configuration/.gitignore b/plugins/configuration/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/plugins/configuration/.gitignore @@ -0,0 +1 @@ +/build diff --git a/plugins/configuration/build.gradle.kts b/plugins/configuration/build.gradle.kts new file mode 100644 index 0000000000..c2ab7a0a54 --- /dev/null +++ b/plugins/configuration/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + `kotlin-dsl` + `java-gradle-plugin` +} + +repositories { + google() + mavenCentral() +} + +configure { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + implementation(deps.gradle.kotlin) + implementation(deps.gradle.android) + implementation(deps.gradle.detekt) +} + +gradlePlugin { + plugins.register("configuration") { + id = "configuration" + implementationClass = "com.tangem.plugin.configuration.ConfigurationPlugin" + } +} \ No newline at end of file diff --git a/config/detekt/detekt.yml b/plugins/configuration/detekt.yml similarity index 100% rename from config/detekt/detekt.yml rename to plugins/configuration/detekt.yml diff --git a/plugins/configuration/settings.gradle.kts b/plugins/configuration/settings.gradle.kts new file mode 100644 index 0000000000..0ed5a2e04b --- /dev/null +++ b/plugins/configuration/settings.gradle.kts @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + create("deps") { + from(files("../../gradle/dependencies.toml")) + } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/ConfigurationPlugin.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/ConfigurationPlugin.kt new file mode 100644 index 0000000000..53b9d53e1c --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/ConfigurationPlugin.kt @@ -0,0 +1,30 @@ +package com.tangem.plugin.configuration + +import com.android.build.gradle.AppExtension +import com.android.build.gradle.LibraryExtension +import com.android.build.gradle.internal.plugins.AppPlugin +import com.android.build.gradle.internal.plugins.LibraryPlugin +import com.tangem.plugin.configuration.configurations.configure +import com.tangem.plugin.configuration.configurations.extension.configure +import org.gradle.api.Action +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class ConfigurationPlugin : Plugin { + override fun apply(target: Project) { + target.plugins.all(startConfigurationAction(project = target)) + } + + private fun startConfigurationAction(project: Project) = Action> { + project.configure() + when (this) { + is AppPlugin -> { + project.configure { configure(project) } + } + is LibraryPlugin -> { + project.configure { configure(project) } + } + } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/DetektConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/DetektConfigurations.kt new file mode 100644 index 0000000000..1bcf190ab5 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/DetektConfigurations.kt @@ -0,0 +1,52 @@ +package com.tangem.plugin.configuration.configurations + +import com.tangem.plugin.configuration.utils.findLibrary +import com.tangem.plugin.configuration.utils.findPlugin +import io.gitlab.arturbosch.detekt.CONFIGURATION_DETEKT +import io.gitlab.arturbosch.detekt.CONFIGURATION_DETEKT_PLUGINS +import io.gitlab.arturbosch.detekt.Detekt +import io.gitlab.arturbosch.detekt.extensions.DetektExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType + +internal fun Project.configureDetektRules() { + plugins.apply(findPlugin(alias = CONFIGURATION_DETEKT).pluginId) + extensions.configure { configure(project) } + configureDetektPlugins() + configureDetektTask() +} + +private fun DetektExtension.configure(project: Project) { + parallel = true + ignoreFailures = false + autoCorrect = true + buildUponDefaultConfig = true + config.setFrom(project.rootProject.files("plugins/configuration/detekt.yml")) +} + +private fun Project.configureDetektPlugins() { + listOf( + findLibrary(alias = "detekt-formatting"), + findLibrary(alias = "detekt-compose"), + ).forEach { + dependencies.add(CONFIGURATION_DETEKT_PLUGINS, it) + } +} + +private fun Project.configureDetektTask() { + tasks.withType { + include("**/*.kt") + exclude("**/resources/**", "**/build/**") + reports { + sarif { + required.set(false) + } + txt { + required.set(true) + } + } + + jvmTarget = "11" + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/KotlinConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/KotlinConfigurations.kt new file mode 100644 index 0000000000..9d10cad98d --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/KotlinConfigurations.kt @@ -0,0 +1,16 @@ +package com.tangem.plugin.configuration.configurations + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +internal fun Project.configureKotlinCompilerOptions() { + project.tasks.withType { + kotlinOptions { + jvmTarget = "11" + allWarningsAsErrors = false + // this is required to produce a unique META-INF/*.kotlin_module files + moduleName = project.path.removePrefix(":").replace(':', '-') + } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/ProjectConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/ProjectConfigurations.kt new file mode 100644 index 0000000000..644b1eaead --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/ProjectConfigurations.kt @@ -0,0 +1,8 @@ +package com.tangem.plugin.configuration.configurations + +import org.gradle.api.Project + +internal fun Project.configure() { + configureKotlinCompilerOptions() + configureDetektRules() +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt new file mode 100644 index 0000000000..3817da1027 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt @@ -0,0 +1,94 @@ +package com.tangem.plugin.configuration.configurations.extension + +import com.android.build.gradle.AppExtension +import com.tangem.plugin.configuration.model.AppConfig +import com.tangem.plugin.configuration.model.BuildType +import com.tangem.plugin.configuration.utils.BuildConfigFieldFactory +import org.gradle.api.Project +import com.android.build.gradle.internal.dsl.BuildType as AndroidBuildType + +internal fun AppExtension.configure(project: Project) { + configureCompileSdk() + configureDefaultConfig(project) + configureBuildFeatures() + configureBuildTypes() + configurePackagingOptions() + configureCompose(project) + configureCompilerOptions() +} + +private fun AppExtension.configureDefaultConfig(project: Project) { + defaultConfig { + applicationId = AppConfig.packageName + minSdk = AppConfig.minSdkVersion + targetSdk = AppConfig.targetSdkVersion + + versionCode = if (project.hasProperty("versionCode")) { + (project.property("versionCode") as String).toInt() + } else { + AppConfig.versionCode + } + + versionName = if (project.hasProperty("versionName")) { + project.property("versionName") as String + } else { + AppConfig.versionName + } + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } +} + +// TODO: [REDACTED_JIRA] +private fun AppExtension.configureBuildFeatures() { + buildFeatures.apply { + viewBinding = true + } +} + +private fun AppExtension.configureBuildTypes() { + buildTypes { + BuildType.values().forEach { buildVariant -> + maybeCreate(buildVariant.id).apply { + configureBuildVariant(extension = this@configureBuildTypes, buildVariant) + + BuildConfigFieldFactory( + fields = buildVariant.configFields, + builder = ::buildConfigField, + ).create() + } + } + } +} + +private fun AndroidBuildType.configureBuildVariant(extension: AppExtension, buildType: BuildType) { + when (buildType) { + BuildType.Release -> { + isDebuggable = false + isMinifyEnabled = false + proguardFiles(extension.getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + } + BuildType.Debug -> { + isDebuggable = true + isMinifyEnabled = false + } + BuildType.External -> { + initWith(extension.buildTypes.getByName(BuildType.Release.id)) + signingConfig = extension.signingConfigs.getByName(BuildType.Debug.id) + } + } + + versionNameSuffix = buildType.versionSuffix?.let { "-$it" } + applicationIdSuffix = buildType.appIdSuffix?.let { ".$it" } +} + +private fun AppExtension.configurePackagingOptions() { + packagingOptions { + resources { + excludes += "lib/x86_64/darwin/libscrypt.dylib" + excludes += "lib/x86_64/freebsd/libscrypt.so" + excludes += "lib/x86_64/linux/libscrypt.so" + excludes += "META-INF/gradle/incremental.annotation.processors" + } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/BaseExtensionConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/BaseExtensionConfigurations.kt new file mode 100644 index 0000000000..5d0b3a45e4 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/BaseExtensionConfigurations.kt @@ -0,0 +1,33 @@ +package com.tangem.plugin.configuration.configurations.extension + +import com.android.build.gradle.BaseExtension +import com.tangem.plugin.configuration.model.AppConfig +import com.tangem.plugin.configuration.utils.findVersion +import org.gradle.api.JavaVersion +import org.gradle.api.Project + +internal fun BaseExtension.configureCompileSdk() { + compileSdkVersion(AppConfig.compileSdkVersion) +} + +internal fun BaseExtension.configureCompilerOptions() { + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +internal fun BaseExtension.configureCompose(project: Project) { + val useCompose = with(project.path) { + contains(":ui") || + contains(":presentation") || + contains(":app") || // TODO: [REDACTED_JIRA] + contains(":tester:impl") // TODO: Rename module + } + buildFeatures.compose = useCompose + if (useCompose) { + composeOptions { + kotlinCompilerExtensionVersion = project.findVersion(alias = "compose-compiler").requiredVersion + } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/LibraryExtensionConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/LibraryExtensionConfigurations.kt new file mode 100644 index 0000000000..bc18afa9b9 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/LibraryExtensionConfigurations.kt @@ -0,0 +1,49 @@ +package com.tangem.plugin.configuration.configurations.extension + +import com.android.build.gradle.LibraryExtension +import com.tangem.plugin.configuration.model.AppConfig +import com.tangem.plugin.configuration.model.BuildType +import com.tangem.plugin.configuration.utils.BuildConfigFieldFactory +import org.gradle.api.Project + +internal fun LibraryExtension.configure(project: Project) { + configureCompileSdk() + configureDefaultConfig() + configureBuildTypes() + configurePackagingOptions() + configureCompose(project) + configureCompilerOptions() +} + +private fun LibraryExtension.configureDefaultConfig() { + defaultConfig { + minSdk = AppConfig.minSdkVersion + vectorDrawables { + useSupportLibrary = true + } + } +} + +private fun LibraryExtension.configureBuildTypes() { + buildTypes { + BuildType.values().forEach { buildVariant -> + maybeCreate(buildVariant.id).apply { + BuildConfigFieldFactory( + fields = buildVariant.configFields, + builder = ::buildConfigField, + ).create() + } + } + } +} + +private fun LibraryExtension.configurePackagingOptions() { + packagingOptions { + resources { + excludes += "lib/x86_64/darwin/libscrypt.dylib" + excludes += "lib/x86_64/freebsd/libscrypt.so" + excludes += "lib/x86_64/linux/libscrypt.so" + excludes += "META-INF/gradle/incremental.annotation.processors" + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/java/AppConfig.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt similarity index 75% rename from buildSrc/src/main/java/AppConfig.kt rename to plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt index 5c966326f1..7f12be0c15 100644 --- a/buildSrc/src/main/java/AppConfig.kt +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt @@ -1,4 +1,6 @@ -object AppConfig { +package com.tangem.plugin.configuration.model + +internal object AppConfig { const val packageName = "com.tangem.wallet" const val versionCode = 1 const val versionName = "1.0.0-SNAPSHOT" diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildConfigField.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildConfigField.kt new file mode 100644 index 0000000000..66437a1de5 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildConfigField.kt @@ -0,0 +1,35 @@ +package com.tangem.plugin.configuration.model + +/** + * Build config field + * + * @property type field type + * @property name field name + * @property value field value + */ +internal sealed class BuildConfigField(val type: String, val name: String, val value: String) { + + class Environment(value: String) : BuildConfigField( + type = "String", + name = "ENVIRONMENT", + value = "\"$value\"", + ) + + class TestActionEnabled(isEnabled: Boolean) : BuildConfigField( + type = "Boolean", + name = "TEST_ACTION_ENABLED", + value = isEnabled.toString(), + ) + + class LogEnabled(isEnabled: Boolean) : BuildConfigField( + type = "Boolean", + name = "LOG_ENABLED", + value = isEnabled.toString(), + ) + + class TesterMenuAvailability(isEnabled: Boolean) : BuildConfigField( + type = "Boolean", + name = "TESTER_MENU_ENABLED", + value = isEnabled.toString(), + ) +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildType.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildType.kt new file mode 100644 index 0000000000..16aa46325d --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/BuildType.kt @@ -0,0 +1,72 @@ +package com.tangem.plugin.configuration.model + +internal enum class BuildType( + val id: String, + val appIdSuffix: String? = null, + val versionSuffix: String? = null, + val configFields: List, +) { + + /** + * Production ready build type for clients + * + * Features: + * - Env: prod + * - Signing config: release + * - Proguard + * */ + Release( + id = "release", + configFields = listOf( + BuildConfigField.Environment(value = "prod"), + BuildConfigField.TestActionEnabled(isEnabled = false), + BuildConfigField.LogEnabled(isEnabled = false), + BuildConfigField.TesterMenuAvailability(isEnabled = false), + ), + ), + + /** + * Build type for developers + * + * Features: + * - Env: dev + * - Signing config: debug + * - Debuggable + * - Logs + * - Tester menu + * - Test action + * - Traffic sniffing + * */ + Debug( + id = "debug", + appIdSuffix = "dev", + configFields = listOf( + BuildConfigField.Environment(value = "dev"), + BuildConfigField.TestActionEnabled(isEnabled = true), + BuildConfigField.LogEnabled(isEnabled = true), + BuildConfigField.TesterMenuAvailability(isEnabled = true), + ), + ), + + /** + * Build type for QA and business + * + * Features: + * - Env: prod + * - Signing config: debug + * - Tester menu + * - Test action + * - Proguard + * */ + External( + id = "debug_beta", + appIdSuffix = "debug", + versionSuffix = "debug", + configFields = listOf( + BuildConfigField.Environment(value = "prod"), + BuildConfigField.TestActionEnabled(isEnabled = true), + BuildConfigField.LogEnabled(isEnabled = false), + BuildConfigField.TesterMenuAvailability(isEnabled = true), + ), + ), +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/BuildConfigFieldFactory.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/BuildConfigFieldFactory.kt new file mode 100644 index 0000000000..66485abb14 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/BuildConfigFieldFactory.kt @@ -0,0 +1,14 @@ +package com.tangem.plugin.configuration.utils + +import com.tangem.plugin.configuration.model.BuildConfigField + +private typealias ConfigFieldBuilder = (String, String, String) -> Unit + +internal class BuildConfigFieldFactory( + private val fields: List, + private val builder: ConfigFieldBuilder, +) { + fun create() { + fields.forEach { field -> builder(field.type, field.name, field.value) } + } +} \ No newline at end of file diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionCatalogsUtils.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionCatalogsUtils.kt new file mode 100644 index 0000000000..78cb30e988 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionCatalogsUtils.kt @@ -0,0 +1,28 @@ +package com.tangem.plugin.configuration.utils + +import org.gradle.api.Project +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.artifacts.VersionConstraint +import org.gradle.kotlin.dsl.getByType +import org.gradle.plugin.use.PluginDependency +import kotlin.jvm.optionals.getOrNull + +private val Project.depsVersionCatalog: VersionCatalog + get() = extensions.getByType().named("deps") + +internal fun Project.findVersion(alias: String): VersionConstraint { + return depsVersionCatalog.findVersion(alias).getOrNull() + ?: error("Unable to find version $alias") +} + +internal fun Project.findPlugin(alias: String): PluginDependency { + return depsVersionCatalog.findPlugin(alias).getOrNull()?.orNull + ?: error("Unable to find plugin $alias") +} + +internal fun Project.findLibrary(alias: String): MinimalExternalModuleDependency { + return depsVersionCatalog.findLibrary(alias).getOrNull()?.orNull + ?: error("Unable to find library $alias") +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 8083954d2b..0c89d3ea9f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,8 @@ include(":app") include(":domain") include(":common") +includeBuild("includedBuild/configuration") + // region Core modules include(":core:analytics") include(":core:datasource")