Current section
Files
Jump to
Current section
Files
lib/heimdallr.ex
defmodule Heimdallr do
@moduledoc """
Documentation for `Heimdallr`.
"""
alias Mix.Tasks.Compile.Elixir, as: ElixirCompiler
@compile_opts ~W(--docs --ignore-module-conflict)
def reload(files) do
mix_changed? = "./mix.exs" in files
deps_changed? = "./mix.lock" in files
code = Enum.filter(files, &String.starts_with?(&1, "./lib/"))
test = Enum.filter(files, &String.starts_with?(&1, "./test/"))
IO.puts(
"#{Enum.count(files)} changes and mix #{inspect(mix_changed?)} and deps #{inspect(deps_changed?)}"
)
if mix_changed?, do: reload_mix()
case ElixirCompiler.run(@compile_opts) do
{:noop, _} -> :ok
{:ok, diagnostics} -> process_code_reload(code, diagnostics)
{:error, _} -> :ok
end
# After re-index, see what depends
process_test_change(test ++ Enum.flat_map(code, &Heimdallr.Indexer.tests/1))
end
alias Mix.{Project, ProjectStack}
alias Mix.Tasks.Deps.{Compile, Get}
defp reload_mix do
IO.puts("mix.exs recompiling project config.")
pre_deps = current_deps()
ProjectStack.pop()
try do
Code.compile_file("./mix.exs")
rescue
_ -> :ok
end
unless pre_deps == current_deps() do
lock = File.read!("./mix.lock")
IO.puts("Dependencies have changed, fetching dependencies.")
Get.run([])
unless File.read!("./mix.lock") == lock do
IO.puts("Dependencies have been update/pulled, recompiling.")
Compile.run([])
# Add support for unloading
end
end
end
defp current_deps, do: Project.config()[:deps]
defp process_code_reload(files, _diagnostics) do
if files != [] and Application.get_env(:heimdallr, :run_checks, true) do
Credo.CLI.main(["--mute-exit-status", "--strict", "list" | files])
end
Enum.each(files, &Heimdallr.Indexer.i/1)
:heimdallr
|> Application.get_env(:after_compile, [])
|> Enum.each(& &1.(files))
:ok
end
defp process_test_change(tests) do
if tests != [] do
IO.puts(elem(execute("mix", ["test", "--color" | tests]), 0))
end
:ok
end
@spec execute(String.t(), [String.t()]) :: {String.t(), integer}
defp execute(command, options) do
case :os.type() do
{:unix, :darwin} ->
commands = ["-q", "/dev/null", command] ++ options
System.cmd("script", commands)
{:unix, _} ->
System.cmd(command, options, stderr_to_stdout: true)
end
end
end