Repository navigation
feat!: remove Android from the CLI; android is a provider (cli#405 PR 3) - #441
Conversation
Delete the CLI's Android subcommand, packager, SDK probe and doctor
(src/cli/android.zig, src/cli/android/*, src/cli/android_sdk.zig). The
`android` package (labelle-android) now owns target and namespace
`android`: `labelle build|run|bundle --platform=android` run its hooks and
`labelle android <cmd>` dispatches to it like any provider namespace.
- cli.zig: drop the `android` parse branch, the projectless doctor fast
path, the helpOnlyPrinter entry and the ApkSlim spec re-exports.
- args.zig: drop `.android_cmd` and `resolveAndroidBackend` (D9: a
non-Android backend now fails instead of switching to sokol).
- pipeline: drop the sokol fallback, the `packageApk` finalisation on
`build` and the Android launch branch on `run`.
- project_config.zig: drop `AndroidConfig` and the `.android` field; the
lenient parse still accepts a legacy block.
- provider_dispatch.zig: `android` leaves `reserved`.
- New generic gate `NoRunReplacement`: `labelle run` of a provider target
with no `replace run` hook, outside the legacy `{wasm, ios}` run
branches, is refused after the install and before any build.
- An unknown first word that the cached schema-2 registry names as a
package namespace gets the no-provider-for-namespace diagnostic with a
`(registry: <pkg>)` line.
- Agnosticism guard allowlist 69 -> 54: the ten android entries plus five
files that came clean (add, app_icon, check, lockfile, plugins).
- test/provider_android_like_e2e.py: an android-shaped fixture provider
through the real CLI, no NDK; wired into CI. Hooks/targets e2e updated.
Claude-Session: https://claude.ai/code/session_01R2K5sJDL5Msn1uRTkybiDP
…cli#405) Move docs/workflows/android-release.yml to labelle-android (deleted here). Update provider-targets (a `labelle run` section, the migration notes, verification), provider-hooks limitations, provider-local-dispatch's reserved list, tester onboarding (bundle then `labelle android deploy`, settings in providers/android.json), the Android packaging RFC status, and the contract doc's provider_config package name (`android`). Claude-Session: https://claude.ai/code/session_01R2K5sJDL5Msn1uRTkybiDP
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
PR 3 of the #405 plan. The CLI no longer contains any Android code. Android is now the
androidprovider (labelle-android: #12 merged, #13 in review).labelle build|run|bundle --platform=androidrun that package's hooks.labelle android <cmd>dispatches to its namespace, like any other provider namespace.The base is
development, which already has contract 1.2.0 (#440). Do not merge until labelle-android #13 is proven on Flying Platform. The dev→main merge waits for the web provider (user decision: CLI 2.0.0, one release train).Deleted
src/cli/android.zigsrc/cli/android/{apk_slim,build,deploy,doctor,launcher_icon,package,run,studio}.zigsrc/cli/android_sdk.zigdocs/workflows/android-release.yml(it now lives in labelle-android, rewritten forbundle+labelle android deploy)Edited
src/cli.zigandroidimport, its parse branch and value-flag handling, the projectlessandroid doctorfast path, thehelpOnlyPrinter .android_cmdentry and its tests, theApkSlim*SpecandArgsResolveAndroidBackendSpecre-exports, and the usage text. An unknown first word now goes throughreportUnknownCommand(see "Namespace diagnostic" below).src/cli/args.zig,args_tests.zig.android_cmdremoved fromCommand.resolveAndroidBackendand its spec removed (D9).src/cli/pipeline.zig.android_cmdbranch removed.src/cli/pipeline/args_resolve.zigsrc/cli/pipeline/build.zigpackageApkfinalisation onlabelle buildand its import removed.src/cli/pipeline/run.zigcrossTargetLaunchSkippeddrops.android, and its test covers the new shape.src/cli/pipeline/install.zigNoRunReplacementgate, pluslegacyRunBranchandnoRunReplacementwith their decision-table tests.src/cli/project_config.zigAndroidConfigand theandroidfield deleted.Orientationdocs made neutral. A test shows that a legacy.androidblock still parses (the CLI's parse setsignore_unknown_fields).Platform.androidandAssetCompression.androidstay until assembler#378 and #407.src/cli/provider_dispatch.zig"android"removed fromreserved, with a test.src/cli/provider_github{,/registry_cache}.zigcachedRegistryNamespaceOwner: schema 2 only, cache only, with a test.help.zig,runner.zig,bundle.zig,app_icon.zig,doctor.zig,add.zig,plugins.zig,check.zig,lockfile.zig,provider_hooks.zig,assembler_proc.zig,pipeline/generate.zigsrc/agnostic_guard_test.zigallowedIndexand stale-entry tests now usecli/serve/*,cli/ios.zigandcli/emsdk_cache.zig, and assert that the removedcli/android*paths are no longer exempt.provider-targets.md: new "labelle run" section, migration notes, verification.provider-hooks.md: limitations.provider-local-dispatch.md: reserved list and namespace diagnostic.tester-onboarding.md: bundle, thenlabelle android deploy, with settings inproviders/android.json.rfc-android-packaging.md: status.provider-contract-v1.md: theprovider_configexample uses packageandroid.New generic gate:
NoRunReplacementThis sits next to
NoBundleReplacement. It is decided with the hook plans after discovery: after the install, before generate, lock or build.command == .run and target.provider != null and hook_plans.run.replace == null and !legacyRunBranch(target.legacy).legacyRunBranchis true only for{wasm, ios}. It only shrinks: a platform leaves it once its launch moves into a provider.error: NoRunReplacement, exit 1.Without this gate, a provider target with no run replacement would fall through to the host launch and run a binary built for another platform. The gate applies to foreign provider targets too, such as
probe-target. So the control step inprovider_hooks_e2e.pychanged: it used to show a replacement-less provider target reaching the host launch. Now it runs the planted sentinel directly, to show the check is real, and then asserts the run is refused before any hook runs.Namespace diagnostic (generic)
labelle <word>, where no built-in, pinned namespace or directory matches, is stillunknown command '<word>'.<word>as its namespace, the message is instead:Guard allowlist delta: 69 → 54 entries
cli/android.zig,cli/android/{apk_slim,build,deploy,doctor,launcher_icon,package,run,studio}.zig,cli/android_sdk.zig.cli/add.zig,cli/app_icon.zig,cli/check.zig,cli/lockfile.zig,cli/plugins.zig.src/astc/*is untouched (feat(astc): read upload capabilities from backend manifests #428).Tests
All run locally on macOS arm64 with Zig 0.16.0, and each exit code was checked on its own:
zig fmt --checkon every touched.zigfile: clean.zig build: 0.zig build -Dtarget=x86_64-windows: 0.zig build test: 0; 1024/1029 passed, 5 skipped, guard included.legacyRunBranch, the legacy-block parse, the unreserved namespace andcachedRegistryNamespaceOwner.zig build test-provider-dispatch: 0; 81/81.provider_dispatch_e2eprovider_github_e2eprovider_config_e2eprovider_hooks_e2eprovider_targets_e2eprovider_android_like_e2e(new)plugin_compat_e2etest/provider_android_like_e2e.pyis new and wired intoci.ymlnext to the other provider suites, on all three OSes. It uses no NDK. A fixture packageandroid(thetest/fixtures/providertool under an android-shaped manifest) declares target and namespaceandroid, the hookspackage(after build),deploy(replaces run) andbundle(replaces bundle), and aruncommand. A fake assembler stands in for the real one. The suite asserts:run,buildandbundle --platform=androideach fail with the no-provider message.labelle android runfails withunknown command, or with the namespace diagnostic when a cache exists. With a schema-2 registry cache, the(registry: android)line is present; without one, it is absent. Nothing is generated and no host launch happens.--platform android.target_dir, andzig-out/lib/libgame.soexists while it runs: it copies the file, which fails if the file is missing.run.envbuilt from--scene/--screenshot/--after.package, thendeploy.NoRunReplacementafter the install and before generate. No hook runs, andbuildstill works.labelle android run --device X --releasereaches the tool verbatim, andlabelle androidlists the namespace's commands.bundle --platform=android --build-number=7passesbuild_number = "7", andoutput_diris<target>/zig-out/bundle/android.project.labellewith a legacy.androidblock goes through the CLI unchanged.provider_targets_e2e.py:labelle android buildwith no provider is now an unknown command instead of the target no-provider error.The real provider with this CLI, without
unreserve-android.sh. I used a detached temp worktree of labelle-androidorigin/feat/provider-packager(e8bfe65), pinnedlocal:in a temp fixture project (bgfx) with a hand-writtenlabelle.lock, and removed both afterwards. Results:labelle helplists:labelle android doctorexited 0 through the provider. The CLI builtbin/labelle-androidinto.labelle/providers/android, and the tool printed its ownnote: no providers/android.json … using defaultsfollowed by the SDK/NDK/JDK report.strings zig-out/bin/labelleno longer contains the doctor's text: there are 0 matches forAll required Android tools,labelle android doctororandroid.jar.No device run was needed in this PR.
Breaking
This change is breaking and ships in CLI 2.0.0. There are no shims.
labelle android build|run|studio|deploy|doctorare gone as built-ins.labelle android …exists only when the project pins theandroidpackage.buildandrunhave no command form any more: uselabelle build|run --platform=android.studiois dropped (D1).doctor,runanddeployare provider commands that act on already-built output.labelle android doctorno longer works (D8, accepted). Run it inside a project that pins the package.labelle build --platform=androidno longer packages an APK itself. Without the provider it fails with the no-provider error. With the provider, the provider's after-build hook writeszig-out/apk/game.apk(D10), replacing.labelle/<b>_android/{game.apk,apk-staging,symbols}.labelle run --platform=androidno longer deploys by itself. A provider target without areplace runhook is refused withNoRunReplacement.project.labelle.androidis no longer read by the CLI. It still parses. Packaging keys move toproviders/android.json. The assembler's codegen keys (immersive_mode,target_sdk_version,load_assets_from_apk) stay until the assembler shrinks the block in Android: one APK packaging path — retire the assembler's package_apk and slim the Gradle path too #405 PR 4a.--emulator,--all-abis,--release/--release-small,--keystore*,--tag,--channeland--notes-fileflags oflabelle android …are gone. Output is arm64 only (D6),--optimizereplaces--release, signing moves to the provider settings, and the deploy flags belong tolabelle android deploy.labelle android …, must move to the provider (not verified here).Not in this PR
package_apk.txtretirement and the.androidshrink (PR 4a).Refs #405
https://claude.ai/code/session_01R2K5sJDL5Msn1uRTkybiDP
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.