-
Notifications
You must be signed in to change notification settings - Fork 414
/
watcher.ex
64 lines (48 loc) · 1.66 KB
/
watcher.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
defmodule Credo.Watcher do
alias Credo.CLI.Output.UI
@default_watch_path "."
def run(argv) do
spawn(fn ->
path = get_path(argv)
UI.puts([
:bright,
:magenta,
"watch: ",
:reset,
:faint,
"Now watching for changes in '#{path}' ...\n"
])
start_watcher_process(path)
watch_loop(argv, nil)
end)
end
defp start_watcher_process(path) do
{:ok, pid} = FileSystem.start_link(dirs: [path])
FileSystem.subscribe(pid)
end
defp watch_loop(argv, exec_from_last_run) do
receive do
{:file_event, _worker_pid, {file_path, events}} ->
elixir_file? = file_path =~ ~r/\.exs?$/
in_ignored_directory? = file_path =~ ~r/\/deps\/$/
relative_path = Path.relative_to_cwd(file_path)
exec =
if Enum.member?(events, :closed) && elixir_file? && !in_ignored_directory? do
UI.puts([:bright, :magenta, "watch: ", :reset, :faint, relative_path, "\n"])
file_that_changed = Path.relative_to_cwd(relative_path)
Credo.run(exec_from_last_run || argv, [file_that_changed])
else
# data = inspect({System.os_time(:milliseconds), events, relative_path})
# UI.puts([:bright, :magenta, "changes: ", :reset, :faint, data])
exec_from_last_run
end
watch_loop(argv, exec)
end
end
defp get_path([]), do: @default_watch_path
defp get_path(argv) do
{_options, argv_rest, _errors} = OptionParser.parse(argv, strict: [watch: :boolean])
path = Enum.find(argv_rest, fn path -> File.exists?(path) or path =~ ~r/[\?\*]/ end)
path || @default_watch_path
end
end