MobDev.Deployer (mob_dev v0.5.11)

Copy Markdown View Source

Pushes compiled BEAM files from _build/dev/lib/*/ebin/ to connected devices.

Does NOT rebuild APKs or recompile native code — that's deploy.sh (first-time setup). Use this for day-to-day code iteration: edit Elixir → mix mob.deploy → code running.

Transport selection

Erlang dist (preferred): when a device node is already reachable via Erlang distribution, BEAMs are hot-loaded via RPC. No restart needed — modules are loaded in place exactly like nl/1 in IEx.

adb push / cp (fallback): when no dist connection exists (first deploy, app not running), falls back to the traditional push-then-restart path.

Platform behaviour

Android: pushes via adb push (requires adb root, i.e. emulator or debug build), or falls back to adb push/data/local/tmp/run-as tar xf for real devices.

iOS simulator: copies files locally into /tmp/otp-ios-sim/beamhello/ (no network hop — the simulator shares the Mac filesystem).

Summary

Functions

True when the adb shell pm list packages <pkg> output indicates <pkg> is installed on the device.

Bucket a per-device results list into {deployed, failed, skipped}.

Discovers devices, pushes BEAMs, and optionally restarts apps. Returns {deployed, failed, skipped} lists of %Device{}. skipped is the deploy-isn't-applicable case — e.g. the app isn't installed on a device because only the other platform was built. Distinct from failed (real error during push).

Functions

android_package_installed?(pm_output, package_name)

@spec android_package_installed?(String.t(), String.t()) :: boolean()

True when the adb shell pm list packages <pkg> output indicates <pkg> is installed on the device.

The check is a substring match for package:<pkg> because adb's output is one package:<name> line per matching package — empty output means "no match" (not "package called empty").

Public so the rule can be regression-tested without an emulator.

categorize_results(results)

@spec categorize_results([{:ok | :skipped | :error, MobDev.Device.t()}]) ::
  {[MobDev.Device.t()], [MobDev.Device.t()], [MobDev.Device.t()]}

Bucket a per-device results list into {deployed, failed, skipped}.

Three outcomes:

  • :ok — push succeeded → deployed
  • :skipped — device wasn't a target (e.g. app not installed, typical when only one platform was built) → skipped
  • :error — push attempted and failed for a real reason → failed

Public so the categorization invariant (skipped never crosses into failed; an unknown outcome isn't silently dropped) can be tested independent of the hardware-dependent push pipeline.

deploy_all(opts \\ [])

@spec deploy_all(keyword()) ::
  {[MobDev.Device.t()], [MobDev.Device.t()], [MobDev.Device.t()]}

Discovers devices, pushes BEAMs, and optionally restarts apps. Returns {deployed, failed, skipped} lists of %Device{}. skipped is the deploy-isn't-applicable case — e.g. the app isn't installed on a device because only the other platform was built. Distinct from failed (real error during push).