Build-Time Config Access
Kayan can expose resolved config values during Gradle configuration, not just in generated Kotlin source. This lets build logic use the same validated config that shared code reads later.
Use buildValue("json_key") when Gradle decisions need to depend on config:
@file:OptIn(io.kayan.gradle.ExperimentalKayanGradleApi::class)
kayan { flavor.set("prod")
schema { boolean("feature_search_enabled", "FEATURE_SEARCH_ENABLED") string("brand_name", "BRAND_NAME") enumValue("release_stage", "RELEASE_STAGE", enumTypeName = "sample.ReleaseStage") }}
val isSearchEnabled = kayan.buildValue("feature_search_enabled") .asBoolean()
dependencies { if (isSearchEnabled) { implementation("com.example:search-sdk:1.0.0") }}By design, this API is meant for non-sensitive build configuration. If a value is appropriate for
Gradle to read during configuration, it is usually fine for buildValue(). Secrets such as API
keys, passwords, and tokens should stay in dedicated secret-management or environment-specific
secure storage instead. See Security for the trust model behind
buildValue() and custom adapters.
When to use it
Section titled “When to use it”Use buildValue() when Gradle itself needs the answer:
- conditional dependencies
- source set or task configuration
- build flags that should be decided during configuration
Use the generated KayanConfig object when application or shared Kotlin code needs the
value at compile time or runtime.
Accessor types
Section titled “Accessor types”buildValue("key") returns a KayanBuildValue with three styles of accessors.
Eager accessors
Section titled “Eager accessors”These resolve immediately and return plain Kotlin values. Use them when the
build script needs the answer right now, for example inside if and when:
kayan.buildValue("brand_name").asString()kayan.buildValue("feature_search_enabled").asBoolean()kayan.buildValue("max_workspace_count").asInt()kayan.buildValue("max_cache_bytes").asLong()kayan.buildValue("rollout_ratio").asDouble()kayan.buildValue("support_links").asStringList()kayan.buildValue("support_labels").asStringMap()kayan.buildValue("regional_support_links").asStringListMap()Nullable accessors
Section titled “Nullable accessors”If a resolved value may be null, use the OrNull variants:
val supportEmail = kayan.buildValue("support_email") .asStringOrNull()Provider accessors
Section titled “Provider accessors”These do the same type checks, but return a Gradle Provider<T> instead of the
plain value. Use them for task inputs and other lazy Gradle wiring:
val brandName = kayan.buildValue("brand_name").asString()val brandNameProvider = kayan.buildValue("brand_name").asStringProvider()asString()resolves immediately during configurationasStringProvider()defers resolution until Gradle needs the value
That difference matters most when assigning into Property<T>, ListProperty<T>,
or other provider-based Gradle APIs:
@file:OptIn(io.kayan.gradle.ExperimentalKayanGradleApi::class)
abstract class PrintBrandTask : DefaultTask() { @get:Input abstract val brandName: Property<String>
@TaskAction fun printBrand() { println(brandName.get()) }}
tasks.register<PrintBrandTask>("printBrand") { brandName.set( kayan.buildValue("brand_name") .asStringProvider() )}Enum values
Section titled “Enum values”At Gradle configuration time, enums are exposed by their normalized name rather than by instantiating the enum type:
when (kayan.buildValue("release_stage").asEnumName()) { "PROD" -> println("production build") "BETA" -> println("beta build")}asString() also works for enum values and returns their normalized constant names.
Error behavior
Section titled “Error behavior”buildValue() fails early with Gradle-friendly messages:
- unknown schema key:
"Key '<key>' is not defined in the Kayan schema"with close-match suggestions - type mismatch:
"Key '<key>' is <actual kind>, cannot access as <requested type>" - null through non-null accessor:
"Key '<key>' is null; use as<Type>OrNull() instead"
Constraints
Section titled “Constraints”flavormust be configured beforebuildValue()is used- keys must still be declared in the Kayan
schema {} - build-time access returns raw Gradle-friendly primitives and collections
- custom adapters are not applied at configuration time
That last point is intentional: Gradle build logic usually needs Boolean, String, or
List<String>, not consumer-owned domain types.
Configuration cache
Section titled “Configuration cache”buildValue() is backed by a Gradle ValueSource, so file changes to the configured
inputs invalidate resolution while configuration-cache-friendly builds can still reuse the
requested key between runs without serializing unrelated resolved values.