From e770811bf5e3ca6d53840f1af76255562963a541 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 21 May 2026 17:35:57 +0000 Subject: [PATCH] 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 --- .github/workflows/create-release.yml | 2 +- CLAUDE.md | 2 +- app/build.gradle | 248 ------------------------ app/build.gradle.kts | 252 +++++++++++++++++++++++++ build.gradle => build.gradle.kts | 28 +-- settings.gradle => settings.gradle.kts | 6 +- 6 files changed, 271 insertions(+), 267 deletions(-) delete mode 100644 app/build.gradle create mode 100644 app/build.gradle.kts rename build.gradle => build.gradle.kts (51%) rename settings.gradle => settings.gradle.kts (75%) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 30411a94..4c91401c 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index ef2036c3..7fa32b8a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index e7f7bfa5..00000000 --- a/app/build.gradle +++ /dev/null @@ -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 -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 00000000..bb253c1c --- /dev/null +++ b/app/build.gradle.kts @@ -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) +} diff --git a/build.gradle b/build.gradle.kts similarity index 51% rename from build.gradle rename to build.gradle.kts index cbcab9d3..eeb5660e 100644 --- a/build.gradle +++ b/build.gradle.kts @@ -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("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().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" + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + + buildDirPath + "/compose_compiler", ) } if (project.findProperty("composeCompilerMetrics") == "true") { freeCompilerArgs.addAll( - "-P", - "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + - buildDirPath + "/compose_compiler" + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + + buildDirPath + "/compose_compiler", ) } } diff --git a/settings.gradle b/settings.gradle.kts similarity index 75% rename from settings.gradle rename to settings.gradle.kts index bd4e5afc..b5119ecd 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -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")