defmodule Mix.Tasks.Clje.Build do @moduledoc """ Compile CljElixir files to BEAM bytecode. ## Usage mix clje.build src/my_module.clje mix clje.build src/foo.clje src/bar.clje mix clje.build src/foo.clje -o _build/dev/lib/clj_elixir/ebin Like `elixirc`. Compiles `.clje` files to `.beam` files without running them. ## Options * `-o` / `--output` - output directory for .beam files (default: `_build/dev/lib//ebin`) """ use Mix.Task @shortdoc "Compile .clje files to BEAM bytecode" @impl Mix.Task def run(args) do {opts, files, _} = OptionParser.parse(args, switches: [output: :string], aliases: [o: :output] ) if files == [] do Mix.shell().error("Usage: mix clje.build [...] [-o output_dir]") System.halt(1) end Mix.Task.run("compile") Mix.Task.run("app.start") output_dir = opts[:output] || Mix.Project.compile_path() results = Enum.map(files, fn file -> Mix.shell().info("Compiling #{file}") case CljElixir.Compiler.compile_file_to_beam(file, output_dir: output_dir) do {:ok, modules} -> Enum.each(modules, fn {mod, _binary} -> Mix.shell().info(" -> #{mod}") end) :ok {:error, diagnostics} -> Enum.each(diagnostics, fn diag -> loc = case {Map.get(diag, :file), Map.get(diag, :line, 0)} do {nil, _} -> "" {_f, 0} -> "#{diag.file}: " {_f, l} -> "#{diag.file}:#{l}: " end Mix.shell().error("#{loc}#{diag.severity}: #{diag.message}") end) :error end end) if Enum.any?(results, &(&1 == :error)) do System.halt(1) end end end