diff --git a/TICKETS.md b/TICKETS.md index 575860d7..cae50d73 100644 --- a/TICKETS.md +++ b/TICKETS.md @@ -172,11 +172,11 @@ External multimodule OSS validation of meta-build axioms (structure over configu type-owned plugins, attrs-only call sites, closed matrix). **Not** another in-repo sample. Open coding: **F-115** (`in_progress`). **F-094** Portal remains `blocked` (human). -4h workers: pick F-115 phase C remainder (Firebase / more features) unless blocked; do not `[SILENT]` while F-115 is open. +4h workers: pick F-115 phase C remainder (more features / DataStore / sync) unless blocked; do not `[SILENT]` while F-115 is open. | ID | Status | Title | Notes | |----|--------|-------|-------| -| F-115 | in_progress | Dogfood Now in Android under Forma | Primary OSS target [`android/nowinandroid`](https://github.com/android/nowinandroid). Design: [`docs/DOGFOOD-NIA.md`](docs/DOGFOOD-NIA.md). **Phase A+B+C Hilt+Room done:** spike green with Hilt Path A + Room Path B (`roomAndroidUtil` / `androidUtilTarget`), data OfflineFirst+DAO, topic+interests (no impl→impl). Engine: KSP companion (F12) + `androidUtilTarget` (F15). **Next phase C:** Firebase binary, more features. No `androidLibrary`. | +| F-115 | in_progress | Dogfood Now in Android under Forma | Primary OSS target [`android/nowinandroid`](https://github.com/android/nowinandroid). Design: [`docs/DOGFOOD-NIA.md`](docs/DOGFOOD-NIA.md). **Phase A+B+C Hilt+Room+Firebase done:** spike green with Hilt Path A + Room Path B + **Firebase Path A** (`hiltFirebaseBinary`, dummy GMS JSON, Analytics/Crashlytics API on binary). Engine: KSP companion (F12) + `androidUtilTarget` (F15). Findings F16/F17 (stack Path A; `transitiveDeps` for Firebase SDKs). **Next phase C:** more features / DataStore / sync. No `androidLibrary`. | ## Backlog (lower priority / historical GitHub) diff --git a/docs/DOGFOOD-NIA.md b/docs/DOGFOOD-NIA.md index fdc460c9..ad17e608 100644 --- a/docs/DOGFOOD-NIA.md +++ b/docs/DOGFOOD-NIA.md @@ -1,6 +1,6 @@ # Dogfood: Now in Android → Forma (F-115) -**Status:** `in_progress` — phase C Hilt Path A + **Room Path B green** (Firebase / more features next) +**Status:** `in_progress` — phase C Hilt + Room + **Firebase Path A green** (more features next) **Upstream:** [android/nowinandroid](https://github.com/android/nowinandroid) (Apache-2.0) **Pinned checkout (local):** `/Users/claw/work/nowinandroid` @ `7d45eae` (main tip when cloned 2026-07-29) **Dogfood fork:** `/Users/claw/work/nowinandroid-forma` @@ -223,7 +223,20 @@ Workspace: same **`forma-spike`** external tree. | Classpath | `extraPlugins` += Room Gradle plugin (`libs.plugins.room`) | | Verify | `forma-spike` `./gradlew :binary:assembleDebug` → **BUILD SUCCESSFUL** (266 tasks); KSP `TopicDao_Impl` / `NiaDatabase_Impl`; APK ~10 MB | -**Still open in phase C:** Firebase binary, remaining features, full designsystem, DataStore UserData. +**Still open in phase C (pre-Firebase):** remaining features, full designsystem, DataStore UserData. + +### Phase C — Firebase Path A ✅ (2026-07-30) + +| Step | Result | +|------|--------| +| `forma-defs` | `FirebaseBinary.kt` — Path A GMS + Crashlytics on `AndroidTargetTypes.binary` + thin **`hiltFirebaseBinary`** (stacks Hilt + Firebase via accumulate register) | +| Classpath | `extraPlugins` += `gmsServices` + `firebaseCrashlytics` (catalog names); settings `plugin(...)` GAVs | +| Binary | Dummy `google-services.json` (package `…spike`); `NiaSpikeApp` calls `FirebaseApp` / Crashlytics / Analytics | +| Companions | **`transitiveDeps`** for Crashlytics + Analytics (not `deps`/`.dep`) so `firebase-common` is on binary compile classpath | +| Verify | `forma-spike` `./gradlew :binary:assembleDebug` → **BUILD SUCCESSFUL** (268 tasks); `processDebugGoogleServices` + Crashlytics inject tasks green | +| In-repo | Example **14** Path A companions aligned to `transitiveDeps` (same F17 lesson) | + +**Still open in phase C:** remaining NiA features (foryou/bookmarks/search/settings), flavors, full designsystem, DataStore UserData, WorkManager sync. ### Phase D — Case study write-up @@ -247,6 +260,8 @@ Workspace: same **`forma-spike`** external tree. | F13 | 2026-07-29 | Hilt Application placement | `@HiltAndroidApp` must live on `com.android.application` (`androidBinary` / `hiltBinary`), not library-shell `androidApp` | | F14 | 2026-07-30 | Path B does not inherit base type plugins | `deriveTargetType` clones matrix/content rules only; plugin registry is per-type. Room util must **re-register Hilt** (or stack plugins on the derived type) — not rely on Path A `androidUtil` Hilt alone | | F15 | 2026-07-30 | No public `androidUtil(type=)` before helper | Engine needed `androidUtilTarget` (like `resourcesTarget`) so Path B Room DSL can pass derived type + processor features | +| F16 | 2026-07-30 | Hilt + Firebase both need Path A on binary | `TargetPluginRegistry` **accumulates** plugins per type (dedup by id). Thin `hiltFirebaseBinary` loads both binding objects then `androidBinary`. | +| F17 | 2026-07-30 | Firebase SDKs via `.dep` / `deps()` non-transitive | Crashlytics/Analytics AARs resolve but **without** `firebase-common` → `FirebaseApp` unresolved on binary. **Fix:** type-owned companions use `transitiveDeps(...)` (BOM still `transitivePlatform`). Example 14 companions fixed the same way. | ## Local reference commands diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 24ed93c3..4a9bf232 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -2,6 +2,26 @@ Newest entries first. +## 2026-07-30 — F-115: NiA dogfood Firebase Path A + transitive Firebase SDKs + +- **Ticket:** F-115 still `in_progress` (more features / DataStore / sync next) +- **Skills/modes:** Hermes direct dogfood (external spike + example 14 companion fix; no engine DSL change) +- **External tree:** `/Users/claw/work/nowinandroid-forma/forma-spike` + - `forma-defs/FirebaseBinary.kt` — Path A GMS + Crashlytics on binary; thin `hiltFirebaseBinary` stacks Hilt+Firebase + - `binary/google-services.json` dummy; `NiaSpikeApp` real Firebase API use + - Classpath: `extraPlugins` + settings plugins for GMS/Crashlytics Gradle plugins + - Findings **F16** (Path A accumulate stack), **F17** (`transitiveDeps` required for Firebase SDKs on binary) +- **In-repo:** `examples/android/14-google-firebase` Path A companions → `transitiveDeps` (same F17) +- **Verify (real host):** + - `forma-spike` `./gradlew :binary:assembleDebug` → **BUILD SUCCESSFUL** (268 tasks) + - Tasks: `processDebugGoogleServices`, `injectCrashlyticsMappingFileIdDebug`, Hilt aggregate green + - APK `binary-debug.apk` ~12.7 MB + - Example 14 `./gradlew :binary:assembleDebug` → **BUILD SUCCESSFUL** +- **Docs:** `docs/DOGFOOD-NIA.md` phase C Firebase + F16/F17; TICKETS F-115 notes; spike README +- **Commits/PRs:** this branch → PR base `v2` +- **Blockers:** none product; F-094 Portal still human-blocked +- **Next:** more NiA features and/or DataStore UserData / WorkManager sync + ## 2026-07-30 — F-115: NiA dogfood Room Path B + androidUtilTarget - **Ticket:** F-115 still `in_progress` (Firebase / more features next) diff --git a/examples/android/14-google-firebase/README.md b/examples/android/14-google-firebase/README.md index 295787a4..d783c8a0 100644 --- a/examples/android/14-google-firebase/README.md +++ b/examples/android/14-google-firebase/README.md @@ -26,6 +26,9 @@ printf 'sdk.dir=%s\n' "$ANDROID_HOME" > local.properties ## Notes - This is **not** a live Firebase backend — the JSON is a dummy for assemble. - Production apps: real `google-services.json` from the Firebase console; never commit secrets. +- Path A companions use **`transitiveDeps`** for Crashlytics/Analytics (not `deps`/`.dep`) so + `firebase-common` lands on the binary compile classpath when Application code lives there + (NiA dogfood finding **F17** / F-115). - Gold sample Architecture Components / Room / Navigation coverage: [`docs/GOOGLE-LIBRARIES.md`](../../../docs/GOOGLE-LIBRARIES.md). - Sample app still has Crashlytics on the **buildscript classpath** only (TODO Path B diff --git a/examples/android/14-google-firebase/forma-defs/src/main/kotlin/FirebaseBinary.kt b/examples/android/14-google-firebase/forma-defs/src/main/kotlin/FirebaseBinary.kt index af847ef0..51478271 100644 --- a/examples/android/14-google-firebase/forma-defs/src/main/kotlin/FirebaseBinary.kt +++ b/examples/android/14-google-firebase/forma-defs/src/main/kotlin/FirebaseBinary.kt @@ -19,11 +19,13 @@ import tools.forma.owners.Owner * * Call sites stay attributes-only — no plugin ids. */ +// transitiveDeps: Crashlytics/Analytics need firebase-common on the consumer compile +// classpath when Application code lives on binary. deps()/String.dep are non-transitive. private val firebaseBomAndSdks: FormaDependency = transitivePlatform("com.google.firebase:firebase-bom:33.16.0") + - deps( - "com.google.firebase:firebase-crashlytics".dep, - "com.google.firebase:firebase-analytics".dep, + transitiveDeps( + "com.google.firebase:firebase-crashlytics", + "com.google.firebase:firebase-analytics", ) private val googleServices = targetPlugin(id = "com.google.gms.google-services")