# GitHug Android Native Android adaptation of the Ruby [Githug](https://github.com/Gazler/githug) learning game, built with **Kotlin + Jetpack Compose**. The product goal is a shippable mobile implementation that preserves GitHug's CLI-first learning style while making repository state easier to inspect on a phone. ## Implementation Strategy The app is organized around GitHug parity rather than simplified command quizzes: - The level catalog follows the upstream Ruby Githug exercise order from `Githug::Level::LEVELS`, excluding the final `contribute` call to action. - Each exercise lives in its own Kotlin source file under `app/src/main/java/solutions/tretter/githugandroid/levels/`. - Each level file documents the intended repository setup, evaluation strategy, hints, command suggestions, and embedded solution scenarios. - Validators prefer repository state and Git objects over raw command text. Direct command-answer validation is reserved for upstream answer-style levels such as identifying a hash, filename, remote URL, author, or count. - Shared tests execute the embedded solution scenarios for every level and assert that the Android catalog still matches the upstream level order. - The runtime prepares an isolated sandbox per level and requires a bundled native Git binary for the device ABI. If no native Git binary is available, the app shows an unavailable-build message instead of starting a playable session. The UI supports a terminal-centered workflow with optional inspection panes: - **CLI ONLY**: hide visualization and play with terminal-style input. - **HYBRID**: command line with optional repository panels. - **VISUAL**: repository panels visible by default, still backed by the same command engine. ## Development Workflow Development tasks should be run through the project tooling script. It provisions the local toolchain, keeps paths project-relative, and runs Gradle with the project configuration expected by this repository. While implementing changes, keep `commit-summary.txt` updated as you go. This file is intentionally ignored by git and excluded from automatic commits so it can be edited manually too; the build tooling uses it as the commit message when it exists and is non-empty. ## Android project tooling This repo includes a root-level tooling script: ```bash bash ./AndroidProjectTooling.sh ``` It is designed to be idempotent and uses project-relative paths to: - install a project-local JDK into `./jdk` - install Android command-line tools into `./android-sdk` - restore `gradle/wrapper/gradle-wrapper.jar` if missing - install required Android SDK packages - write `local.properties` Available commands: | Command | Purpose | Output | | --- | --- | --- | | `bash ./AndroidProjectTooling.sh` | Provision or refresh the local Android/JDK toolchain only. | Toolchain under `./jdk` and `./android-sdk` | | `bash ./AndroidProjectTooling.sh --test` | Compile host Git, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Test reports under `app/build/reports/` | | `bash ./AndroidProjectTooling.sh --clean-test` | Compile host Git, clean Gradle outputs, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Fresh test reports under `app/build/reports/` | | `bash ./AndroidProjectTooling.sh --test-emulator` | Install emulator packages if needed, create/start the visible project test AVD, compile Android Git, and run debug instrumentation tests. | Instrumentation reports under `app/build/reports/androidTests/` | | `bash ./AndroidProjectTooling.sh --test-emulator --hide-emulator-window` | Run the same emulator instrumentation tests without showing the emulator window. | Instrumentation reports under `app/build/reports/androidTests/` | | `bash ./AndroidProjectTooling.sh --build` | Build the debug APK. | `app/build/outputs/apk/debug/githug-android-debug-v.apk` | | `bash ./AndroidProjectTooling.sh --build-release-aab` | Build the release Android App Bundle. | `app/build/outputs/bundle/release/githug-android-release-v.aab` | | `bash ./AndroidProjectTooling.sh --compile-git` | Compile Git for the development host and all Android target ABIs. | Host and Android `libgit.so` binaries | To run the JVM unit test suite after ensuring the local toolchain is ready: ```bash bash ./AndroidProjectTooling.sh --test ``` To run instrumentation tests on an Android emulator: ```bash bash ./AndroidProjectTooling.sh --test-emulator ``` The emulator window is shown by default so UI instrumentation can be followed visually. Add `--hide-emulator-window` for headless runs: ```bash bash ./AndroidProjectTooling.sh --test-emulator --hide-emulator-window ``` Test outputs and logs are written under project-local build directories: - JVM test HTML report: `app/build/reports/tests/testDebugUnitTest/index.html` - JVM test XML results: `app/build/test-results/testDebugUnitTest/` - Emulator instrumentation HTML report: `app/build/reports/androidTests/connected/debug/index.html` - Emulator instrumentation XML/results: `app/build/outputs/androidTest-results/connected/debug/` - Per-test emulator logcat files: `app/build/outputs/androidTest-results/connected/debug//logcat-*.txt` - Emulator startup log: `build/reports/android-emulator.log` Runtime diagnostics are emitted to Android logcat with the `GitHugAndroid` tag. To capture a focused trace from a device or emulator: ```bash android-sdk/platform-tools/adb logcat -c android-sdk/platform-tools/adb logcat -v time -s GitHugAndroid:D '*:S' ``` The trace includes level loading and preparation timings, native Git argv/cwd/exit/output previews, repository inspection timings, validation snapshots, and the final app decision for each submitted command. For level-resolution issues, compare the `GitRuntime`, `GitProcess`, `GitInspector`, `Validation`, and `GitHugApp` lines around the submitted command. To build installable/debuggable artifacts: ```bash bash ./AndroidProjectTooling.sh --build ``` To build the release AAB intended for Play Store style distribution work: ```bash bash ./AndroidProjectTooling.sh --build-release-aab ``` The script avoids depending on the system Java version by provisioning a project-local **JDK 17**, which is required by current Android SDK command-line tools. To avoid repeated expensive SDK verification, the script writes a small state file named: `./.android-project-tooling.state` If all required components were verified successfully, the script will skip SDK verification/reinstallation for the next **24 hours** unless required directories are missing. When `--build` or `--build-release-aab` is used, the script also: - increments `versionCode` by 1 - increments the patch component of `versionName`, for example `0.1.0` to `0.1.1` - compiles the generated Android `libgit.so` binaries when they are missing or stale - bundles full Git manpage source files from Git's `Documentation/` directory into app assets - renames the generated artifact to a `githug-android-*` filename that includes the post-bump `versionCode` - uploads the renamed APK/AAB with local `./upload2DL.sh` when that script exists - attempts to create a git commit after a successful build if there are source changes The build commands currently run these Gradle tasks: - `--build`: `assembleDebug` - `--build-release-aab`: `bundleRelease` ## Git Binary Compilation Native Git compilation is integrated into the root tooling script: ```bash bash ./AndroidProjectTooling.sh --compile-git ``` Options: | Command | Purpose | Output | | --- | --- | --- | | `bash ./AndroidProjectTooling.sh --test` | Ensure the host Git binary is current, then run tests with it. | `build/host-git/libgit.so` and test reports | | `bash ./AndroidProjectTooling.sh --clean-test` | Ensure the host Git binary is current, clean Gradle outputs, then run tests with it. | `build/host-git/libgit.so` and fresh test reports | | `bash ./AndroidProjectTooling.sh --test-emulator` | Ensure Android ABI Git binaries are current, then run instrumentation tests on the visible project AVD. | Android `libgit.so` binaries and instrumentation reports | | `bash ./AndroidProjectTooling.sh --compile-git` | Ensure host Git and Android ABI Git binaries are current. | Host and Android outputs | Android ABI outputs are generated files and are ignored by git: - `app/src/main/jniLibs/arm64-v8a/libgit.so` - `app/src/main/jniLibs/armeabi-v7a/libgit.so` - `app/src/main/jniLibs/x86/libgit.so` - `app/src/main/jniLibs/x86_64/libgit.so` The `--test` tooling command automatically builds host Git only when the Git source checkout has changed, then exports `GITHUG_TEST_GIT_BINARY=build/host-git/libgit.so`. This keeps JVM tests on the same `GitRepositoryRuntime` path as the app, including the packaged-runtime helper resolution behavior. Git build outputs are stamped with a Git source fingerprint. Re-running `--test` or `--compile-git` reuses existing `libgit.so` binaries when the checked-out Git sources and target build flavor are unchanged. Git manpage assets are also refreshed from the checked-out Git source whenever Git is compiled or an app artifact is built. Git source patches can live under `patches/git/` and are applied by `AndroidProjectTooling.sh` after the Git source checkout is cloned or reused. These patches are part of the source fingerprint, so changing a patch forces the host and Android Git binaries to rebuild. The current runtime does not require a Git source patch: it resolves Git's existing exported `init_git` and `cmd_main` symbols through JNI and calls them with Git-style `argc`/`argv`. ## Runtime Architecture The command engine has one app-facing runtime: - **Native Git path**: the packaged Git binary for the device ABI is loaded by the JNI bridge and every `git ...` command invokes Git's existing `init_git(argv)` and `cmd_main(argc, argv)` path in a real per-level repository sandbox in app-private storage. The runtime exposes a `RepoState` surface to validators. In addition to files, commits, branches, tags, remotes, and config, the model tracks learning-relevant effects such as stashes, fetched remote refs, pushed branches/tags, submodules, and repository maintenance actions. Helper shell-like commands (`ls`, `pwd`, `cat`, `sh