Current section

Files

Jump to
elixir_script lib mix tasks compile.elixir_script.ex
Raw

lib/mix/tasks/compile.elixir_script.ex

defmodule Mix.Tasks.Compile.ElixirScript do
use Mix.Task.Compiler
alias ElixirScript.Manifest
alias ElixirScript.Compiler
@recursive true
@manifest ".compile.elixir_script"
@manifest_vsn 1
@moduledoc """
Mix compiler to allow mix to compile Elixirscript source files into JavaScript
Looks for an `elixir_script` or `elixirscript` key in your mix project config
def project do
[
app: :my_app,
version: "0.1.0",
elixir: "~> 1.0",
deps: deps,
elixir_script: [ input: Example, output: "dest/js"],
compilers: Mix.compilers ++ [:elixir_script]
]
end
Available options are:
* `input`: The module or modules that are the entry to your application (required)
* `output`: The path of the generated JavaScript file. (defaults to `priv/elixir_script/build`)
If path ends in `.js` then that will be the name of the file. If a directory is given,
file will be named `elixirscript.build.js`
* `root`: Optional root for imports of FFI JavaScript modules.
Defaults to `.`. If using output directly in a browser, you may want to make it something like `/js` or some uri.
The mix compiler will also compile any dependencies that have the elixirscript compiler in its mix compilers as well
"""
@spec run([binary()]) ::
:ok | :noop | {:ok | :noop | :error, [Mix.Task.Compiler.Diagnostic.t()]}
def run(_) do
{input, opts} = get_compiler_params()
diagnostics =
try do
result = Compiler.compile(input, opts)
Manifest.write_manifest(manifest(), result)
result
|> Enum.map(fn {_module, info} ->
Map.get(info, :diagnostics, [])
end)
|> List.flatten()
|> Enum.map(fn x ->
%Mix.Task.Compiler.Diagnostic{
compiler_name: "elixir_script",
file: x.file,
message: x.message,
position: x.position,
severity: x.severity
}
end)
rescue
x in [ElixirScript.CompileError] ->
[
%Mix.Task.Compiler.Diagnostic{
compiler_name: "elixir_script",
message: x.message,
severity: x.severity,
position: nil,
file: nil
}
]
end
case diagnostics do
[] -> :ok
x -> x
end
end
def clean do
manifest()
|> Manifest.read_manifest()
|> Enum.each(fn {_module, info} ->
File.rm(info.js_path)
end)
:ok
end
def manifests, do: [manifest()]
defp manifest, do: Path.join(Mix.Project.manifest_path(), @manifest)
@doc false
def get_compiler_params() do
elixirscript_config = get_elixirscript_config()
input = Keyword.fetch!(elixirscript_config, :input)
opts = [
output: Keyword.get(elixirscript_config, :output)
]
{input, opts}
end
defp get_elixirscript_config() do
config = Mix.Project.config()
exjs_config =
cond do
Keyword.has_key?(config, :elixir_script) ->
Keyword.get(config, :elixir_script, [])
Keyword.has_key?(config, :elixirscript) ->
Keyword.get(config, :elixirscript, [])
true ->
defaults()
end
Keyword.merge(defaults(), exjs_config)
end
defp defaults() do
[
output: "priv/elixir_script/build"
]
end
end