Connects to already-running device nodes and hot-pushes BEAM modules via RPC.
Unlike MobDev.Deployer, this does NOT restart apps — modules are loaded
into the running BEAM in place, just like nl/1 in IEx.
Requires apps to already be running (start with mix mob.connect or
mix mob.deploy first).
Summary
Functions
Sets up adb tunnels (idempotent) and connects to all running device nodes. Returns list of connected node atoms.
Pushes all compiled BEAM files from the active Mix build path to nodes.
Pushes BEAM files that changed since snapshot (from snapshot_beams/0).
Returns {pushed_count, failed_list} — pushed_count is 0 if nothing changed.
connect/1 again for a long-running watcher, plus the cached nodes it
connected to before that still answer, so a node discovery misses once is
not dropped. A cached node on a device another session has claimed since
is dropped, so the next push leaves it alone.
Returns ebin directories for runtime deps only (no dev-only tooling).
Used by Deployer so the filesystem push matches the dist push scope.
Names of the libs that ship to the device: the project's runtime deps and
their transitive applications, minus deps marked only: :dev or
runtime: false (unless re-declared in extra_applications). Decides what
gets pushed, and which deps MobDev.Plugin.NifActivation treats as device
plugins.
Takes a snapshot of current BEAM mtimes for runtime deps only.
Pass the result to push_changed/2 before and after compiling to get only
the modules that actually changed.
Functions
Sets up adb tunnels (idempotent) and connects to all running device nodes. Returns list of connected node atoms.
Devices another agent-device session has claimed are skipped
(MobDev.DeviceLeases): this pushes to every device, so none is named.
@spec push_all([node()]) :: {non_neg_integer(), list()}
Pushes all compiled BEAM files from the active Mix build path to nodes.
Only pushes BEAMs for runtime dependencies — deps marked only: :dev or
runtime: false in mix.exs (and their transitive deps) are excluded.
This prevents dev tooling (mob_dev, Bandit, Phoenix, etc.) from being pushed
to the device when using path: deps during local framework development.
Returns {pushed_count, failed_list}.
@spec push_changed([node()], %{required(String.t()) => non_neg_integer()}) :: {non_neg_integer(), list()}
Pushes BEAM files that changed since snapshot (from snapshot_beams/0).
Returns {pushed_count, failed_list} — pushed_count is 0 if nothing changed.
connect/1 again for a long-running watcher, plus the cached nodes it
connected to before that still answer, so a node discovery misses once is
not dropped. A cached node on a device another session has claimed since
is dropped, so the next push leaves it alone.
@spec runtime_beam_dirs() :: [String.t()]
Returns ebin directories for runtime deps only (no dev-only tooling).
Used by Deployer so the filesystem push matches the dist push scope.
Names of the libs that ship to the device: the project's runtime deps and
their transitive applications, minus deps marked only: :dev or
runtime: false (unless re-declared in extra_applications). Decides what
gets pushed, and which deps MobDev.Plugin.NifActivation treats as device
plugins.
@spec snapshot_beams() :: %{required(String.t()) => non_neg_integer()}
Takes a snapshot of current BEAM mtimes for runtime deps only.
Pass the result to push_changed/2 before and after compiling to get only
the modules that actually changed.