Convert Gradle build scripts from Groovy to Kotlin DSL

Migrates settings.gradle, root build.gradle, and app/build.gradle to
their .kts equivalents. Updates the F-Droid CI sed pattern and the
CLAUDE.md reference to match the new file names.

https://claude.ai/code/session_01VFNWcRfGTUpgqzUBpU9wFu
This commit is contained in:
Claude
2026-05-21 17:35:57 +00:00
parent fa0e97441a
commit e770811bf5
6 changed files with 271 additions and 267 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
- name: Prepare F-Droid build (no self-update)
run: |
sed -i '/android.permission.REQUEST_INSTALL_PACKAGES/d' app/src/main/AndroidManifest.xml
sed -i 's/buildConfigField "boolean", "IS_FDROID_BUILD", "false"/buildConfigField "boolean", "IS_FDROID_BUILD", "true"/' app/build.gradle
sed -i 's/buildConfigField("boolean", "IS_FDROID_BUILD", "false")/buildConfigField("boolean", "IS_FDROID_BUILD", "true")/' app/build.gradle.kts
- name: Build APK
run: ./gradlew assembleRelease --stacktrace
+1 -1
View File
@@ -13,7 +13,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
./build.sh # builds both offline and free release variants to ~/release/
```
Git hooks are auto-installed via the root `build.gradle` preBuild task — no manual setup needed.
Git hooks are auto-installed via the root `build.gradle.kts` preBuild task — no manual setup needed.
## Build flavors
-248
View File
@@ -1,248 +0,0 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.gradle.ktlint) version(libs.versions.ktlint)
alias(libs.plugins.kotlin.ksp) version(libs.versions.ksp)
alias(libs.plugins.jetbrainsComposeCompiler)
}
android {
namespace = 'com.greenart7c3.nostrsigner'
compileSdk = 37
defaultConfig {
applicationId "com.greenart7c3.nostrsigner"
minSdk 26
versionCode 191
versionName "6.1.0-pre3"
buildConfigField "boolean", "IS_FDROID_BUILD", "false"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
resourceConfigurations += [
'bn-rBD',
'cs',
'cy-rGB',
'da-rDK',
'de',
'el-rGR',
'en-rGB',
'eo',
'es',
'es-rES',
'es-rMX',
'es-rUS',
'et-rEE',
'fa',
'fi-rFI',
'fo-rFO',
'fr',
'fr-rCA',
'gu-rIN',
'hi-rIN',
'hr-rHR',
'hu',
'in',
'in-rID',
'it-rIT',
'iw-rIL',
'ja',
'kk-rKZ',
'ko-rKR',
'ks-rIN',
'ku-rTR',
'lt-rLT',
'ne-rNP',
'nl',
'nl-rBE',
'pcm-rNG',
'pl-rPL',
'pt-rBR',
'pt-rPT',
'ru',
'ru-rUA',
'sa-rIN',
'sl-rSI',
'so-rSO',
'sr-rSP',
'ss-rZA',
'sv-rSE',
'sw-rKE',
'sw-rTZ',
'ta',
'th',
'tr',
'uk',
'ur-rIN',
'uz-rUZ',
'vi-rVN',
'zh',
'zh-rCN',
'zh-rHK',
'zh-rSG',
'zh-rTW'
]
lint {
disable 'MissingTranslation', 'LocalContextGetResourceValueCall'
}
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
if (System.getenv('SIGN_RELEASE')) {
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
}
buildTypes {
release {
if (System.getenv('SIGN_RELEASE')) {
signingConfig signingConfigs.release
}
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), 'proguard-rules.pro'
minifyEnabled true
resValue "string", "app_name", "@string/app_name_release"
}
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
resValue "string", "app_name", "@string/app_name_debug"
}
}
flavorDimensions += "version"
productFlavors {
register("free") {
getIsDefault().set(true)
dimension = "version"
}
register("offline") {
dimension = "version"
}
}
splits {
abi {
enable = true
reset()
include "x86", "x86_64", "arm64-v8a", "armeabi-v7a"
universalApk = true
}
}
buildFeatures {
compose = true
buildConfig = true
resValues = true
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
excludes +='META-INF/versions/9/OSGI-INF/MANIFEST.MF'
}
jniLibs.useLegacyPackaging = true
}
}
composeCompiler {
reportsDestination = layout.buildDirectory.dir("compose_compiler")
}
dependencies {
implementation(libs.quartz) {
exclude group: 'net.java.dev.jna'
}
implementation(libs.jna) {
artifact { type = "aar" }
}
implementation libs.core.ktx
implementation libs.activity.compose
implementation libs.ui
implementation libs.ui.tooling.preview
// Navigation
implementation libs.navigation.compose
implementation libs.material3
implementation libs.material.icons.extended
implementation libs.appcompat
implementation libs.work.runtime.ktx
implementation libs.material3.window
implementation libs.paging.common
implementation libs.paging.compose
implementation libs.paging.runtime
testImplementation libs.junit
testImplementation libs.mockk
testImplementation libs.kotlinx.coroutines.test
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
androidTestImplementation libs.ui.test.junit4
debugImplementation libs.ui.tooling
debugImplementation libs.ui.test.manifest
implementation libs.security.crypto.ktx
// Lifecycle
implementation libs.lifecycle.runtime.compose
implementation libs.lifecycle.viewmodel.compose
implementation libs.lifecycle.runtime.ktx
// For QR generation
implementation libs.core
implementation libs.zxing.android.embedded
// Biometrics
implementation libs.biometric.ktx
ksp(libs.room.compiler)
implementation(libs.room.ktx)
implementation(libs.room.runtime)
implementation(libs.room.paging)
freeImplementation libs.okhttp
freeImplementation libs.okhttpCoroutines
freeImplementation libs.kmptor.runtime
freeImplementation libs.kmptor.resource.exec
// Load images from the web.
implementation libs.coil.compose
// view gifs
implementation libs.coil.gif
// view svgs
implementation libs.coil.svg
// enables network for coil
implementation libs.coil.okhttp
implementation libs.storage
implementation libs.datastore.preferences
implementation libs.security.crypto
implementation libs.lifecycle.process
implementation libs.kotlinx.collections.immutable
}
+252
View File
@@ -0,0 +1,252 @@
import java.io.FileInputStream
import java.util.Properties
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.gradle.ktlint) version libs.versions.ktlint.get()
alias(libs.plugins.kotlin.ksp) version libs.versions.ksp.get()
alias(libs.plugins.jetbrainsComposeCompiler)
}
android {
namespace = "com.greenart7c3.nostrsigner"
compileSdk = 37
defaultConfig {
applicationId = "com.greenart7c3.nostrsigner"
minSdk = 26
versionCode = 191
versionName = "6.1.0-pre3"
buildConfigField("boolean", "IS_FDROID_BUILD", "false")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
resourceConfigurations += listOf(
"bn-rBD",
"cs",
"cy-rGB",
"da-rDK",
"de",
"el-rGR",
"en-rGB",
"eo",
"es",
"es-rES",
"es-rMX",
"es-rUS",
"et-rEE",
"fa",
"fi-rFI",
"fo-rFO",
"fr",
"fr-rCA",
"gu-rIN",
"hi-rIN",
"hr-rHR",
"hu",
"in",
"in-rID",
"it-rIT",
"iw-rIL",
"ja",
"kk-rKZ",
"ko-rKR",
"ks-rIN",
"ku-rTR",
"lt-rLT",
"ne-rNP",
"nl",
"nl-rBE",
"pcm-rNG",
"pl-rPL",
"pt-rBR",
"pt-rPT",
"ru",
"ru-rUA",
"sa-rIN",
"sl-rSI",
"so-rSO",
"sr-rSP",
"ss-rZA",
"sv-rSE",
"sw-rKE",
"sw-rTZ",
"ta",
"th",
"tr",
"uk",
"ur-rIN",
"uz-rUZ",
"vi-rVN",
"zh",
"zh-rCN",
"zh-rHK",
"zh-rSG",
"zh-rTW",
)
lint {
disable += listOf("MissingTranslation", "LocalContextGetResourceValueCall")
}
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
if (System.getenv("SIGN_RELEASE") != null) {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
}
buildTypes {
release {
if (System.getenv("SIGN_RELEASE") != null) {
signingConfig = signingConfigs.getByName("release")
}
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
isMinifyEnabled = true
resValue("string", "app_name", "@string/app_name_release")
}
debug {
applicationIdSuffix = ".debug"
versionNameSuffix = "-DEBUG"
resValue("string", "app_name", "@string/app_name_debug")
}
}
flavorDimensions += "version"
productFlavors {
register("free") {
isDefault = true
dimension = "version"
}
register("offline") {
dimension = "version"
}
}
splits {
abi {
isEnable = true
reset()
include("x86", "x86_64", "arm64-v8a", "armeabi-v7a")
isUniversalApk = true
}
}
buildFeatures {
compose = true
buildConfig = true
resValues = true
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
}
jniLibs.useLegacyPackaging = true
}
}
composeCompiler {
reportsDestination.set(layout.buildDirectory.dir("compose_compiler"))
}
dependencies {
implementation(libs.quartz) {
exclude(group = "net.java.dev.jna")
}
implementation(libs.jna) {
artifact {
type = "aar"
}
}
implementation(libs.core.ktx)
implementation(libs.activity.compose)
implementation(libs.ui)
implementation(libs.ui.tooling.preview)
// Navigation
implementation(libs.navigation.compose)
implementation(libs.material3)
implementation(libs.material.icons.extended)
implementation(libs.appcompat)
implementation(libs.work.runtime.ktx)
implementation(libs.material3.window)
implementation(libs.paging.common)
implementation(libs.paging.compose)
implementation(libs.paging.runtime)
testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
implementation(libs.security.crypto.ktx)
// Lifecycle
implementation(libs.lifecycle.runtime.compose)
implementation(libs.lifecycle.viewmodel.compose)
implementation(libs.lifecycle.runtime.ktx)
// For QR generation
implementation(libs.core)
implementation(libs.zxing.android.embedded)
// Biometrics
implementation(libs.biometric.ktx)
ksp(libs.room.compiler)
implementation(libs.room.ktx)
implementation(libs.room.runtime)
implementation(libs.room.paging)
"freeImplementation"(libs.okhttp)
"freeImplementation"(libs.okhttpCoroutines)
"freeImplementation"(libs.kmptor.runtime)
"freeImplementation"(libs.kmptor.resource.exec)
// Load images from the web.
implementation(libs.coil.compose)
// view gifs
implementation(libs.coil.gif)
// view svgs
implementation(libs.coil.svg)
// enables network for coil
implementation(libs.coil.okhttp)
implementation(libs.storage)
implementation(libs.datastore.preferences)
implementation(libs.security.crypto)
implementation(libs.lifecycle.process)
implementation(libs.kotlinx.collections.immutable)
}
+10 -10
View File
@@ -5,14 +5,14 @@ plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.serialization) apply false
alias(libs.plugins.kotlin.ksp) version(libs.versions.ksp) apply false
alias(libs.plugins.gradle.ktlint) version(libs.versions.ktlint) apply false
alias(libs.plugins.kotlin.ksp) version libs.versions.ksp.get() apply false
alias(libs.plugins.gradle.ktlint) version libs.versions.ktlint.get() apply false
}
tasks.register('installGitHook', Copy) {
from new File(rootProject.rootDir, 'git-hooks/pre-commit')
from new File(rootProject.rootDir, 'git-hooks/pre-push')
into { new File(rootProject.rootDir, '.git/hooks') }
tasks.register<Copy>("installGitHook") {
from(File(rootProject.rootDir, "git-hooks/pre-commit"))
from(File(rootProject.rootDir, "git-hooks/pre-push"))
into(File(rootProject.rootDir, ".git/hooks"))
filePermissions {
unix(0b111_111_111)
}
@@ -25,21 +25,21 @@ project(":app") {
}
subprojects {
tasks.withType(KotlinCompile).configureEach {
tasks.withType<KotlinCompile>().configureEach {
compilerOptions {
def buildDirPath = project.layout.buildDirectory.get().asFile.absolutePath
val buildDirPath = project.layout.buildDirectory.get().asFile.absolutePath
if (project.findProperty("composeCompilerReports") == "true") {
freeCompilerArgs.addAll(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
buildDirPath + "/compose_compiler"
buildDirPath + "/compose_compiler",
)
}
if (project.findProperty("composeCompilerMetrics") == "true") {
freeCompilerArgs.addAll(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
buildDirPath + "/compose_compiler"
buildDirPath + "/compose_compiler",
)
}
}
+3 -3
View File
@@ -3,7 +3,7 @@ pluginManagement {
google()
mavenCentral()
gradlePluginPortal()
maven { url = "https://jitpack.io" }
maven("https://jitpack.io")
}
}
@@ -12,8 +12,8 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = "https://jitpack.io" }
maven("https://jitpack.io")
}
}
rootProject.name = "Nostr Signer"
include ':app'
include(":app")