Merge pull request #3007 from vitorpamplona/claude/gradle-to-kotlin-dsl-sOUlg

Migrate build scripts from Groovy to Kotlin DSL
This commit is contained in:
Vitor Pamplona
2026-05-20 13:30:58 -04:00
committed by GitHub
6 changed files with 566 additions and 549 deletions
-435
View File
@@ -1,435 +0,0 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.googleServices)
alias(libs.plugins.jetbrainsComposeCompiler)
alias(libs.plugins.serialization)
}
def getCurrentBranch() {
try {
def branch = 'git rev-parse --abbrev-ref HEAD'.execute().text.trim()
return branch
} catch (Exception e) {
println "Could not determine git branch: ${e.message}"
return "unknown"
}
}
def generateVersionName(String baseVersion) {
def currentBranch = getCurrentBranch()
if (currentBranch == "main" || currentBranch == "master" || currentBranch == "unknown" || currentBranch == "HEAD") {
return baseVersion
} else {
// Clean branch name for version (replace special characters)
def cleanBranch = currentBranch.replaceAll(/[^a-zA-Z0-9\-_]/, "-")
// Limit branch name to maximum 20 characters
if (cleanBranch.length() > 20) {
cleanBranch = cleanBranch.substring(0, 20)
}
return "${baseVersion}-${cleanBranch}"
}
}
// Workaround: stability.analyzer plugin doesn't declare task dependencies properly for Gradle 9.x
afterEvaluate {
def stabilityNames = tasks.names.findAll { it.contains("StabilityCheck") }
def compileNames = tasks.names.findAll { it.matches("compile.*UnitTestKotlin") }
stabilityNames.each { scName ->
compileNames.each { ctName ->
tasks.named(scName).configure { mustRunAfter(tasks.named(ctName)) }
}
}
}
android {
namespace = 'com.vitorpamplona.amethyst'
compileSdk = libs.versions.android.compileSdk.get().toInteger()
defaultConfig {
applicationId = "com.vitorpamplona.amethyst"
minSdk = libs.versions.android.minSdk.get().toInteger()
targetSdk = libs.versions.android.targetSdk.get().toInteger()
versionCode = 446
versionName = generateVersionName(libs.versions.app.get())
buildConfigField "String", "RELEASE_NOTES_ID", "\"b1b91d7ee0c5da9d081d1a53470248ee4585b058b11aa34fe28c0e3e07ac1e0a\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
resourceConfigurations += [
'ar',
'ar-rSA',
'bn-rBD',
'cs',
'cs-rCZ',
'cy-rGB',
'da-rDK',
'de',
'de-rDE',
'el-rGR',
'en-rGB',
'eo',
'eo-rUY',
'es',
'es-rES',
'es-rMX',
'es-rUS',
'et-rEE',
'fa',
'fa-rIR',
'fi-rFI',
'fo-rFO',
'fr',
'fr-rCA',
'fr-rFR',
'gu-rIN',
'hi-rIN',
'hr-rHR',
'hu',
'hu-rHU',
'in',
'in-rID',
'it-rIT',
'iw-rIL',
'ja',
'ja-rJP',
'kk-rKZ',
'ko-rKR',
'ks-rIN',
'ku-rTR',
'lt-rLT',
'ne-rNP',
'nl',
'nl-rBE',
'nl-rNL',
'pcm-rNG',
'pl-rPL',
'pt-rBR',
'pt-rPT',
'ru',
'ru-rRU',
'ru-rUA',
'sa-rIN',
'sl-rSI',
'so-rSO',
'sr-rSP',
'ss-rZA',
'sv-rSE',
'sw-rKE',
'sw-rTZ',
'ta',
'ta-rIN',
'th',
'th-rTH',
'tr',
'tr-rTR',
'uk',
'uk-rUA',
'ur-rIN',
'uz-rUZ',
'vi-rVN',
'zh',
'zh-rCN',
'zh-rHK',
'zh-rSG',
'zh-rTW'
]
}
// Opt-in fast-build flags. Default behavior is unchanged.
//
// -PdisableAbiSplits=true skip per-ABI APK splits; produces a single
// APK per (flavor, buildType) instead of 5.
// Cuts ~600 MB of intermediates and several
// minutes off CI.
// -PdisableUniversalApk=true when ABI splits are enabled, skip the
// extra universal APK output. (No effect
// when disableAbiSplits is also set, since
// there are no splits to add to.)
// -Pamethyst.skipMapping=true disable R8 minification on release and
// benchmark. APK is larger, but builds are
// much faster and outputs/mapping/ (~260MB)
// is not produced. Local-dev and PR-CI use
// only — release pipelines must not set it.
def disableAbiSplits = providers.gradleProperty("disableAbiSplits")
.map { it.toBoolean() }.getOrElse(false)
def disableUniversalApk = providers.gradleProperty("disableUniversalApk")
.map { it.toBoolean() }.getOrElse(false)
def skipMapping = providers.gradleProperty("amethyst.skipMapping")
.map { it.toBoolean() }.getOrElse(false)
buildTypes {
release {
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), 'proguard-rules.pro'
minifyEnabled = !skipMapping
}
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
resValue "string", "app_name", "@string/app_name_debug"
}
create("benchmark") {
initWith(getByName("release"))
applicationIdSuffix '.benchmark'
versionNameSuffix '-BENCHMARK'
resValue "string", "app_name", "@string/app_name_benchmark"
profileable = true
signingConfig = signingConfigs.debug
}
}
// TODO: remove this when lightcompressor uses one MP4 parser only
packaging {
resources {
resources.pickFirsts.add('builddef.lst')
resources.pickFirsts.add('META-INF/LICENSE.md')
resources.pickFirsts.add('META-INF/LICENSE-notice.md')
}
}
flavorDimensions = ["channel"]
productFlavors {
play {
getIsDefault().set(true)
dimension "channel"
buildConfigField "boolean", "IS_CASTING_AVAILABLE", "true"
}
fdroid {
dimension "channel"
buildConfigField "boolean", "IS_CASTING_AVAILABLE", "false"
}
}
splits {
abi {
enable = !disableAbiSplits
reset()
include "x86", "x86_64", "arm64-v8a", "armeabi-v7a"
universalApk = !disableUniversalApk
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
buildFeatures {
compose = true
buildConfig = true
resValues = true
}
packagingOptions {
resources {
excludes += ['/META-INF/{AL2.0,LGPL2.1}', '**/libscrypt.dylib']
}
}
lint {
disable 'MissingTranslation'
}
testOptions {
unitTests.returnDefaultValues = true
}
}
// TODO: until google merges and unifiedpush updates https://github.com/tink-crypto/tink-java-apps/pull/5
configurations.all {
def tink = "com.google.crypto.tink:tink-android:1.17.0"
resolutionStrategy {
force(tink)
dependencySubstitution {
substitute module('com.google.crypto.tink:tink') using module(tink)
}
}
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
}
}
composeCompiler {
reportsDestination = layout.buildDirectory.dir("compose_compiler")
metricsDestination = layout.buildDirectory.dir("compose_compiler")
}
dependencies {
implementation platform(libs.androidx.compose.bom)
implementation project(path: ':quartz')
implementation project(path: ':commons')
implementation project(path: ':nestsClient')
implementation libs.androidx.core.ktx
implementation libs.androidx.activity.compose
implementation libs.androidx.ui
implementation libs.androidx.ui.graphics
implementation libs.androidx.ui.tooling.preview
// Needs this to open gallery / image upload
implementation libs.androidx.fragment.ktx
// Navigation
implementation libs.androidx.navigation.compose
// Material 3 Design
implementation libs.androidx.material3
// Adaptive Layout / Two Pane
implementation libs.androidx.material3.windowSize
implementation libs.accompanist.adaptive
// Lifecycle
implementation libs.androidx.lifecycle.runtime.ktx
implementation libs.androidx.lifecycle.runtime.compose
implementation libs.androidx.lifecycle.viewmodel.compose
// Zoomable images
implementation libs.zoomable
// Biometrics
implementation libs.androidx.biometric.ktx
// Background Work
implementation libs.androidx.work.runtime.ktx
// Websockets API
implementation libs.okhttp
implementation libs.okhttpCoroutines
// Encrypted Key Storage
implementation libs.androidx.security.crypto.ktx
implementation libs.androidx.datastore.preferences
// view videos
implementation libs.androidx.media3.exoplayer
implementation libs.androidx.media3.exoplayer.hls
implementation libs.androidx.media3.ui.compose.material3
implementation libs.androidx.media3.session
// important for proxy / tor
implementation libs.androidx.media3.datasource.okhttp
// 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
// loads thumbnails for media3
// TODO: Replace this to the FrameExtractor in media 3
// when FrameExtractor accepts custom data sources.
implementation(libs.coil.video)
// Permission to upload pictures:
implementation libs.accompanist.permissions
// For QR generation
implementation libs.zxing
implementation libs.zxing.embedded
// Markdown
//implementation "com.halilibo.compose-richtext:richtext-ui:0.16.0"
//implementation "com.halilibo.compose-richtext:richtext-ui-material:0.16.0"
//implementation "com.halilibo.compose-richtext:richtext-commonmark:0.16.0"
// Markdown (With fix for full-image bleeds)
implementation libs.markdown.ui
implementation libs.markdown.ui.material3
implementation libs.markdown.commonmark
// Language picker and Theme chooser
implementation libs.androidx.appcompat
// Dynamically adjust between phone and tablet UI
implementation libs.androidx.window.core.android
// Local model for language identification
playImplementation libs.google.mlkit.language.id
// Google services model the translate text
playImplementation libs.google.mlkit.translate
// On-device AI writing assistance (Gemini Nano via AICore)
playImplementation libs.google.mlkit.genai.proofreading
playImplementation libs.google.mlkit.genai.prompt
playImplementation libs.google.mlkit.genai.rewriting
// On-device alt-text suggestions: genai image description (preferred, descriptive sentences)
// with image-labeling as a keyword-join fallback for devices without AICore.
playImplementation libs.google.mlkit.genai.image.description
// PushNotifications
playImplementation platform(libs.firebase.bom)
playImplementation libs.firebase.messaging
//PushNotifications(FDroid)
fdroidImplementation libs.unifiedpush
// Google Cast SDK — Chromecast support. Play flavor only because the
// framework hard-depends on Google Play services, which is unavailable
// on de-Googled / GrapheneOS devices that ship the F-Droid build.
playImplementation libs.play.services.cast.framework
// Charts
implementation libs.vico.charts.compose
implementation libs.vico.charts.m3
// Waveform visualizer
implementation libs.audiowaveform
// Video compression lib
implementation libs.abedElazizShe.video.compressor.fork
// Image compression lib
implementation libs.zelory.image.compressor
// EXIF metadata stripping
implementation libs.androidx.exifinterface
// Voice anonymization DSP
implementation libs.tarsosdsp
// WebRTC for voice/video calls
implementation libs.stream.webrtc.android
// Cbor for cashuB format
implementation libs.kotlinx.serialization.cbor
// Kotlin serialization for the times where we need the Json tree and performance is not that important.
implementation(libs.kotlinx.serialization.json)
testImplementation libs.junit
testImplementation libs.mockk
testImplementation libs.kotlinx.coroutines.test
androidTestImplementation platform(libs.androidx.compose.bom)
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.junit.ktx
androidTestImplementation libs.androidx.espresso.core
androidTestImplementation libs.androidx.ui.test.junit4
androidTestImplementation libs.mockk.android
debugImplementation platform(libs.androidx.compose.bom)
debugImplementation libs.androidx.ui.tooling
debugImplementation libs.androidx.ui.test.manifest
implementation libs.androidx.camera.core
implementation libs.androidx.camera.camera2
implementation libs.androidx.camera.lifecycle
implementation libs.androidx.camera.view
implementation libs.androidx.camera.extensions
}
+440
View File
@@ -0,0 +1,440 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.googleServices)
alias(libs.plugins.jetbrainsComposeCompiler)
alias(libs.plugins.serialization)
}
fun getCurrentBranch(): String {
return try {
val process = ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")
.redirectErrorStream(true)
.start()
val branch = process.inputStream.bufferedReader().use { it.readText() }.trim()
process.waitFor()
branch
} catch (e: Exception) {
println("Could not determine git branch: ${e.message}")
"unknown"
}
}
fun generateVersionName(baseVersion: String): String {
val currentBranch = getCurrentBranch()
if (currentBranch == "main" || currentBranch == "master" || currentBranch == "unknown" || currentBranch == "HEAD") {
return baseVersion
}
// Clean branch name for version (replace special characters)
var cleanBranch = currentBranch.replace(Regex("[^a-zA-Z0-9\\-_]"), "-")
// Limit branch name to maximum 20 characters
if (cleanBranch.length > 20) {
cleanBranch = cleanBranch.substring(0, 20)
}
return "$baseVersion-$cleanBranch"
}
// Workaround: stability.analyzer plugin doesn't declare task dependencies properly for Gradle 9.x
afterEvaluate {
val stabilityNames = tasks.names.filter { it.contains("StabilityCheck") }
val compileNames = tasks.names.filter { it.matches(Regex("compile.*UnitTestKotlin")) }
stabilityNames.forEach { scName ->
compileNames.forEach { ctName ->
tasks.named(scName).configure { mustRunAfter(tasks.named(ctName)) }
}
}
}
android {
namespace = "com.vitorpamplona.amethyst"
compileSdk = libs.versions.android.compileSdk.get().toInt()
defaultConfig {
applicationId = "com.vitorpamplona.amethyst"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = 446
versionName = generateVersionName(libs.versions.app.get())
buildConfigField("String", "RELEASE_NOTES_ID", "\"b1b91d7ee0c5da9d081d1a53470248ee4585b058b11aa34fe28c0e3e07ac1e0a\"")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
@Suppress("UnstableApiUsage")
resourceConfigurations += listOf(
"ar",
"ar-rSA",
"bn-rBD",
"cs",
"cs-rCZ",
"cy-rGB",
"da-rDK",
"de",
"de-rDE",
"el-rGR",
"en-rGB",
"eo",
"eo-rUY",
"es",
"es-rES",
"es-rMX",
"es-rUS",
"et-rEE",
"fa",
"fa-rIR",
"fi-rFI",
"fo-rFO",
"fr",
"fr-rCA",
"fr-rFR",
"gu-rIN",
"hi-rIN",
"hr-rHR",
"hu",
"hu-rHU",
"in",
"in-rID",
"it-rIT",
"iw-rIL",
"ja",
"ja-rJP",
"kk-rKZ",
"ko-rKR",
"ks-rIN",
"ku-rTR",
"lt-rLT",
"ne-rNP",
"nl",
"nl-rBE",
"nl-rNL",
"pcm-rNG",
"pl-rPL",
"pt-rBR",
"pt-rPT",
"ru",
"ru-rRU",
"ru-rUA",
"sa-rIN",
"sl-rSI",
"so-rSO",
"sr-rSP",
"ss-rZA",
"sv-rSE",
"sw-rKE",
"sw-rTZ",
"ta",
"ta-rIN",
"th",
"th-rTH",
"tr",
"tr-rTR",
"uk",
"uk-rUA",
"ur-rIN",
"uz-rUZ",
"vi-rVN",
"zh",
"zh-rCN",
"zh-rHK",
"zh-rSG",
"zh-rTW",
)
}
// Opt-in fast-build flags. Default behavior is unchanged.
//
// -PdisableAbiSplits=true skip per-ABI APK splits; produces a single
// APK per (flavor, buildType) instead of 5.
// Cuts ~600 MB of intermediates and several
// minutes off CI.
// -PdisableUniversalApk=true when ABI splits are enabled, skip the
// extra universal APK output. (No effect
// when disableAbiSplits is also set, since
// there are no splits to add to.)
// -Pamethyst.skipMapping=true disable R8 minification on release and
// benchmark. APK is larger, but builds are
// much faster and outputs/mapping/ (~260MB)
// is not produced. Local-dev and PR-CI use
// only — release pipelines must not set it.
val disableAbiSplits = providers.gradleProperty("disableAbiSplits")
.map { it.toBoolean() }.getOrElse(false)
val disableUniversalApk = providers.gradleProperty("disableUniversalApk")
.map { it.toBoolean() }.getOrElse(false)
val skipMapping = providers.gradleProperty("amethyst.skipMapping")
.map { it.toBoolean() }.getOrElse(false)
buildTypes {
getByName("release") {
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
isMinifyEnabled = !skipMapping
}
getByName("debug") {
applicationIdSuffix = ".debug"
versionNameSuffix = "-DEBUG"
resValue("string", "app_name", "@string/app_name_debug")
}
create("benchmark") {
initWith(getByName("release"))
applicationIdSuffix = ".benchmark"
versionNameSuffix = "-BENCHMARK"
resValue("string", "app_name", "@string/app_name_benchmark")
isProfileable = true
signingConfig = signingConfigs.getByName("debug")
}
}
// TODO: remove this when lightcompressor uses one MP4 parser only
packaging {
resources {
pickFirsts.add("builddef.lst")
pickFirsts.add("META-INF/LICENSE.md")
pickFirsts.add("META-INF/LICENSE-notice.md")
}
}
flavorDimensions += "channel"
productFlavors {
create("play") {
isDefault = true
dimension = "channel"
buildConfigField("boolean", "IS_CASTING_AVAILABLE", "true")
}
create("fdroid") {
dimension = "channel"
buildConfigField("boolean", "IS_CASTING_AVAILABLE", "false")
}
}
splits {
abi {
isEnable = !disableAbiSplits
reset()
include("x86", "x86_64", "arm64-v8a", "armeabi-v7a")
isUniversalApk = !disableUniversalApk
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
buildFeatures {
compose = true
buildConfig = true
resValues = true
}
packaging {
resources {
excludes += listOf("/META-INF/{AL2.0,LGPL2.1}", "**/libscrypt.dylib")
}
}
lint {
disable += "MissingTranslation"
}
testOptions {
unitTests.isReturnDefaultValues = true
}
}
// TODO: until google merges and unifiedpush updates https://github.com/tink-crypto/tink-java-apps/pull/5
configurations.all {
val tink = "com.google.crypto.tink:tink-android:1.17.0"
resolutionStrategy {
force(tink)
dependencySubstitution {
substitute(module("com.google.crypto.tink:tink")).using(module(tink))
}
}
}
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
composeCompiler {
reportsDestination = layout.buildDirectory.dir("compose_compiler")
metricsDestination = layout.buildDirectory.dir("compose_compiler")
}
dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(project(":quartz"))
implementation(project(":commons"))
implementation(project(":nestsClient"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
// Needs this to open gallery / image upload
implementation(libs.androidx.fragment.ktx)
// Navigation
implementation(libs.androidx.navigation.compose)
// Material 3 Design
implementation(libs.androidx.material3)
// Adaptive Layout / Two Pane
implementation(libs.androidx.material3.windowSize)
implementation(libs.accompanist.adaptive)
// Lifecycle
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel.compose)
// Zoomable images
implementation(libs.zoomable)
// Biometrics
implementation(libs.androidx.biometric.ktx)
// Background Work
implementation(libs.androidx.work.runtime.ktx)
// Websockets API
implementation(libs.okhttp)
implementation(libs.okhttpCoroutines)
// Encrypted Key Storage
implementation(libs.androidx.security.crypto.ktx)
implementation(libs.androidx.datastore.preferences)
// view videos
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.exoplayer.hls)
implementation(libs.androidx.media3.ui.compose.material3)
implementation(libs.androidx.media3.session)
// important for proxy / tor
implementation(libs.androidx.media3.datasource.okhttp)
// 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)
// loads thumbnails for media3
// TODO: Replace this to the FrameExtractor in media 3
// when FrameExtractor accepts custom data sources.
implementation(libs.coil.video)
// Permission to upload pictures:
implementation(libs.accompanist.permissions)
// For QR generation
implementation(libs.zxing)
implementation(libs.zxing.embedded)
// Markdown
//implementation "com.halilibo.compose-richtext:richtext-ui:0.16.0"
//implementation "com.halilibo.compose-richtext:richtext-ui-material:0.16.0"
//implementation "com.halilibo.compose-richtext:richtext-commonmark:0.16.0"
// Markdown (With fix for full-image bleeds)
implementation(libs.markdown.ui)
implementation(libs.markdown.ui.material3)
implementation(libs.markdown.commonmark)
// Language picker and Theme chooser
implementation(libs.androidx.appcompat)
// Dynamically adjust between phone and tablet UI
implementation(libs.androidx.window.core.android)
// Local model for language identification
"playImplementation"(libs.google.mlkit.language.id)
// Google services model the translate text
"playImplementation"(libs.google.mlkit.translate)
// On-device AI writing assistance (Gemini Nano via AICore)
"playImplementation"(libs.google.mlkit.genai.proofreading)
"playImplementation"(libs.google.mlkit.genai.prompt)
"playImplementation"(libs.google.mlkit.genai.rewriting)
// On-device alt-text suggestions: genai image description (preferred, descriptive sentences)
// with image-labeling as a keyword-join fallback for devices without AICore.
"playImplementation"(libs.google.mlkit.genai.image.description)
// PushNotifications
"playImplementation"(platform(libs.firebase.bom))
"playImplementation"(libs.firebase.messaging)
//PushNotifications(FDroid)
"fdroidImplementation"(libs.unifiedpush)
// Google Cast SDK — Chromecast support. Play flavor only because the
// framework hard-depends on Google Play services, which is unavailable
// on de-Googled / GrapheneOS devices that ship the F-Droid build.
"playImplementation"(libs.play.services.cast.framework)
// Charts
implementation(libs.vico.charts.compose)
implementation(libs.vico.charts.m3)
// Waveform visualizer
implementation(libs.audiowaveform)
// Video compression lib
implementation(libs.abedElazizShe.video.compressor.fork)
// Image compression lib
implementation(libs.zelory.image.compressor)
// EXIF metadata stripping
implementation(libs.androidx.exifinterface)
// Voice anonymization DSP
implementation(libs.tarsosdsp)
// WebRTC for voice/video calls
implementation(libs.stream.webrtc.android)
// Cbor for cashuB format
implementation(libs.kotlinx.serialization.cbor)
// Kotlin serialization for the times where we need the Json tree and performance is not that important.
implementation(libs.kotlinx.serialization.json)
testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.junit.ktx)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.ui.test.junit4)
androidTestImplementation(libs.mockk.android)
debugImplementation(platform(libs.androidx.compose.bom))
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.androidx.camera.core)
implementation(libs.androidx.camera.camera2)
implementation(libs.androidx.camera.lifecycle)
implementation(libs.androidx.camera.view)
implementation(libs.androidx.camera.extensions)
}
-73
View File
@@ -1,73 +0,0 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.androidBenchmark)
}
android {
namespace = 'com.vitorpamplona.amethyst.benchmark'
compileSdk = libs.versions.android.compileSdk.get().toInteger()
defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInteger()
targetSdk = libs.versions.android.targetSdk.get().toInteger()
// Enable measuring on an emulator, or devices with low battery
testInstrumentationRunner 'androidx.benchmark.junit4.AndroidBenchmarkRunner'
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR,LOW-BATTERY"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
sourceSets.androidTest.resources.srcDirs += ["../quartz/src/androidDeviceTest/resources"]
testBuildType = "benchmark"
buildTypes {
debug {
// Since debuggable can"t be modified by gradle for library modules,
// it must be done in a manifest - see src/androidTest/AndroidManifest.xml
minifyEnabled false
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "benchmark-proguard-rules.pro"
}
release {
isDefault = false
minifyEnabled = true
}
create("benchmark") {
isDefault = true
initWith(getByName("release"))
signingConfig = signingConfigs.debug
}
}
}
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
}
}
dependencies {
implementation libs.androidx.core.ktx
androidTestImplementation platform(libs.androidx.compose.bom)
androidTestImplementation libs.androidx.runner
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.junit
androidTestImplementation libs.androidx.benchmark.junit4
androidTestImplementation project(path: ':quartz')
androidTestImplementation project(path: ':commons')
// Custom C secp256k1 (libschnorr256k1) for the 3-way Android benchmark
androidTestImplementation libs.schnorr256k1.kmp
androidTestImplementation libs.androidx.compose.foundation
// Add your dependencies here. Note that you cannot benchmark code
// in an app module this way - you will need to move any code you
// want to benchmark to a library module:
// https://developer.android.com/studio/projects/android-library#Convert
}
+80
View File
@@ -0,0 +1,80 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.androidBenchmark)
}
android {
namespace = "com.vitorpamplona.amethyst.benchmark"
compileSdk = libs.versions.android.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
// Enable measuring on an emulator, or devices with low battery
testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner"
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR,LOW-BATTERY"
}
testOptions {
targetSdk = libs.versions.android.targetSdk.get().toInt()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
sourceSets {
getByName("androidTest") {
resources.directories.add(file("../quartz/src/androidDeviceTest/resources").path)
}
}
testBuildType = "benchmark"
buildTypes {
getByName("debug") {
// Since debuggable can"t be modified by gradle for library modules,
// it must be done in a manifest - see src/androidTest/AndroidManifest.xml
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "benchmark-proguard-rules.pro")
}
getByName("release") {
isDefault = false
isMinifyEnabled = true
}
create("benchmark") {
isDefault = true
initWith(getByName("release"))
signingConfig = signingConfigs.getByName("debug")
}
}
}
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
dependencies {
implementation(libs.androidx.core.ktx)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.runner)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.junit)
androidTestImplementation(libs.androidx.benchmark.junit4)
androidTestImplementation(project(":quartz"))
androidTestImplementation(project(":commons"))
// Custom C secp256k1 (libschnorr256k1) for the 3-way Android benchmark
androidTestImplementation(libs.schnorr256k1.kmp)
androidTestImplementation(libs.androidx.compose.foundation)
// Add your dependencies here. Note that you cannot benchmark code
// in an app module this way - you will need to move any code you
// want to benchmark to a library module:
// https://developer.android.com/studio/projects/android-library#Convert
}
+30 -25
View File
@@ -1,3 +1,5 @@
import com.diffplug.gradle.spotless.SpotlessExtensionPredeclare
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
@@ -13,37 +15,42 @@ plugins {
}
// Shared app version for all subprojects — read from gradle/libs.versions.toml.
// Android versionCode stays local in amethyst/build.gradle (must be monotonic int).
// Android versionCode stays local in amethyst/build.gradle.kts (must be monotonic int).
// Desktop packageVersion inherits via project.version in desktopApp/build.gradle.kts.
val appVersion = libs.versions.app.get()
allprojects {
version = libs.versions.app.get()
version = appVersion
configurations.configureEach {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
resolutionStrategy.cacheChangingModulesFor(0, "seconds")
}
apply plugin: 'com.diffplug.spotless'
apply(plugin = "com.diffplug.spotless")
if (project === rootProject) {
spotless {
predeclareDeps()
}
spotlessPredeclare {
configure<SpotlessExtensionPredeclare> {
kotlin {
ktlint('1.7.1')
ktlint("1.7.1")
}
}
} else {
spotless {
kotlin {
target 'src/**/*.kt'
target("src/**/*.kt")
ktlint('1.7.1')
licenseHeaderFile rootProject.file('.spotless/copyright.kt'), "@file:|package|import|class|object|sealed|open|interface|abstract "
ktlint("1.7.1")
licenseHeaderFile(
rootProject.file(".spotless/copyright.kt"),
"@file:|package|import|class|object|sealed|open|interface|abstract ",
)
}
groovyGradle {
target '*.gradle'
kotlinGradle {
target("*.gradle.kts")
}
}
}
@@ -55,30 +62,28 @@ subprojects {
tasks.named("preBuild") {
dependsOn("spotlessApply")
}
} catch (UnknownTaskException ignored) {
} catch (ignored: UnknownTaskException) {
tasks.matching {
it.name.startsWith("pre") && it.name.endsWith("Build")
}.configureEach {
dependsOn("spotlessApply")
}
}
}
}
tasks.register('installGitHook', Copy) {
def dotGit = new File(rootProject.rootDir, '.git')
def hooksDir
if (dotGit.isFile()) {
val installGitHook = tasks.register<Copy>("installGitHook") {
val dotGit = File(rootProject.rootDir, ".git")
val hooksDir: File = if (dotGit.isFile) {
// Git worktree: .git is a file with "gitdir: <path>"
def gitDir = new File(dotGit.text.trim().replace('gitdir: ', ''))
hooksDir = new File(gitDir, 'hooks')
val gitDir = File(dotGit.readText().trim().replace("gitdir: ", ""))
File(gitDir, "hooks")
} else {
hooksDir = new File(dotGit, 'hooks')
File(dotGit, "hooks")
}
from new File(rootProject.rootDir, '.git-hooks/pre-commit')
from new File(rootProject.rootDir, '.git-hooks/pre-push')
into { hooksDir }
filePermissions { unix(0777) }
from(File(rootProject.rootDir, ".git-hooks/pre-commit"))
from(File(rootProject.rootDir, ".git-hooks/pre-push"))
into(hooksDir)
filePermissions { unix("0777") }
}
tasks.getByPath(':amethyst:preBuild').dependsOn installGitHook
tasks.getByPath(":amethyst:preBuild").dependsOn(installGitHook)
+16 -16
View File
@@ -10,9 +10,9 @@ pluginManagement {
mavenCentral()
gradlePluginPortal()
maven {
url = "https://jitpack.io"
url = uri("https://jitpack.io")
content {
includeModule 'com.github.UnifiedPush', 'android-connector'
includeModule("com.github.UnifiedPush", "android-connector")
}
}
}
@@ -24,21 +24,21 @@ dependencyResolutionManagement {
mavenLocal()
google()
mavenCentral()
maven { url = "https://jitpack.io" }
maven { url = "https://raw.githubusercontent.com/guardianproject/gpmaven/master" }
maven { url = "https://mvn.0110.be/releases" }
maven { url = uri("https://jitpack.io") }
maven { url = uri("https://raw.githubusercontent.com/guardianproject/gpmaven/master") }
maven { url = uri("https://mvn.0110.be/releases") }
}
}
rootProject.name = "Amethyst"
include ':amethyst'
include ':benchmark'
include ':quartz'
include ':geode'
include ':commons'
include ':quic'
include ':nestsClient'
include ':desktopApp'
include ':cli'
include ':quic-interop'
project(':quic-interop').projectDir = file('quic/interop')
include(":amethyst")
include(":benchmark")
include(":quartz")
include(":geode")
include(":commons")
include(":quic")
include(":nestsClient")
include(":desktopApp")
include(":cli")
include(":quic-interop")
project(":quic-interop").projectDir = file("quic/interop")