Skip to content

Support iOS-only development on a Mac (don't crash when adb is absent)#29

Merged
GenericJam merged 1 commit into
masterfrom
fix/ios-only-no-adb
Jun 29, 2026
Merged

Support iOS-only development on a Mac (don't crash when adb is absent)#29
GenericJam merged 1 commit into
masterfrom
fix/ios-only-no-adb

Conversation

@GenericJam

Copy link
Copy Markdown
Owner

Problem

On a Mac set up only for iOS (no Android platform-tools), mix mob.connect crashes:

** (ErlangError) Erlang error: :enoent
    (elixir) System.cmd("adb", ["forward", "--list"], ...)

The dist-port collision check (Tunnel.ports_in_use/1forward_host_ports/0) shells out to adb forward --list. System.cmd("adb", ...) raises :enoent for a missing binary rather than returning a non-zero exit, and because it runs inside a linked Task.async, the crash propagates an exit that kills the whole connect. The existing {:error, _} -> MapSet.new() fallback never gets a chance to run.

iOS-only on a Mac is fully supported (the simulator shares the Mac's network stack — no tunnels needed); adb should simply never be required.

Fix

1. Robustness (the actual bug). Tunnel.run_adb/1 now resolves adb via System.find_executable/1 first — the same guard Discovery.Android.list_devices/0 already uses — and returns {:error, "adb not found on PATH"} when it's absent. Every caller already handles {:error, _}, so the port scan and forward cleanup degrade to "no adb forwards" instead of crashing. iOS-only Macs now work with no adb installed at all.

2. Explicit iOS-only mode (requested ergonomic). Even when adb is present, you can scope a session:

  • mix mob.connect --ios-only / --android-only
  • A project-wide default in mob.exs so a Mac-only iOS dev sets it once:
    config :mob_dev, platforms: [:ios]
    Skipping the Android scan also avoids sweeping in a phone plugged in for some other project. The flag overrides the config default; combining both flags is a clear error.

Tests (pure kernels + regression)

  • MobDev.Config.parse_platforms/1 — nil/valid/filtered/invalid/non-list matrix
  • Mix.Tasks.Mob.Connect.resolve_platforms/2 — flag precedence + both-flags error
  • MobDev.TunnelAdbMissingTest — with adb off PATH, ports_in_use/1 returns a MapSet instead of crashing (locks the regression)

31 targeted tests pass. Pre-existing unrelated failures (HotPush/enable/adopt/tflite/ndk — environmental) were confirmed failing on the base before this change too.

🤖 Generated with Claude Code

`mix mob.connect` (and any tunnel path) crashed with `:enoent` for a
Mac set up only for iOS: the dist-port collision check shelled out to
`adb forward --list`, and `System.cmd("adb", ...)` *raises* for a missing
binary rather than returning a non-zero exit. The raise happened inside a
linked `Task.async`, so the exit propagated and killed the whole connect.

Two parts:

1. Bug fix — `MobDev.Tunnel.run_adb/1` resolves `adb` via
   `System.find_executable/1` first (mirroring `Discovery.Android.list_devices/0`)
   and returns `{:error, "adb not found on PATH"}` when absent. Every caller
   already handles `{:error, _}`, so the port scan / cleanup degrade to "no
   adb forwards" instead of crashing. iOS-only Macs now work with no adb at all.

2. Explicit iOS-only mode — `mix mob.connect --ios-only` / `--android-only`
   restrict discovery to one platform, and a `mob.exs` default
   (`config :mob_dev, platforms: [:ios]`) makes it project-wide so a Mac-only
   iOS dev sets it once. Skipping the Android scan also avoids sweeping in a
   phone plugged in for some other project.

New pure kernels with tests: `MobDev.Config.parse_platforms/1`,
`Mix.Tasks.Mob.Connect.resolve_platforms/2`, plus a regression test that
`Tunnel.ports_in_use/1` degrades to a MapSet when adb is off PATH.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@GenericJam GenericJam merged commit 2dfbd95 into master Jun 29, 2026
3 checks passed
GenericJam added a commit that referenced this pull request Jun 29, 2026
…s absent)

mix mob.connect no longer crashes with :enoent when adb isn't installed
(Tunnel.run_adb guards on System.find_executable). Adds --ios-only /
--android-only and a `config :mob_dev, platforms: [:ios]` default. (#29)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@GenericJam GenericJam deleted the fix/ios-only-no-adb branch June 29, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant