Files
amethyst/.claude/skills/gradle-expert/references/dependency-graph.md
T

266 lines
8.8 KiB
Markdown

# Module Dependency Graph
## Visual Hierarchy
```
┌─────────────────────────────────────────────────────────┐
│ Root Project │
│ (Amethyst) │
└─────────────────────────────────────────────────────────┘
┌────────────────┼────────────────┬────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐
│ :amethyst │ │ :desktopApp │ │ :benchmark │ │:ammolite │
│ (Android) │ │ (JVM) │ │ (Android) │ │ (Support)│
└─────────────┘ └─────────────┘ └─────────────┘ └──────────┘
│ │ │
│ │ │
└────────────────┼────────────────┘
┌─────────────┐
│ :commons │
│ (KMP UI) │
│ │
│ jvmAndroid │
│ / \ │
│ jvm android│
└─────────────┘
┌─────────────┐
│ :quartz │
│(KMP Library)│
│ │
│ commonMain │
│ │ │
│ jvmAndroid │
│ / | \ │
│jvm and ios │
└─────────────┘
```
## Module Details
### :quartz (KMP Nostr Library)
**Type:** Kotlin Multiplatform Library
**Targets:** JVM, Android, iOS (iosArm64, iosSimulatorArm64)
**Dependencies:**
- External: secp256k1, jackson, okhttp, kotlinx.coroutines, kotlinx.collections.immutable
- Source sets: commonMain → jvmAndroid → {androidMain, jvmMain}, iosMain
**Role:** Core Nostr protocol implementation, shared across all platforms
### :commons (Shared UI Components)
**Type:** Kotlin Multiplatform Library
**Targets:** JVM, Android
**Dependencies:**
- Module: `:quartz`
- External: Compose Multiplatform, Material3, kotlinx.collections.immutable
- Source sets: commonMain → jvmAndroid → {androidMain, jvmMain}
**Role:** Shared Compose UI components for Desktop and Android
### :desktopApp (Desktop Application)
**Type:** JVM Application
**Targets:** JVM (Desktop)
**Dependencies:**
- Modules: `:commons`, `:quartz`
- External: Compose Desktop, kotlinx.coroutines.swing
**Role:** Desktop-specific navigation, layouts, and entry point
### :amethyst (Android Application)
**Type:** Android Application
**Targets:** Android
**Dependencies:**
- Modules: `:commons`, `:quartz`, `:ammolite`
- External: Android SDK, AndroidX, Firebase, Tor
**Role:** Android-specific navigation, layouts, and entry point
### :benchmark (Android Benchmark)
**Type:** Android Library
**Targets:** Android
**Dependencies:**
- Modules: `:commons`, `:quartz`
- External: AndroidX Benchmark
**Role:** Performance benchmarking for Android builds
### :ammolite (Support Module)
**Type:** Android Library
**Targets:** Android
**Dependencies:** Android-specific utilities
**Role:** Android support utilities for amethyst
## Dependency Flow Patterns
### Desktop Build Chain
```
:desktopApp → :commons (jvmMain) → :quartz (jvmMain)
jvmAndroid
commonMain
```
### Android Build Chain
```
:amethyst → :commons (androidMain) → :quartz (androidMain)
↓ ↓
:ammolite jvmAndroid
commonMain
```
## Source Set Dependencies
### :quartz Source Sets
```
commonMain (base)
├─ jvmAndroid (shared JVM code)
│ ├─ androidMain (Android platform)
│ └─ jvmMain (Desktop platform)
└─ iosMain (iOS platform)
├─ iosArm64Main
└─ iosSimulatorArm64Main
```
**Key Dependencies per Source Set:**
- **commonMain**: secp256k1-kmp, kotlinx.coroutines, collection, immutable collections
- **jvmAndroid**: jackson, okhttp, url-detector, rfc3986
- **androidMain**: secp256k1-kmp-jni-android, lazysodium-android, jna (aar)
- **jvmMain**: secp256k1-kmp-jni-jvm, lazysodium-java, jna (jar)
### :commons Source Sets
```
commonMain (base UI)
└─ jvmAndroid (shared JVM UI)
├─ androidMain (Android UI utilities)
└─ jvmMain (Desktop UI utilities)
```
**Key Dependencies per Source Set:**
- **commonMain**: Compose Multiplatform, Material3, :quartz
- **jvmAndroid**: url-detector
- **androidMain**: AndroidX Compose tooling
- **jvmMain**: Compose Desktop
## Critical Dependency Patterns
### 1. secp256k1 Variants
```kotlin
// commonMain - API only
api(libs.secp256k1.kmp.common)
// androidMain - JNI Android
api(libs.secp256k1.kmp.jni.android)
// jvmMain - JNI JVM
implementation(libs.secp256k1.kmp.jni.jvm)
```
**Why:** Different JNI bindings for Android vs Desktop JVM
### 2. JNA Variants (for LibSodium)
```kotlin
// androidMain
implementation("com.goterl:lazysodium-android:5.2.0@aar")
implementation("net.java.dev.jna:jna:5.18.1@aar")
// jvmMain
implementation(libs.lazysodium.java)
implementation(libs.jna) // JAR variant
```
**Why:** Android needs AAR packaging, JVM needs JAR
### 3. Compose Alignment
```kotlin
// commons/build.gradle.kts
implementation(compose.ui) // Compose Multiplatform BOM
implementation(compose.material3)
// Version catalog alignment
composeMultiplatform = "1.9.3"
composeBom = "2025.12.01" // AndroidX Compose
```
**Why:** Two Compose ecosystems (Multiplatform + AndroidX) must align
## Dependency Configuration Types
### API vs Implementation
**Use `api` when:**
- Dependency types appear in module's public API
- Used in expect/actual declarations visible to consumers
- Example: `secp256k1-kmp-common` in quartz (public types)
**Use `implementation` when:**
- Internal implementation detail
- Not exposed to module consumers
- Example: `okhttp` in quartz (internal network client)
### Example from quartz
```kotlin
// Public API - exposed to consumers
api(libs.secp256k1.kmp.common)
api(libs.jackson.module.kotlin) // Event serialization public
// Internal implementation
implementation(libs.okhttp)
implementation(libs.kotlinx.coroutines.core)
```
## Transitive Dependency Impact
### When :desktopApp depends on :commons
- Gets `:quartz` transitively (via :commons)
- Gets `secp256k1-kmp-jvm` transitively (via :quartz jvmMain)
- Does NOT get Android-specific dependencies (scoped to androidMain)
### When :amethyst depends on :commons
- Gets `:quartz` transitively (via :commons)
- Gets `secp256k1-kmp-jni-android` transitively (via :quartz androidMain)
- Does NOT get JVM/Desktop-specific dependencies (scoped to jvmMain)
## Verifying Dependencies
### Check Module Dependencies
```bash
./gradlew :desktopApp:dependencies
./gradlew :amethyst:dependencies
```
### Check Specific Library
```bash
./gradlew dependencyInsight --dependency secp256k1
./gradlew dependencyInsight --dependency compose-ui
```
### Visualize with Build Scan
```bash
./gradlew :desktopApp:dependencies --scan
# Opens interactive dependency graph in browser
```
## Common Dependency Issues
### Issue 1: Wrong secp256k1 Variant in Desktop
**Symptom:** `UnsatisfiedLinkError: no secp256k1jni in java.library.path`
**Cause:** Desktop using Android JNI variant
**Fix:** Ensure jvmMain uses `secp256k1-kmp-jni-jvm`
### Issue 2: Compose Version Mismatch
**Symptom:** `IllegalStateException: Version mismatch`
**Cause:** Compose Multiplatform plugin vs runtime version mismatch
**Fix:** Align `composeMultiplatform` version in libs.versions.toml with Kotlin plugin
### Issue 3: Duplicate JNA Classes
**Symptom:** `DuplicateClassException: com.sun.jna.Native`
**Cause:** Both JAR and AAR JNA variants in classpath
**Fix:** Use AAR (@aar) in androidMain, JAR in jvmMain (never in shared source sets)