The plugin supports a number of advanced behaviours. For example, it can be used to consume properties
from various external sources, it provides fallbacks for dynamic properties and can be
used in Android projects to map build properties to buildConfigField
and resValue
.
Examples for most features can also be found on our github repo.
- Read properties from different sources
- Define custom property source
- Fallback support
- Map properties to Android Gradle plugin
- Define Android product flavors using properties
The plugin comes with built in support for various sources for properties that can be configured within the
buildProperties
closure.
Properties can be consumed from one or multiple files:
dev {
using rootProject.file('dev.properties')
}
production {
using rootProject.file('production.properties')
}
Properties can be consumed from the project properties:
cli {
using project
}
Project properties can be either either passed via the command line:
gradlew build -Papi_key=12345
or via the build script itself:
ext {
api_key=12345
}
Properties can be consumed from the system properties:
env {
using System.getenv()
}
Besides the built-in sources for properties, the plugin also provides an API to create custom ones.
These need to extend the Entries
and can be provided via BuildProperties.entries(Entries entries)
. For example,
a custom implementation could consume properties from a web resource.
api {
using customApiEntries()
}
If a property cannot be found it's possible to provide a fallback.
A fallback value for a given Entry
via the or()
operator can be defined as:
Example | |
---|---|
another Entry |
buildProperties.secrets['notThere'].or(buildProperties.secrets['fallback']) |
a Closure |
buildProperties.secrets['notThere'].or({ Math.random() }) |
a value | buildProperties.secrets['notThere'].or('fallback') |
If the whole fallback chain evaluation fails then a CompositeException
is thrown listing all
the causes in the chain, e.g.:
A problem occurred while evaluating entry:
- exception message 1
- exception message 2
- exception message 3
Besides providing a fallback Entry
, also another Entries
source can be declared as fallback:
files {
using(file('$file.name')).or(file('$includeFile.name'))
}
Using the plugin, properties can be mapped as buildConfigField
and resValue
to the Android Gradle plugin.
buildProperties {
api {
using project.file('../properties/api_secrets.properties')
}
}
android {
...
defaultConfig {
buildConfigString 'CLIENT_ID', buildProperties.api['api_client_id']
buildConfigString 'CLIENT_SECRET', buildProperties.api['api_client_secret']
...
Besides that it enhances these facilities by enforcing types.
To generate a string field in your BuildConfig you used to write:
buildConfigField 'String', 'LOL', '\"sometimes the picture take\"'
but now you can instead write:
buildConfigString 'LOL', 'sometimes the picture take'
The full list of new typed facilities is as follows:
Example | |
---|---|
buildConfigBoolean |
buildConfigBoolean 'TEST_BOOLEAN', false |
buildConfigInt |
buildConfigInt 'TEST_INT', 42 |
buildConfigLong |
buildConfigLong 'TEST_LONG', System.currentTimeMillis() |
buildConfigDouble |
buildConfigDouble 'TEST_DOUBLE', Math.PI |
buildConfigString |
buildConfigString 'TEST_STRING', 'whateva' |
resValueInt |
resValueInt 'debug_test_int', 100 |
resValueBoolean |
resValueBoolean 'debug_test_bool', true |
resValueString |
resValueString 'debug_test_string', 'dunno bro...' |
Using the plugin, properties can be also injected into other gradle plugin extensions.
For example, Android productFlavors
can be easily configured by first creating a method that configures a product flavor from
given properties:
productFlavors.all { flavor ->
flavor.ext.from = { flavorProperties ->
println ">>> Configuring '${flavor.name}' flavor using '${flavorProperties.name}' build properties"
flavor.applicationId flavorProperties['applicationId'].string
flavor.versionCode flavorProperties['versionCode'].int
flavor.versionName flavorProperties['versionName'].string
.
.
.
}
}
and then by calling it:
productFlavors {
dev {
from buildProperties.dev
}
production {
from buildProperties.prod
}
}