Packages
mob_dev
0.6.13
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.37
0.3.35
0.3.34
0.3.33
0.3.28
0.3.26
0.3.23
0.3.21
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.18
0.2.17
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Development tooling for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/mob.push.ex
defmodule Mix.Tasks.Mob.Push do
use Mix.Task
@shortdoc "Compile and hot-push changed modules to running mob devices"
@moduledoc """
Compiles the project and hot-pushes updated BEAM modules to all running
Android and iOS devices — no app restart.
The apps must already be running (start them with `mix mob.connect` or
`mix mob.deploy` first). Modules are loaded into the live BEAM in place,
equivalent to calling `nl(Module)` in IEx for each changed module.
Options:
--all Push all modules, not just those changed since last compile
--cookie Erlang cookie (default: mob_secret)
Examples:
mix mob.push
mix mob.push --all
mix mob.push --cookie my_cookie
## Under the hood
`mix mob.push` is a scripted version of the IEx hot-code-push workflow:
mix compile
# For each changed module, on each connected node:
nl(MyApp.SomeScreen)
# which calls:
:rpc.call(node, :code, :load_binary, [MyApp.SomeScreen, path, beam_binary])
The `nl/1` built-in in IEx does the same thing for a single module. `mix mob.push`
does it for all changed modules across all connected nodes in one shot.
"""
@impl Mix.Task
def run(args) do
{opts, _, _} =
OptionParser.parse(args,
switches: [all: :boolean, cookie: :string],
aliases: [c: :cookie]
)
push_all = Keyword.get(opts, :all, false)
cookie = opts |> Keyword.get(:cookie, "mob_secret") |> String.to_atom()
IO.puts("")
snapshot = MobDev.HotPush.snapshot_beams()
Mix.Task.run("compile")
IO.puts("\n#{IO.ANSI.cyan()}Connecting to devices...#{IO.ANSI.reset()}")
nodes = MobDev.HotPush.connect(cookie: cookie)
if nodes == [] do
IO.puts("#{IO.ANSI.yellow()}No running nodes found.#{IO.ANSI.reset()}")
IO.puts("Start apps first: mix mob.connect")
else
IO.puts(" Connected: #{Enum.map_join(nodes, ", ", &to_string/1)}")
IO.puts("#{IO.ANSI.cyan()}Pushing modules...#{IO.ANSI.reset()}")
{pushed, failed} =
if push_all,
do: MobDev.HotPush.push_all(nodes),
else: MobDev.HotPush.push_changed(nodes, snapshot)
if pushed == 0 and failed == [] do
IO.puts(" #{IO.ANSI.yellow()}Nothing changed.#{IO.ANSI.reset()}")
else
if pushed > 0 do
IO.puts(" #{IO.ANSI.green()}✓ #{pushed} module(s) pushed#{IO.ANSI.reset()}")
end
Enum.each(failed, fn {mod, reason} ->
IO.puts(" #{IO.ANSI.red()}✗ #{mod}: #{inspect(reason)}#{IO.ANSI.reset()}")
end)
end
end
end
end