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