defmodule FileWatch do
@shortdoc FileWatch.MixProject.description()
@moduledoc """
#{@shortdoc} v#{FileWatch.MixProject.version()}
### Get config template
config template, #{FileWatch.Assets.config_file_name()}, will be generated under CWD.
configuration details are described in it.
$ fwatch --config-template
### Start watch
$ fwatch
"""
alias FileWatch.Assets
def main(args) do
assets_dir_path = File.cwd!()
case OptionParser.parse(args, strict: [config_template: :boolean]) do
{[], [], []} ->
run(assets_dir_path)
{[config_template: true], [], []} ->
Path.join(assets_dir_path, Assets.config_file_name())
|> Assets.create_config_file()
_ ->
help()
end
end
@spec run(assets_dir_path :: String.t()) :: :ok | :error
def run(assets_dir_path) do
config_file_path = Path.join(assets_dir_path, Assets.config_file_name())
case Assets.read_config(config_file_path) do
{:ok, config} ->
Application.put_all_env(config)
Application.get_all_env(:logger) |> Logger.configure()
wrapper_file_path = Path.join(assets_dir_path, Assets.wrapper_file_name())
Assets.create_wrapper_file(wrapper_file_path)
run_impl(wrapper_file_path)
:error ->
:error
end
end
@doc """
run_impl/2 is the essential function of :file_watch,
which can be called either as an escript or as a mix task.
"""
@spec run_impl(wrapper_file_path :: String.t()) :: :ok
def run_impl(wrapper_file_path) when is_binary(wrapper_file_path) do
Application.put_env(:file_watch, :main_pid, self())
start_link(config: Application.get_all_env(:file_watch), wrapper_file_path: wrapper_file_path)
if on_iex?(), do: :ok, else: receive(do: (:exit -> :ok))
end
def exit() do
Application.fetch_env!(:file_watch, :main_pid) |> send(:exit)
end
def highlight(binary) when is_binary(binary) do
binary |> String.trim_trailing() |> String.split("\n") |> highlight()
end
def highlight(lines) when is_list(lines) do
"""
\n\s\s#{Enum.join(lines, "\n\s\s")}
"""
end
defp help(), do: @moduledoc |> highlight() |> IO.puts()
defp on_iex?() do
Code.ensure_loaded?(IEx) and IEx.started?()
end
use Supervisor
def start_link(args) when is_list(args) do
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
end
@impl Supervisor
def init(args) when is_list(args) do
children = [{FileWatch.FsSubscriber, args}]
Supervisor.init(children, strategy: :one_for_one)
end
end