#!/usr/bin/env elixir defmodule :mix_compile_helper do def run() do project_root = get_project_root() if project_root do {stdout, exit_status} = System.cmd "mix", ["compile", "--ignore-module-conflict"], cd: project_root, stderr_to_stdout: true stdout |> String.split("\n") |> Enum.map(&(make_paths_absolute(&1, project_root))) |> Enum.join("\n") |> IO.puts exit({:shutdown, exit_status}) else usage(:root_not_found) end end def usage(:general) do file = __ENV__.file |> Path.split |> List.last IO.puts "Usage:" IO.puts "Make sure executable is in the path. Run inside mix project" IO.puts " #{file}" end def usage(:root_not_found) do IO.puts "mix.exs not detected in the directory structure" usage(:general) end defp make_paths_absolute(line, root) do line |> make_error_paths_absolute(root) |> make_warning_paths_absolute(root) end defp make_error_paths_absolute(line, root) do replace_at_position_if_pattern(line, "CompileError", 2, root) end defp make_warning_paths_absolute(line, root) do replace_at_position_if_pattern(line, "warning:", 0, root) end defp replace_at_position_if_pattern(line, pattern, position, root) do if String.contains?(line, pattern) do line |> String.split(" ") |> List.update_at(position, &(Path.absname(&1, root))) |> Enum.join(" ") else line end end def get_project_root do System.cwd |> Path.split |> Enum.reverse |> get_project_root end def get_project_root([]), do: nil def get_project_root([_|rest] = reversed_path) do current_path = reversed_path |> Enum.reverse |> Path.join() mix_file = Path.join(current_path, "mix.exs") if File.exists?(mix_file), do: current_path, else: get_project_root(rest) end end :mix_compile_helper.run