-
Notifications
You must be signed in to change notification settings - Fork 57
/
code_reloader.ex
79 lines (62 loc) · 1.86 KB
/
code_reloader.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
defmodule Kitto.CodeReloader do
@moduledoc """
Handles reloading of code in development
"""
use GenServer
alias Kitto.Runner
@doc """
Starts the code reloader server
"""
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: opts[:name] || __MODULE__)
end
@doc false
def init(opts) do
if reload_code? do
:fs.start_link(:default_fs)
:fs.subscribe(:default_fs)
end
{:ok, %{opts: opts}}
end
@doc """
Returns true when the code reloader is set to start
See: https://github.com/kittoframework/kitto/wiki/Code-Reloading
"""
def reload_code? do
Application.get_env(:kitto, :reload_code?, true) && Mix.env == :dev
end
### Callbacks
# Linux inotify
def handle_info({_pid, {:fs, :file_event}, {path, event}}, state)
when event in [[:modified, :closed], [:created]],
do: reload(path, state)
def handle_info({_pid, {:fs, :file_event}, {path, [:deleted]}}, state),
do: stop(path, state)
# Mac fsevent
def handle_info({_pid, {:fs, :file_event}, {path, [_, :modified]}}, state) do
reload(path, state)
end
def handle_info(_other, state) do
{:noreply, state}
end
defp stop(path, state) do
with file <- path |> to_string do
if job?(file), do: Runner.stop_job(state.opts[:server], file)
end
{:noreply, state}
end
defp reload(path, state) do
with file <- path |> to_string do
cond do
file |> job? -> Runner.reload_job(state.opts[:server], file)
file |> lib? -> Mix.Tasks.Compile.Elixir.run ["--ignore-module-conflict"]
true -> :noop # File not watched.
end
end
{:noreply, state}
end
defp jobs_rexp, do: ~r/#{Kitto.Runner.jobs_dir}.+.*exs?$/
defp lib_rexp, do: ~r/#{Kitto.root}\/lib.+.*ex$/
defp lib?(path), do: String.match?(path, lib_rexp)
defp job?(path), do: path |> String.match?(jobs_rexp)
end