Skip to content

Commit

Permalink
Adjust string properties for better call site usage
Browse files Browse the repository at this point in the history
  • Loading branch information
ashdavies committed Aug 18, 2024
1 parent 6fdd581 commit 2cfb104
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 35 deletions.
23 changes: 6 additions & 17 deletions conferences-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,11 @@ android {
}

val release by signingConfigs.creating {
val releaseStoreFile by stringProperty()
storeFile = rootProject.file(releaseStoreFile)
val releaseStoreFile by stringProperty { storeFile = rootProject.file(it) }
val releaseStorePassword by stringProperty { storePassword = it }

val releaseStorePassword by stringProperty()
storePassword = releaseStorePassword

val releaseKeyAlias by stringProperty()
keyAlias = releaseKeyAlias

val releaseKeyPassword by stringProperty()
keyPassword = releaseKeyPassword
val releaseKeyAlias by stringProperty { keyAlias = it }
val releaseKeyPassword by stringProperty { keyPassword = it }
}

buildTypes {
Expand All @@ -52,13 +46,8 @@ android {
}

buildConfig {
val androidApiKey by stringProperty { value ->
buildConfigField("ANDROID_API_KEY", value)
}

val androidStrictMode by booleanProperty { value ->
buildConfigField("ANDROID_STRICT_MODE", value)
}
val androidApiKey by stringPropertyWithTag(::buildConfigField)
val androidStrictMode by stringPropertyWithTag(::buildConfigField)

packageName.set(android.namespace)
}
Expand Down
53 changes: 35 additions & 18 deletions fused-properties/src/main/kotlin/StringProperty.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,56 @@ import kotlin.properties.ReadOnlyProperty

public fun interface ReadOnlyDelegateProvider<T> : PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, T>>

private fun Project.stringPropertyProvider(propertyName: String): Provider<String> {
private interface PropertyDefinition {
val gradlePropertyName: String
val envPropertyName: String
}

private fun PropertyDefinition(propertyName: String) = object : PropertyDefinition {
private val propertyNameParts = propertyName.split(Regex("(?=[A-Z])"))
override val gradlePropertyName = propertyNameParts.joinToString(".") { it.lowercase() }
override val envPropertyName = propertyNameParts.joinToString("_") { it.uppercase() }
}

private fun Project.stringPropertyProvider(definition: PropertyDefinition): Provider<String> {
val rootPropertiesProvider = rootProject.cachedLocalPropertiesProvider()
val localPropertiesProvider = cachedLocalPropertiesProvider()
val startPropertiesProvider = startParameterProvider()

val propertyNameParts = propertyName.split(Regex("(?=[A-Z])"))
val gradlePropertyName = propertyNameParts.joinToString(".") { it.lowercase() }
val envPropertyName = propertyNameParts.joinToString("_") { it.uppercase() }

return startPropertiesProvider.mapOrNull { it[gradlePropertyName] }
.orElse(localPropertiesProvider.map { it.getProperty(gradlePropertyName) })
.orElse(rootPropertiesProvider.map { it.getProperty(gradlePropertyName) })
.orElse(providers.gradleProperty(gradlePropertyName))
.orElse(providers.environmentVariable(envPropertyName))
return startPropertiesProvider.mapOrNull { it[definition.gradlePropertyName] }
.orElse(localPropertiesProvider.map { it.getProperty(definition.gradlePropertyName) })
.orElse(rootPropertiesProvider.map { it.getProperty(definition.gradlePropertyName) })
.orElse(providers.gradleProperty(definition.gradlePropertyName))
.orElse(providers.environmentVariable(definition.envPropertyName))
}

public fun Project.booleanProperty(block: (Boolean) -> Unit = { }): ReadOnlyDelegateProvider<Boolean> {
return readOnlyDelegateProvider { it.get().toBoolean().also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.get().toBoolean().also(block) }
}

public fun Project.stringPropertyWithTag(action: (String, String) -> Unit): ReadOnlyDelegateProvider<String> {
return readOnlyDelegateProvider { provider, tag -> provider.get().also { action(tag, it) } }
}

public fun Project.stringProperty(block: (String) -> Unit = { }): ReadOnlyDelegateProvider<String> {
return readOnlyDelegateProvider { it.get().also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.get().also(block) }
}

public fun Project.stringPropertyOrNull(block: (String?) -> Unit = { }): ReadOnlyDelegateProvider<String?> {
return readOnlyDelegateProvider { it.orNull.also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.orNull.also(block) }
}

private fun <T> Project.readOnlyDelegateProvider(transform: (Provider<String>) -> T): ReadOnlyDelegateProvider<T> {
return ReadOnlyDelegateProvider { _, property ->
val value = transform(stringPropertyProvider(property.name))
ReadOnlyProperty { _, _ -> value }
}
private fun <T> Project.readOnlyDelegateProvider(
transform: (provider: Provider<String>, tag: String) -> T,
): ReadOnlyDelegateProvider<T> = ReadOnlyDelegateProvider { _, property ->
val definition = PropertyDefinition(property.name)

val value = transform(
stringPropertyProvider(definition),
definition.envPropertyName,
)

ReadOnlyProperty { _, _ -> value }
}

private fun <S : Any, T> Provider<S>.mapOrNull(block: (S) -> T?): Provider<T> {
Expand Down

0 comments on commit 2cfb104

Please sign in to comment.