Skip to content

Commit

Permalink
feat: support resource customization (#1739)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitorhugods authored and tmspzz committed Jul 13, 2023
1 parent 7251e4c commit a51895b
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package customization

import java.io.File

data class BuildTimeConfiguration(
val flavorSettings: NormalizedFlavorSettings,
val customResourceOverrideDirectory: File?
)

data class NormalizedFlavorSettings(
val flavorMap: Map<String, Map<String, Any?>>
)
Expand Down
43 changes: 30 additions & 13 deletions buildSrc/src/main/kotlin/customization/Customization.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package customization

import groovy.json.JsonSlurper
import org.ajoberstar.grgit.Credentials
import org.ajoberstar.grgit.Grgit
import java.io.File
Expand All @@ -29,6 +28,7 @@ object Customization {

internal const val GIT_PROPERTIES_FILE_NAME = "local.properties"
internal const val CUSTOM_CHECKOUT_DIR_NAME = "custom"
internal const val CUSTOM_RESOURCES_OVERRIDE_DIR_NAME = "resources"
internal const val CUSTOM_JSON_FILE_NAME = "custom-reloaded.json"
internal const val DEFAULT_JSON_FILE_NAME = "default.json"

Expand All @@ -45,33 +45,50 @@ object Customization {
* according to the specified [customizationOption].
* Will attempt to read [CustomizationGitProperty] from environment variables
* or [GIT_PROPERTIES_FILE_NAME] file if [customizationOption] is null.
* @return the [NormalizedFlavorSettings], result from the importing of configuration files.
* @return the [BuildTimeConfiguration], result from the importing of configuration files.
*/
fun getBuildtimeConfiguration(
rootDir: File
): BuildTimeConfiguration {
val isCustomFromGit = properties.readCustomizationProperty(CustomizationGitProperty.CUSTOM_REPOSITORY) != null
return if (isCustomFromGit) {
val customFile = getCustomisationFileFromGitProperties(rootDir)
getBuildtimeConfiguration(rootDir, CustomizationOption.FromFile(customFile))
} else {
getBuildtimeConfiguration(rootDir, CustomizationOption.DefaultOnly)
}
}

/**
* Basing all the work on the [rootDir], import configuration files
* according to the specified [customizationOption].
* @return the [BuildTimeConfiguration], result from the importing of configuration files.
*/
fun getBuildtimeConfiguration(
rootDir: File,
customizationOption: CustomizationOption? = null
): NormalizedFlavorSettings {
customizationOption: CustomizationOption
): BuildTimeConfiguration {

val defaultConfigFile = File(rootDir, DEFAULT_JSON_FILE_NAME)
val defaultConfig = configurationFileImporter.loadConfigsFromFile(defaultConfigFile)

return when (customizationOption) {
val normalizedFlavorSettings = when (customizationOption) {
is CustomizationOption.DefaultOnly -> defaultConfig

is CustomizationOption.FromFile -> getCustomBuildConfigs(
defaultConfig,
customizationOption.customJsonFile
)
}

null -> {
val isCustomFromGit = properties.readCustomizationProperty(CustomizationGitProperty.CUSTOM_REPOSITORY) != null
if (isCustomFromGit) {
val customFile = getCustomisationFileFromGitProperties(rootDir)
getCustomBuildConfigs(defaultConfig, customFile)
} else {
defaultConfig
}
val resourcesOverrideDirectory = when(customizationOption){
is CustomizationOption.DefaultOnly -> null
is CustomizationOption.FromFile -> {
File(customizationOption.customJsonFile.parentFile, CUSTOM_RESOURCES_OVERRIDE_DIR_NAME)
.takeIf { it.exists() }
}
}
return BuildTimeConfiguration(normalizedFlavorSettings, resourcesOverrideDirectory)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/customization/FeatureFlags.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
package customization

import scripts.Variants_gradle.ProductFlavors
import flavor.ProductFlavors

/**
* By convention use the prefix FEATURE_ for every
Expand Down
26 changes: 26 additions & 0 deletions buildSrc/src/main/kotlin/customization/ResourcesOverrider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package customization

import com.android.build.gradle.BaseExtension
import com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet
import flavor.ProductFlavors
import java.io.File

fun BaseExtension.overrideResourcesForAllFlavors(
customResourcesRootDir: File
) {

sourceSets {
ProductFlavors.all.forEach {
getByName(it.buildName).apply {
val resDir = (res as DefaultAndroidSourceDirectorySet).srcDirs.first()
println("Copying files from '${customResourcesRootDir.absolutePath}' into '${resDir.absolutePath}'")

customResourcesRootDir.walkTopDown().filter { !it.isDirectory }.forEach { customContent ->
val relativePath = customContent.relativeTo(customResourcesRootDir).path
val targetFile = File(resDir, relativePath)
customContent.copyTo(targetFile, overwrite = true)
}
}
}
}
}
31 changes: 31 additions & 0 deletions buildSrc/src/main/kotlin/flavor/ProductFlavors.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package flavor

object FlavorDimensions {
const val DEFAULT = "default"
}

sealed class ProductFlavors(
val buildName: String,
val appName: String,
val dimensions: String = FlavorDimensions.DEFAULT,
val shareduserId: String = ""
) {
override fun toString(): String = this.buildName

object Dev : ProductFlavors("dev", "Wire Dev")
object Staging : ProductFlavors("staging", "Wire Staging")

object Beta : ProductFlavors("beta", "Wire Beta")
object Internal : ProductFlavors("internal", "Wire Internal")
object Production : ProductFlavors("prod", "Wire", shareduserId = "com.waz.userid")

companion object {
val all: Collection<ProductFlavors> = setOf(
Dev,
Staging,
Beta,
Internal,
Production,
)
}
}
44 changes: 15 additions & 29 deletions buildSrc/src/main/kotlin/scripts/variants.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ package scripts
import com.android.build.api.dsl.ApplicationProductFlavor
import com.android.build.api.dsl.ProductFlavor
import customization.ConfigType
import customization.Customization
import customization.Customization.getBuildtimeConfiguration
import customization.FeatureConfigs
import customization.FeatureFlags
import customization.Features
import customization.overrideResourcesForAllFlavors
import flavor.FlavorDimensions
import flavor.ProductFlavors

plugins { id("com.android.application") apply false }
// DO NOT USE CAPITAL LETTER FOR THE BUILD TYPE NAME OR JENKINS WILL BE MAD
Expand All @@ -37,26 +41,6 @@ object BuildTypes {
const val COMPAT_RELEASE = "compatrelease"
}

sealed class ProductFlavors(
val buildName: String,
val appName: String,
val dimensions: String = FlavorDimensions.DEFAULT,
val shareduserId: String = ""
) {
override fun toString(): String = this.buildName

object Dev : ProductFlavors("dev", "Wire Dev")
object Staging : ProductFlavors("staging", "Wire Staging")

object Beta : ProductFlavors("beta", "Wire Beta")
object Internal : ProductFlavors("internal", "Wire Internal")
object Production : ProductFlavors("prod", "Wire", shareduserId = "com.waz.userid")
}

object FlavorDimensions {
const val DEFAULT = "default"
}

object Default {
val BUILD_FLAVOR: String = System.getenv("flavor") ?: System.getenv("FLAVOR") ?: ProductFlavors.Dev.buildName
val BUILD_TYPE = System.getenv("buildType") ?: System.getenv("BUILD_TYPE") ?: BuildTypes.DEBUG
Expand Down Expand Up @@ -147,13 +131,15 @@ android {
}
}

flavorDimensions(FlavorDimensions.DEFAULT)

val buildtimeConfiguration = getBuildtimeConfiguration(rootDir = rootDir)
val flavorMap = buildtimeConfiguration.flavorSettings.flavorMap

flavorDimensions(FlavorDimensions.DEFAULT)
productFlavors {
fun createFlavor(flavor: ProductFlavors) {
val flavorName = flavor.buildName
val flavorSpecificMap = buildtimeConfiguration.flavorMap[flavorName]
val flavorSpecificMap = flavorMap[flavorName]
requireNotNull(flavorSpecificMap) {
"Missing configs in json file for the flavor '$flavorName'"
}
Expand All @@ -169,11 +155,11 @@ android {
flavour = flavor
)
}
createFlavor(ProductFlavors.Dev)
createFlavor(ProductFlavors.Staging)
createFlavor(ProductFlavors.Beta)
createFlavor(ProductFlavors.Internal)
createFlavor(ProductFlavors.Production)
ProductFlavors.all.forEach(::createFlavor)
}

buildtimeConfiguration.customResourceOverrideDirectory?.let {
overrideResourcesForAllFlavors(it)
}

/**
Expand All @@ -195,7 +181,7 @@ android {
flavor,
configs.configType.type,
configs.name,
buildtimeConfiguration.flavorMap[flavor.name]?.get(configs.value)?.toString()
flavorMap[flavor.name]?.get(configs.value)?.toString()
)
}

Expand All @@ -204,7 +190,7 @@ android {
flavor,
configs.configType.type,
configs.name,
buildtimeConfiguration.flavorMap[flavor.name]?.get(configs.value).toString()
flavorMap[flavor.name]?.get(configs.value).toString()
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/test/kotlin/customization/CustomizationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class CustomizationTest {
Customization.CustomizationOption.DefaultOnly
)

result.flavorMap["dev"]!!["foo"] shouldBeEqualTo "default"
result.flavorSettings.flavorMap["dev"]!!["foo"] shouldBeEqualTo "default"
}

@Test
Expand Down Expand Up @@ -94,6 +94,6 @@ class CustomizationTest {
Customization.CustomizationOption.FromFile(customFile)
)

result.flavorMap["dev"]!!["foo"] shouldBeEqualTo "custom"
result.flavorSettings.flavorMap["dev"]!!["foo"] shouldBeEqualTo "custom"
}
}

0 comments on commit a51895b

Please sign in to comment.