ADFA-4911: Inject plugin-api + builder coordinates into localMvnRepository during onboarding - #1600
Conversation
…lMvnRepository Ship plugin-api (fat compile jar) + plugin-builder + the Gradle plugin marker as a sibling asset that onboarding merges into the on-device localMvnRepository, so plugins resolve the API and builder by coordinate, offline, with no libs/ jars.
…e flavors - localMvnRepository archive branch wipes its dir and entries install concurrently, so apply the plugin overlay inside that branch (not a separate racing entry). - common/eventbus-events/idetooltips carry v7/v8 flavors; harvest v8 classes.jar for the fat plugin-api coordinate.
…o a build-dir maven repo
…s-events + idetooltips)
…ring onboarding Split LOCAL_MAVEN_REPO_ARCHIVE_ZIP_NAME out of the shared archive branch in both BundledAssetsInstaller and SplitAssetsInstaller so the harvested repo extract (wipe+extract) is followed, in the same job, by a merge (no wipe) of plugin-maven-repo.zip via AssetsInstallationHelper.extractZipToDir. This keeps the overlay out of the concurrent install-entry race that would otherwise let the generic archive branch's destDir.deleteRecursively() wipe it. Adds ExtractZipToDirMergeTest to pin the merge/no-wipe and path-traversal contract both installers depend on.
… 8.8.2 implementation The builder pinned com.android.tools.build:gradle:8.8.2 (the CoGo app's own `agp`) as an `implementation` dep, so its published POM forced 8.8.2 as a runtime transitive. But on-device plugin builds use the tooling AGP (`agp-tooling` = 8.11.0), which is what the harvested localMvnRepository ships -- so resolving the builder-by-coordinate offline failed: "Could not find com.android.tools.build:gradle:8.8.2". Fix: compile against 8.11.0 and make it compileOnly. AGP is supplied at runtime by the plugin project's own com.android.application, so the builder must not force its own AGP. The published plugin-builder POM is now dependency-free; plugin-api + builder + marker resolve offline, and the builder plugin applies and runs against the harvested AGP. Found by the ADFA-4911 end-to-end offline verification (Task 7).
…ead for the plugin-api coordinate The fat plugin-api jar bundles plugin-api + common + eventbus-events + idetooltips. plugin-api pinned languageVersion 2.1 (metadata 2.1.0) and the three add-ons inherited the project's 2.3.0 (metadata 2.3.0). The on-device Kotlin compiler that builds plugins is 1.9.22, which reads metadata only up to 2.0.0 -- so a plugin compiling against the coordinate failed: "compiled with an incompatible version of Kotlin ... metadata is 2.1.0 / 2.3.0, expected ... up to 2.0.0". Pin all four modules to languageVersion/apiVersion 2.0 so every class in the coordinate emits metadata 2.0.0. Verified: offline coordinate-only plugin build now compiles against the fat jar and produces a .cgp with no -Xskip-metadata-version-check; plugin-api apiCheck and the full app compile still pass. Found by the ADFA-4911 end-to-end offline verification (Task 7). Shipped on-device toolchain: AGP 8.11.0, Kotlin 1.9.22, Gradle 8.14.3, JDK 21.
The tests exercise the real extractZipToDir (no stubs were ever defined), so mockkObject(AssetsInstallationHelper) did nothing but leak a process-global object mock (no unmock), which could bleed into other tests sharing the JVM.
…irement On-device offline builds resolve AGP/Kotlin from the harvested localMvnRepository (AGP 8.11.0, Kotlin 1.9.22), and require AGP declared apply-false at the root so CoGo's init-script LogSenderPlugin resolves AGP's ApplicationVariant. Verified on emulator via a coordinate-only offline .cgp build.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
📝 Walkthrough
WalkthroughThe PR builds a Maven repository containing plugin API and builder artifacts, packages it into bundled and split assets, merges it into the on-device local Maven repository during installation, and documents coordinate-based plugin authoring. ChangesPlugin Maven repository injection
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant app_build_gradle
participant AndroidIDEAssetsPlugin
participant BundledOrSplitInstaller
participant LocalMavenRepository
app_build_gradle->>AndroidIDEAssetsPlugin: provide plugin-maven-repo.zip
AndroidIDEAssetsPlugin->>BundledOrSplitInstaller: package bundled or split asset
BundledOrSplitInstaller->>LocalMavenRepository: extract harvested repository
BundledOrSplitInstaller->>LocalMavenRepository: merge plugin Maven overlay
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
app/src/test/java/com/itsaky/androidide/assets/ExtractZipToDirMergeTest.kt (1)
3-6: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMigrate this test to JUnit Jupiter and Truth.
This new test introduces
org.junit.Testand JUnit 4 assertions. Use JUnit Jupiter annotations/assertions instead, and apply Truth for equality/boolean checks where appropriate.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/test/java/com/itsaky/androidide/assets/ExtractZipToDirMergeTest.kt` around lines 3 - 6, Update ExtractZipToDirMergeTest to use JUnit Jupiter’s Test annotation and assertions instead of org.junit.Test and JUnit 4 Assert imports; replace equality and boolean checks with the project’s Truth assertions, while preserving the test behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/build.gradle.kts`:
- Around line 492-507: Update writePluginApiPom to create pomFile’s parent
directory before calling writeText, ensuring the task succeeds when run directly
or before assemblePluginApiFatJar. Use the existing pomFile path and create its
parent without changing the generated POM content.
In
`@docs/superpowers/plans/2026-07-28-inject-plugin-coordinates-localmvnrepository.md`:
- Line 17: Align both design documents with the shipped dependency model: in
docs/superpowers/plans/2026-07-28-inject-plugin-coordinates-localmvnrepository.md
lines 17, 48-50, and 104-109, remove the claim that plugin-api build files
remain untouched, document compileOnly AGP 8.11.0, and describe a
dependency-free builder POM; in
docs/superpowers/specs/2026-07-28-inject-plugin-coordinates-localmvnrepository-design.md
lines 64-69 and 172-175, replace the builder-POM transitive dependency
requirement and add plugin-api/build.gradle.kts to the touched-file list.
---
Nitpick comments:
In `@app/src/test/java/com/itsaky/androidide/assets/ExtractZipToDirMergeTest.kt`:
- Around line 3-6: Update ExtractZipToDirMergeTest to use JUnit Jupiter’s Test
annotation and assertions instead of org.junit.Test and JUnit 4 Assert imports;
replace equality and boolean checks with the project’s Truth assertions, while
preserving the test behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 3b987166-dc34-48c3-a8e1-85d399938493
📒 Files selected for processing (16)
.gitignoreapp/build.gradle.ktsapp/src/main/java/com/itsaky/androidide/assets/BundledAssetsInstaller.ktapp/src/main/java/com/itsaky/androidide/assets/SplitAssetsInstaller.ktapp/src/test/java/com/itsaky/androidide/assets/ExtractZipToDirMergeTest.ktcommon/build.gradle.ktscomposite-builds/build-deps-common/constants/src/main/java/org/adfa/constants/constants.ktcomposite-builds/build-logic/plugins/src/main/java/com/itsaky/androidide/plugins/AndroidIDEAssetsPlugin.ktdocs/PLUGIN_API_CHANGELOG.mddocs/PLUGIN_AUTHORING.mddocs/superpowers/plans/2026-07-28-inject-plugin-coordinates-localmvnrepository.mddocs/superpowers/specs/2026-07-28-inject-plugin-coordinates-localmvnrepository-design.mdeventbus-events/build.gradle.ktsidetooltips/build.gradle.ktsplugin-api/build.gradle.ktsplugin-api/plugin-builder/build.gradle.kts
createPluginMavenRepoZip depends on both writePluginApiPom and assemblePluginApiFatJar but declares no order between them; the staging dir was only created as a side effect of the Jar task, so writePluginApiPom could run first (or standalone) and fail with FileNotFoundException. mkdirs() the parent.
The final implementation differs from the pre-implementation planning docs: - The four module build files (plugin-api/common/eventbus-events/idetooltips) ARE edited (Kotlin languageVersion/apiVersion 2.0 pins), not untouched. - The builder declares AGP compileOnly 8.11.0 (not implementation 8.8.2), so its published POM is dependency-free; plugin-builder applies maven-publish.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@docs/superpowers/specs/2026-07-28-inject-plugin-coordinates-localmvnrepository-design.md`:
- Around line 68-73: Align the coordinate table’s builder POM description with
the dependency-free claim in the surrounding section. Update the “real
config-time deps” wording to state that AGP is compile-only and excluded from
the published POM, while preserving the distinction between compile-time
availability and published transitive dependencies.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: df8bf3db-afb8-4d94-b097-f55ef26d5d81
📒 Files selected for processing (3)
app/build.gradle.ktsdocs/superpowers/plans/2026-07-28-inject-plugin-coordinates-localmvnrepository.mddocs/superpowers/specs/2026-07-28-inject-plugin-coordinates-localmvnrepository-design.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/superpowers/plans/2026-07-28-inject-plugin-coordinates-localmvnrepository.md
ADFA-4911: Inject plugin-api + builder coordinates into localMvnRepository during onboarding
During CoGo onboarding, materialize the plugin-api + plugin-builder Maven coordinates and the
com.itsaky.androidide.plugins.buildGradle plugin marker into the on-devicelocalMvnRepository, so plugin projects resolve them by coordinate, offline, with nolibs/*.jar. Unblocks building plugins inside CoGo at scale (ADFA-4693).How it works
plugin-maven-repo.zip:com.itsaky.androidide:plugin-api:1.0.0jar (merged classes ofplugin-api+common+eventbus-events+idetooltips) with a dependency-free POM (it's compile-only/provided);plugin-builderimpl + POM + the plugin marker, emitted by realmaven-publish.Shipped as both a bundled
.brasset and a split-zip entry.BundledAssetsInstaller,SplitAssetsInstaller) merge that zip intoLOCAL_MAVEN_DIRinside the existinglocalMvnRepositorybranch (after its wipe+extract, via the non-wipingextractZipToDir) — avoiding a wipe/concurrency race. The overlay is deliberately not a separate install entry.Onboarding reuses the already-shipped artifacts as the single source of truth, keeps versions in sync automatically, and leaves the fragile harvest pipeline untouched.
On-device version pins
The fat
plugin-api+ the three add-on modules pin KotlinlanguageVersion/apiVersionto 2.0 so their metadata is readable by the on-device Kotlin 1.9.22 compiler; the builder targets on-device AGP 8.11.0 ascompileOnly(dependency-free published POM) so offline resolution doesn't drag transitives.Verification
ExtractZipToDirMergeTest: the merge primitive adds overlay entries without wiping existing files and rejects path traversal.app/module, nolibs/) builds:app:assemblePluginDebugfully offline (device network cut +--offline) to an 818 KB.cgp(valid archive,classes.dexcompiled against the coordinate). No resolution errors.Docs
PLUGIN_AUTHORING.mddocuments theplugin-api:1.0.0coordinate and, from the on-device verification, the on-device AGP 8.11.0 / Kotlin 1.9.22 constraint and the rootapply falseAGP requirement (for CoGo's init-scriptLogSenderPlugin).PLUGIN_API_CHANGELOG.mdupdated.Out of scope (companion tickets)
plugin.idinstead oflibs/plugin-api.jar— ADFA-4913 (until then, a coordinate-only project is built via Run Tasks, not the quick-run plugin path).Blocks ADFA-4693. Relates to ADFA-4908, ADFA-4913.