Skip to content

Commit

Permalink
Put escript options under :escript in the project config
Browse files Browse the repository at this point in the history
  • Loading branch information
alco committed Jun 16, 2014
1 parent 0c8c6f0 commit 1857267
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 32 deletions.
63 changes: 40 additions & 23 deletions lib/mix/lib/mix/tasks/escriptize.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,56 @@ defmodule Mix.Tasks.Escriptize do
## Configuration
The following option must be specified in your `mix.exs`:
The following option must be specified in your `mix.exs` under `:escript`
key:
* `:escript_main_module` - the module to be invoked once the escript starts.
* `:main_module` - the module to be invoked once the escript starts.
The module must contain a function named `main/1` that will receive the
command line arguments as binaries;
The remaining options can be specified to further customize the escript:
* `:escript_name` - the name of the generated escript.
* `:name` - the name of the generated escript.
Defaults to app name;
* `:escript_path` - the path to write the escript to.
* `:path` - the path to write the escript to.
Defaults to app name;
* `:escript_app` - the app to start with the escript.
* `:app` - the app to start with the escript.
Defaults to app name. Set it to `nil` if no application should
be started.
* `:escript_embed_elixir` - if `true` embed elixir in the escript file.
* `:embed_elixir` - if `true` embed elixir in the escript file.
Defaults to `true`.
* `:escript_embed_extra_apps` - embed additional Elixir applications.
if `:escript_embed_elixir` is `true`.
* `:embed_extra_apps` - embed additional Elixir applications.
if `:embed_elixir` is `true`.
Defaults to `[]`.
* `:escript_shebang` - shebang interpreter directive used to execute the escript.
* `:shebang` - shebang interpreter directive used to execute the escript.
Defaults to "#! /usr/bin/env escript\n".
* `:escript_comment` - comment line to follow shebang directive in the escript.
* `:comment` - comment line to follow shebang directive in the escript.
Defaults to "%%\n"
* `:escript_emu_args` - emulator arguments to embed in the escript file.
* `:emu_args` - emulator arguments to embed in the escript file.
Defaults to "%%!\n".
## Example
defmodule MyApp.Mixfile do
def project do
[ app: :myapp,
version: "0.0.1",
escript: escript ]
end
def escript do
[ main_module: MyApp.CLI,
embed_extra_apps: [:mix] ]
end
end
"""
def run(args) do
{opts, _, _} = OptionParser.parse(args, switches: [force: :boolean, no_compile: :boolean])
Expand All @@ -65,28 +81,29 @@ defmodule Mix.Tasks.Escriptize do
end

defp escriptize(project, force) do
script_name = project[:escript_name] || project[:app]
filename = project[:escript_path] || Atom.to_string(script_name)
main = project[:escript_main_module]
embed = Keyword.get(project, :escript_embed_elixir, true)
app = Keyword.get(project, :escript_app, project[:app])
escript_opts = project[:escript]
script_name = escript_opts[:name] || project[:app]
filename = escript_opts[:path] || Atom.to_string(script_name)
main = escript_opts[:main_module]
embed = Keyword.get(escript_opts, :embed_elixir, true)
app = Keyword.get(escript_opts, :app, project[:app])
files = project_files()

cond do
!script_name ->
Mix.raise "Could not generate escript, no name given, " <>
"set :escript_name or :app in the project settings"
"set :name escript option or :app in the project settings"

!main or !Code.ensure_loaded?(main)->
Mix.raise "Could not generate escript, please set :escript_main_module " <>
"in your project configuration to a module that implements main/1"
Mix.raise "Could not generate escript, please set :main_module " <>
"in your project configuration (under `:escript` option) to a module that implements main/1"

force || Mix.Utils.stale?(files, [filename]) ->
tuples = gen_main(script_name, main, app) ++ to_tuples(files)
tuples = tuples ++ deps_tuples()

if embed do
extra_apps = project[:escript_embed_extra_apps] || []
extra_apps = escript_opts[:embed_extra_apps] || []
tuples = Enum.reduce [:elixir|extra_apps], tuples, fn(app, acc) ->
app_tuples(app) ++ acc
end
Expand All @@ -98,9 +115,9 @@ defmodule Mix.Tasks.Escriptize do

case :zip.create 'mem', tuples, [:memory] do
{:ok, {'mem', zip}} ->
shebang = project[:escript_shebang] || "#! /usr/bin/env escript\n"
comment = project[:escript_comment] || "%%\n"
emu_args = project[:escript_emu_args] || "%%!\n"
shebang = escript_opts[:shebang] || "#! /usr/bin/env escript\n"
comment = escript_opts[:comment] || "%%\n"
emu_args = escript_opts[:emu_args] || "%%!\n"

script = IO.iodata_to_binary([shebang, comment, emu_args, zip])

Expand Down
26 changes: 17 additions & 9 deletions lib/mix/test/mix/tasks/escriptize_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,37 @@ defmodule Mix.Tasks.EscriptizeTest do
def project do
[ app: :escripttest,
version: "0.0.1",
escript_main_module: Escripttest,
escript_embed_elixir: true ]
escript: [
main_module: Escripttest,
embed_elixir: true
]
]
end
end

defmodule EscriptWithPath do
def project do
[ app: :escripttestwithpath,
version: "0.0.1",
escript_app: nil,
escript_embed_elixir: true,
escript_main_module: Escripttest,
escript_name: :escripttestwithpath,
escript_path: Path.join("ebin", "escripttestwithpath") ]
escript: [
app: nil,
embed_elixir: true,
main_module: Escripttest,
name: :escripttestwithpath,
path: Path.join("ebin", "escripttestwithpath")
]
]
end
end

defmodule EscriptWithDeps do
def project do
[ app: :escripttestwithdeps,
version: "0.0.1",
escript_main_module: Escripttest,
escript_path: Path.join("ebin", "escripttestwithdeps"),
escript: [
main_module: Escripttest,
path: Path.join("ebin", "escripttestwithdeps"),
],
deps: [{:ok, path: fixture_path("deps_status/deps/ok")}] ]
end
end
Expand Down

0 comments on commit 1857267

Please sign in to comment.