Skip to content

App plugin

Add the following to the root build.gradle or build.gradle.kts to apply the plugin:

plugins {
    id("com.freeletics.gradle.app.android").version("<latest-version>")
}

Default configurations

Common configuration

The plugin applies the following common configuration:

  • The Java and Kotlin toolchain are set to the java-toolchain version catalog version.
  • Kotlin’s progressive mode is enabled.
  • Kotlin compiler warnings are treated as errors.
    • This can be disabled by setting fgp.kotlin.warningsAsErrors=false
    • It’s possible to ignore deprecation warning by setting fgp.kotlin.suppressDeprecationWarnings=true
  • Several Kotlin compiler flags are set to improve the default behavior.
  • All produced archives are configured to be reproducible.

Default dependencies

The plugins can dynamically add default dependencies to all modules. This can be enabled by creating any of the following bundles:

[bundles]
# any dependency in this bundle is automatically added to all modules as implementation dependency
default-all = [ ... ]
# any dependency in this bundle is automatically added to all modules as compileOnly dependency
default-all-compile = [ ... ]
# any dependency in this bundle is automatically added to all Android modules as implementation dependency
default-android = [ ... ]
# any dependency in this bundle is automatically added to all Android modules as compileOnly dependency
default-android-compile = [ ... ]
# any dependency in this bundle is automatically added to all modules as testImplementation dependency
default-testing = [ ... ]
# any dependency in this bundle is automatically added to all modules as testCompileOnly dependency
default-testing-compile = [ ... ]
# any dependency in this bundle is automatically added to all modules as testRuntimeOnly dependency
default-testing-runtime = [ ... ]
# any dependency in this bundle is automatically added to all modules as lintChecks dependency
default-lint = [ ... ]

Android configuration

  • The compileSdk is set to the android-compile version catalog version
  • The minSdk is set to the android-min version catalog version
  • The targetSdk is set to the android-target version catalog version
  • Optionally the buildToolsVersion is set to the android-buildTools version catalog version if it’s present in the version catalog.
  • If the android-desugarjdklibs library is defined the version catalog core library desugaring is be enabled automatically.

Features

Explicit API

It’s possible to enable Kotlin’s explicit API mode directly from the DSL by calling:

freeletics {
    explicitApi()
}

Experimental API opt in

It’s possible to opt into an experimental API for the module directly from the DSL by calling:

freeletics {
    optIn("...")
}

Compose

To enable Jetpack Compose for the module call:

freeletics {
    useCompose()
}

It’s possible to enable compose compiler reports and metrics by setting the following 2 properties. Afterwards the outputs can be found in the build folder.

