Current section

Files

Jump to
venomous lib serpent_watcher.ex
Raw

lib/serpent_watcher.ex

defmodule Venomous.SerpentWatcher do
@moduledoc """
🐍🔎 📁 A snake spy watching every step...
Disabled by default. `config :venomous, :serpent_watcher, enable: true` to enable.
Starts python watchdog process, watching over every python module inside module_paths directories.
Default watcher requires watchdog module, which can be installed with `mix venomous.watchdog install`
Whenever file is edited/created/deleted watcher casts `:reload` with module name to SnakeManager.
The default reload module function imports and reloads the module from its name.
## Configuration
```elixir
config :venomous,
serpent_watcher: [
enable: true, # Disabled by default
logging: true, # Hot reload logging. Enabled by default
module: :serpent_watcher, # default
func: :watch_directories, #default
manager_pid: Venomous.SnakeManager # default
]
```
```elixir
config :venomous, :snake_manager, %{
...
reload_module: :reload, # default. reload function is hard coded to :reload
...
}
```
"""
alias Venomous.SnakeOpts
require Logger
use GenServer
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def init(args) do
{:ok, args, {:continue, :start_serpent}}
end
defp create_abs_paths(nil), do: []
defp create_abs_paths(path) when is_binary(path), do: [Path.expand(path)]
defp create_abs_paths(paths) when is_list(paths) do
Enum.map(paths, &Path.expand(&1))
end
def handle_continue(:start_serpent, state) do
python_opts = SnakeOpts.to_erlport_opts(state)
case :python.start_link(python_opts) do
{:error, reason} ->
Logger.error("Failed to start Serpent Watcher")
{:stop, reason, state}
{:ok, pypid} ->
Logger.info("Started Serpent Watcher")
watchlist = create_abs_paths(state[:module_paths])
logging = state[:logging]
:python.call(pypid, state[:module], state[:func], [
state[:manager_pid],
watchlist,
logging
])
exit(:serpent_down)
end
end
end