Goal
Make android-dev a real environment component, the way #50 made rust-dev one.
android-dev is a planned module today: it declares a container name and its router markers (settings.gradle, settings.gradle.kts, gradlew, local.properties), and nothing else.
$ ./install.sh --components android-dev
install.sh: planned, so it cannot be installed yet: android-dev
Do this one last
android-dev is the hardest of the three planned environments, and it is the only one whose boundary is not already proven by an existing module:
- it needs a JDK and the Android SDK, so the container owns two toolchains rather than one;
- the SDK is large, and its licence must be accepted before a component can install it unattended;
- a physical device or an emulator needs host access that the other environments never ask for. An emulator wants
/dev/kvm, and a device over USB wants a udev rule and the host adb server. Decide what is in scope before writing anything.
Consider deliberately narrowing the first version to Gradle builds and unit tests only, with the emulator and device access declared out of scope and recorded as such in docs/android-dev.md. A narrow environment that is honest about its limits is worth more than a wide one that only works on one machine.
dotnet-dev (#52) is the better next environment, because its shape is the shape rust-dev already proved.
What to add
docs/environments.md, "Adding an environment", holds the procedure:
distrobox/android-dev.ini
manifests/android-dev-packages.txt
manifests/android-dev.env
bootstrap/android-dev.sh
config/devbox-router/environments.d/android-dev.env
components/android-dev/install.sh, and install/verify in component.json
verify/28-android-dev.sh
docs/android-dev.md, listed in docs/README.md
The boundary to keep
The same split every other environment makes: the container owns the toolchain manager, and the repository owns the toolchain. A repository already declares its Gradle version in gradle/wrapper/gradle-wrapper.properties and its SDK levels in build.gradle, so the container pins the JDK and the SDK command-line tools as a baseline and lets gradlew do the rest.
ANDROID_HOME, ANDROID_USER_HOME and GRADLE_USER_HOME stay inside the isolated container HOME. local.properties is machine-local and must never be tracked, which is worth stating in docs/not-tracked.md.
Keep the rest: the host ~/projects mount, the agent CLIs and the shared agent policy, the forwarded ssh-agent socket, and no private key or signing keystore inside the container. A signing keystore is a credential; docs/secrets.md already says where a credential lives.
Acceptance criteria
The last criterion is not optional
#50 hit exactly this. rust-dev was the stock example of "an environment the router resolves but nothing configures", in four documents and in the routing suite, and the suite failed when the premise stopped being true: H4 expected exit 5 and got 0. This issue removes the last real example, so the fix here is a construction that does not depend on a real module being planned.
Context
Follows #50 and #52. Advances the environment work that #8 defined.
Goal
Make
android-deva real environment component, the way #50 maderust-devone.android-devis a planned module today: it declares a container name and its router markers (settings.gradle,settings.gradle.kts,gradlew,local.properties), and nothing else.Do this one last
android-devis the hardest of the three planned environments, and it is the only one whose boundary is not already proven by an existing module:/dev/kvm, and a device over USB wants a udev rule and the hostadbserver. Decide what is in scope before writing anything.Consider deliberately narrowing the first version to Gradle builds and unit tests only, with the emulator and device access declared out of scope and recorded as such in
docs/android-dev.md. A narrow environment that is honest about its limits is worth more than a wide one that only works on one machine.dotnet-dev(#52) is the better next environment, because its shape is the shaperust-devalready proved.What to add
docs/environments.md, "Adding an environment", holds the procedure:distrobox/android-dev.inimanifests/android-dev-packages.txtmanifests/android-dev.envbootstrap/android-dev.shconfig/devbox-router/environments.d/android-dev.envcomponents/android-dev/install.sh, andinstall/verifyincomponent.jsonverify/28-android-dev.shdocs/android-dev.md, listed indocs/README.mdThe boundary to keep
The same split every other environment makes: the container owns the toolchain manager, and the repository owns the toolchain. A repository already declares its Gradle version in
gradle/wrapper/gradle-wrapper.propertiesand its SDK levels inbuild.gradle, so the container pins the JDK and the SDK command-line tools as a baseline and letsgradlewdo the rest.ANDROID_HOME,ANDROID_USER_HOMEandGRADLE_USER_HOMEstay inside the isolated container HOME.local.propertiesis machine-local and must never be tracked, which is worth stating indocs/not-tracked.md.Keep the rest: the host
~/projectsmount, the agent CLIs and the shared agent policy, the forwarded ssh-agent socket, and no private key or signing keystore inside the container. A signing keystore is a credential;docs/secrets.mdalready says where a credential lives.Acceptance criteria
./install.sh --components android-devcreates the container and converges the toolchain.component.jsonhas"status": "supported"and declares every file it owns.developerprofile composes it, which keeps thedanielprofile complete.devboxroutes a repository withgradlewinto the container, and./gradlew buildworks there.local.propertiesis tracked;bin/scan-secretsreports zero findings.docs/android-dev.mdstates what the environment does not do, if the first version excludes the emulator or device access../verify.sh --only 28passes, and./verify.shpasses on the host and insideweb-dev.README.md,docs/environments.mdanddocs/architecture.mdmoveandroid-devfrom planned to supported.The last criterion is not optional
#50 hit exactly this.
rust-devwas the stock example of "an environment the router resolves but nothing configures", in four documents and in the routing suite, and the suite failed when the premise stopped being true: H4 expected exit 5 and got 0. This issue removes the last real example, so the fix here is a construction that does not depend on a real module being planned.Context
Follows #50 and #52. Advances the environment work that #8 defined.