fgp.compose.enableCompilerMetrics=true
fgp.compose.enableCompilerReports=true`

kotlinx.serialization

To enable kotlinx.serialziation for the module call:

freeletics {
    useSerialization()
}

This expects the version catalog to have a kotlinx-serialization entry with the org.jetbrains.kotlinx:kotlinx-serialization-core library.

Metro

To enable Metro for the module call:

freeletics {
    useMetro()
}

Khonshu

To enable Khonshu for the module call:

freeletics {
    useKhonshu()
}

Both Metro and KSP will be automatically enabled when using Khonshu.

This expects the version catalog to have the following 2 entries: - khonshu-codegen-runtime pointing to com.freeletics.khonshu:codegen-runtime - khonshu-codegen-compiler pointing to com.freeletics.khonshu:codegen-compiler

Poko

To enable Poko for the module call:

freeletics {
    usePoko()
}

Kopy

To enable Kopy for the module call:

freeletics {
    useKopy()
}

SQLDelight

To enable SQLDelight for the module call:

freeletics {
    useSqlDelight()
}

There are 2 optional parameters for this function: - the name for the generated database which defaults to database - a dependency if this module depends on another module’s SQLDelight definitions

To change the used SQL dialect add the dialect of your choice to the version catalog with an entry called sqldelight-dialect.

Room

To enable Room for the module call:

freeletics {
    useRoom()
}

This will automatically apply KSP to the project and will use Kotlin code generation.

Optionally a schemaLocation can be provided.

This expects the version catalog to have the following 2 entries: - androidx-room-runtime pointing to androidx.room:room-runtime - androidx-room-compiler pointing to androidx.room:room-compiler

Burst

To enable Burst for the module call:

freeletics {
    useBurst()
}

OSS publishing

Publishing to Maven Central using the gradle-maven-publish-plugin.

freeletics {
    enableOssPublishing()
}

Enabling this will also apply Dokka, enable ABI validation and enable explicit API mode.

For the configuration of the POM, only the following Gradle properties need to be defined: - GROUP - VERSION_NAME - POM_REPO_NAME - POM_ARTIFACT_ID - POM_NAME - POM_DESCRIPTION

Internal publishing

Publishing to an internal repo can be enabled by calling the following function:

freeletics {
    enableInternalPublishing()
}

A fgp.internalArtifacts.url gradle property needs to be defined with the URL of the remote repository. The username and password for this repository are expected to be set through internalArtifactsUsername and internalArtifactsPassword.

Build config fields

To add a custom build config field call:

freeletics {
    android {
        // create a BuildConfig field with the given value
        buildConfigField("type", "name", "value")
        // create a BuildConfig field with separate values for debug and release
        buildConfigField("type", "name", "debug value", "release value")
    }
}

–8← “docs/features/android-app-2-resvalue.md)

Android options

freeletics {
    app {
        // the application id that will be used for the app
        applicationId("com.example")
        // sets an application id suffix for the given build type
        applicationIdSuffix("release", ".suffix")
        // resources will be limited to the given locales
        limitLanguagesTo("en", "de", "fr")
        // enable minification with R8 and use the given proguard files as additional config (parameters are optional)
        minify(
                rootProject.file("proguard/library1.pro"),
                rootProject.file("proguard/library2.pro"),
        )
    }
}

Git based versioning

When enabled the versionName and versionCode will be computed based on information from Git.

freeletics {
    app {
        // the passed in value will be used for matching git tags and branches as described below
        // can be anything identifying an app, e.g. `fl` for `freeletics` or just `freeletics` directly
        versionFromGit("<short-app-name>")
    }
}

The version information can come from: - a tag for the current commit in the format of <short-app-name>/v<app-version> -> <app-version> is used as version name - otherwise the output of git describe (<short-app-name>/v<last-app-version>-<commits-since-tag>-<current-commit-sha>) is used which would result in <last-app-version>-<commits-since-tag>-<current-commit-sha>

The version code is then computed by taking the version and applying the following formula

<major> * 1_000_000 + <minor> * 10_000 + <patch>

For builds on the main branch when the current commit is not tagged, the following formula is used:

<major> * 1_000_000 + <minor> * 10_000 + <day_of_week> * 1_000 + <commits since last release>

Also creates BuildConfig.GIT_SHA1, BuildConfig.BUILD_TIMESTAMP fields containing information from the current commit.

To not break incremental builds and build cache versionName, versionCode and the 2 build config fields will default to constants. The computation will only happen if -Pfgp.computeInfoFromGit=true is passed to the build.

License checks

Applies Licensee (app.cash.licensee) and already configures it to accept Apache-2.0, MIT and MIT-0 licenses.

freeletics {
    app {
        checkLicenses()
    }
}

This will also register a task updateLicenses that will copy the output of licenseeRelease to src/main/assets/license_acknowledgements.json and strip the version information from that file. This file will be shipped wit the app and can be used as data source for a license acknowledgement screen in the app.

Crashlytics

Applies the Crashlytics Gradle plugin and configures it for the release build type. This configuration does not require the Google services Gradle plugin but it expects src/debug/res/values/google-services.xml and src/release/res/values/google-services.xml to exist. The Crashlytics mapping upload will only be enabled when -Pfgp.computeInfoFromGit=true is passed to the build.

freeletics {
    app {
        crashReporting()
    }
}

There will also be a generated BuildConfig.CRASHLYTICS_ENABLED boolean field that will only be true if the mapping upload was enabled.