Take ktfmt's defaults for the Kotlin half
The server half went to rustfmt's defaults earlier today; this is the same move for the app, and the same reasoning. Kotlin ships no formatter with the Gradle build, so the question was which to adopt: ktfmt is Kotlin-org owned now (it moved from facebook/ktfmt), is a formatter rather than a configurable linter, and has essentially nothing to tune -- which is what rule 27 is asking for. ktlint's .editorconfig surface is the thing that rule warns against, and detekt is static analysis, whose job Android Lint already does here. One setting, and it is a choice between the tool's own two styles rather than a tuning: kotlinLangStyle() is the 4-space one, which is what this code already was. The 2-space default would have reindented every file to say nothing. ./gradlew :androidApp:ktfmtFormat to apply ./gradlew :androidApp:ktfmtCheck to verify Formatting only. The one thing worth checking by hand was the generated PEM constant, since a leading newline there costs Android's CertificateFactory its preamble sniff and fails at runtime nowhere near the cause: ktfmt moved `.trimMargin()` onto its own line and left the template alone, and the regenerated constant still starts at the opening quotes. Verified after: ktfmtCheck, compileDebugKotlin and lintDebug all pass, and the APK builds. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw
This commit is contained in:
1 parent
dde5042b12
commit
0c13090d70
16 files changed
+585
-496
No files matched your search
@@ -2,8 +2,18 @@ plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
alias(libs.plugins.ktfmt)
|
||||
}
|
||||
|
||||
// Formatting is the formatter's. The one setting is which of ktfmt's two
|
||||
// styles: kotlinlang is the 4-space one, which is what this code already
|
||||
// is -- picking the 2-space default would have reindented every file to
|
||||
// say nothing. Everything else stays at ktfmt's defaults, deliberately.
|
||||
//
|
||||
// ./gradlew :androidApp:ktfmtFormat to apply
|
||||
// ./gradlew :androidApp:ktfmtCheck to verify
|
||||
ktfmt { kotlinLangStyle() }
|
||||
|
||||
// The CA this app pins is baked in at build time from the certificates on
|
||||
// the machine doing the build -- `$XDG_CONFIG_HOME/ai-app/certs/ca.pem`,
|
||||
// which the server generates on first start. AI_APP_CA overrides the path.
|
||||
@@ -15,19 +25,18 @@ plugins {
|
||||
// is no second trust anchor to get wrong, and no stale paste to notice
|
||||
// three days later. It also means the private key never has to exist
|
||||
// anywhere near this repo.
|
||||
val pinnedCaPath: String = System.getenv("AI_APP_CA")
|
||||
?: "${System.getenv("XDG_CONFIG_HOME") ?: "${System.getProperty("user.home")}/.config"}" +
|
||||
"/ai-app/certs/ca.pem"
|
||||
val pinnedCaPath: String =
|
||||
System.getenv("AI_APP_CA")
|
||||
?: "${System.getenv("XDG_CONFIG_HOME") ?: "${System.getProperty("user.home")}/.config"}" +
|
||||
"/ai-app/certs/ca.pem"
|
||||
|
||||
abstract class GeneratePinnedCert : DefaultTask() {
|
||||
/** Where the certificate is looked for, reported in failures. */
|
||||
@get:Input
|
||||
abstract val caPath: Property<String>
|
||||
@get:Input abstract val caPath: Property<String>
|
||||
|
||||
/**
|
||||
* The certificate itself, set only when it exists -- so a missing one
|
||||
* produces this task's own instructions rather than Gradle's "no such
|
||||
* input file", which doesn't say what to run.
|
||||
* The certificate itself, set only when it exists -- so a missing one produces this task's own
|
||||
* instructions rather than Gradle's "no such input file", which doesn't say what to run.
|
||||
*/
|
||||
@get:InputFile
|
||||
@get:Optional
|
||||
@@ -35,8 +44,7 @@ abstract class GeneratePinnedCert : DefaultTask() {
|
||||
abstract val caCertificate: RegularFileProperty
|
||||
|
||||
/** Wired by AGP through `addGeneratedSourceDirectory`. */
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
@get:OutputDirectory abstract val outputDir: DirectoryProperty
|
||||
|
||||
@TaskAction
|
||||
fun generate() {
|
||||
@@ -47,7 +55,7 @@ abstract class GeneratePinnedCert : DefaultTask() {
|
||||
"No CA certificate at $path.\n" +
|
||||
"Start ai-server once on this machine first -- it generates the CA the " +
|
||||
"app pins, and the certificate has to exist before an APK can embed it.\n" +
|
||||
"Set AI_APP_CA=/path/to/ca.pem to build against a different one.",
|
||||
"Set AI_APP_CA=/path/to/ca.pem to build against a different one."
|
||||
)
|
||||
}
|
||||
val pem = ca.readText().trim()
|
||||
@@ -69,18 +77,20 @@ abstract class GeneratePinnedCert : DefaultTask() {
|
||||
|const val PINNED_CA_PEM = ""${'"'}$pem
|
||||
|""${'"'}
|
||||
|
|
||||
""".trimMargin(),
|
||||
"""
|
||||
.trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val generatePinnedCert = tasks.register<GeneratePinnedCert>("generatePinnedCert") {
|
||||
val ca = file(pinnedCaPath)
|
||||
caPath.set(pinnedCaPath)
|
||||
if (ca.isFile) {
|
||||
caCertificate.set(ca)
|
||||
val generatePinnedCert =
|
||||
tasks.register<GeneratePinnedCert>("generatePinnedCert") {
|
||||
val ca = file(pinnedCaPath)
|
||||
caPath.set(pinnedCaPath)
|
||||
if (ca.isFile) {
|
||||
caCertificate.set(ca)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.aiapp"
|
||||
@@ -93,16 +103,8 @@ android {
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } }
|
||||
buildTypes { getByName("release") { isMinifyEnabled = false } }
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
|
||||
Reference in new issue
Block a user