From 0076e6d33a7a6620f168b0a59dadbba769dec3d5 Mon Sep 17 00:00:00 2001 From: Tim Dysinger Date: Sat, 29 Nov 2014 12:08:14 -0600 Subject: [PATCH 01/10] Copied the rebar2 LFE compiler code. This was code originally contributed by Tim Dysinger, so I've set him as the author in github. --- src/rebar_lfe_compiler.erl | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/rebar_lfe_compiler.erl diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl new file mode 100644 index 000000000..8488b0ff0 --- /dev/null +++ b/src/rebar_lfe_compiler.erl @@ -0,0 +1,84 @@ +%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et +%% ------------------------------------------------------------------- +%% +%% rebar: Erlang Build Tools +%% +%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com), +%% Tim Dysinger (tim@dysinger.net) +%% +%% Permission is hereby granted, free of charge, to any person obtaining a copy +%% of this software and associated documentation files (the "Software"), to deal +%% in the Software without restriction, including without limitation the rights +%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%% copies of the Software, and to permit persons to whom the Software is +%% furnished to do so, subject to the following conditions: +%% +%% The above copyright notice and this permission notice shall be included in +%% all copies or substantial portions of the Software. +%% +%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +%% THE SOFTWARE. +%% ------------------------------------------------------------------- + +-module(rebar_lfe_compiler). + +-export([compile/2]). + +%% for internal use only +-export([info/2]). + +-include("rebar.hrl"). + +%% =================================================================== +%% Public API +%% =================================================================== + +compile(Config, _AppFile) -> + FirstFiles = rebar_config:get_list(Config, lfe_first_files, []), + rebar_base_compiler:run(Config, FirstFiles, "src", ".lfe", "ebin", ".beam", + fun compile_lfe/3). + +%% =================================================================== +%% Internal functions +%% =================================================================== + +info(help, compile) -> + ?CONSOLE( + "Build Lisp Flavoured Erlang (*.lfe) sources.~n" + "~n" + "Valid rebar.config options:~n" + " erl_opts is reused.'~n", + []). + +compile_lfe(Source, _Target, Config) -> + case code:which(lfe_comp) of + non_existing -> + ?ERROR("~n" + "*** MISSING LFE COMPILER ***~n" + " You must do one of the following:~n" + " a) Install LFE globally in your erl libs~n" + " b) Add LFE as a dep for your project, eg:~n" + " {lfe, \"0.6.1\",~n" + " {git, \"git://github.com/rvirding/lfe\",~n" + " {tag, \"v0.6.1\"}}}~n" + "~n", []), + ?FAIL; + _ -> + ErlOpts = rebar_utils:erl_opts(Config), + Opts = [{i, "include"}, {outdir, "ebin"}, return] ++ ErlOpts, + case lfe_comp:file(Source, Opts) of + {ok, _Mod, Ws} -> + rebar_base_compiler:ok_tuple(Config, Source, Ws); + {error, Es, Ws} -> + rebar_base_compiler:error_tuple(Config, Source, + Es, Ws, Opts); + _ -> + ?FAIL + end + end. From 6f8b0e4b3f5dc07e7d0e1d9ff05f69fe8009b72b Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 12:25:33 -0600 Subject: [PATCH 02/10] Updated compile function signature. Also: used filename:join with "src" and "ebin" like other compilers in rebar3 are doing. --- src/rebar_lfe_compiler.erl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index 8488b0ff0..176a17823 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -39,10 +39,16 @@ %% Public API %% =================================================================== -compile(Config, _AppFile) -> +compile(Config, Dir) -> FirstFiles = rebar_config:get_list(Config, lfe_first_files, []), - rebar_base_compiler:run(Config, FirstFiles, "src", ".lfe", "ebin", ".beam", - fun compile_lfe/3). + rebar_base_compiler:run(Config, + check_files(rebar_state:get( + Config, lfe_first_files, [])), + filename:join(Dir, "src"), + ".lfe", + filename:join(Dir, "ebin"), + ".beam", + fun compile_lfe/3), %% =================================================================== %% Internal functions From 66a1c8bd3d09edf295f091ea53d795ebf657853a Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 12:43:24 -0600 Subject: [PATCH 03/10] Updated notice with new versions of LFE releases. --- src/rebar_lfe_compiler.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_lfe_compiler.erl index 176a17823..5b22e25f2 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_lfe_compiler.erl @@ -70,9 +70,9 @@ compile_lfe(Source, _Target, Config) -> " You must do one of the following:~n" " a) Install LFE globally in your erl libs~n" " b) Add LFE as a dep for your project, eg:~n" - " {lfe, \"0.6.1\",~n" + " {lfe, \"0.9.0\",~n" " {git, \"git://github.com/rvirding/lfe\",~n" - " {tag, \"v0.6.1\"}}}~n" + " {tag, \"v0.9.0\"}}}~n" "~n", []), ?FAIL; _ -> From 0877192be039413d0032070f6a62cf66fed20005 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 13:04:08 -0600 Subject: [PATCH 04/10] Converted to rebar3 provider module. --- ...ompiler.erl => rebar_prv_lfe_compiler.erl} | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) rename src/{rebar_lfe_compiler.erl => rebar_prv_lfe_compiler.erl} (61%) diff --git a/src/rebar_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl similarity index 61% rename from src/rebar_lfe_compiler.erl rename to src/rebar_prv_lfe_compiler.erl index 5b22e25f2..3befd2385 100644 --- a/src/rebar_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -6,6 +6,7 @@ %% %% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com), %% Tim Dysinger (tim@dysinger.net) +%% Duncan McGreggor (duncan@lfe.io) %% %% Permission is hereby granted, free of charge, to any person obtaining a copy %% of this software and associated documentation files (the "Software"), to deal @@ -26,29 +27,52 @@ %% THE SOFTWARE. %% ------------------------------------------------------------------- --module(rebar_lfe_compiler). +-module(rebar_prv_lfe_compiler). --export([compile/2]). +-behaviour(provider). + +-export([init/1, + do/1, + format_error/1]). %% for internal use only -export([info/2]). -include("rebar.hrl"). +-define(PROVIDER, lfe). +-define(DEPS, []). + %% =================================================================== %% Public API %% =================================================================== +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {bare, false}, + {deps, ?DEPS}, + {example, "rebar lfe compile"}, + {short_desc, "Compile LFE source files."}, + {desc, ""}, + {opts, []}])), + {ok, State1}. -compile(Config, Dir) -> - FirstFiles = rebar_config:get_list(Config, lfe_first_files, []), - rebar_base_compiler:run(Config, - check_files(rebar_state:get( - Config, lfe_first_files, [])), - filename:join(Dir, "src"), - ".lfe", - filename:join(Dir, "ebin"), - ".beam", - fun compile_lfe/3), +do(Config) -> + Cwd = rebar_utils:get_cwd(), + FirstFiles = check_files(rebar_state:get(Config, lfe_first_files, [])), + Result = rebar_base_compiler:run(Config, + FirstFiles + filename:join(Cwd, "src"), + ".lfe", + filename:join(Cwd, "ebin"), + ".beam", + fun compile_lfe/3), + {Result, Config}. + +-spec format_error(any()) -> iolist(). +format_error(Reason) -> + io_lib:format("~p", [Reason]). %% =================================================================== %% Internal functions @@ -88,3 +112,16 @@ compile_lfe(Source, _Target, Config) -> ?FAIL end end. + +%% +%% Ensure all files in a list are present and abort if one is missing +%% +-spec check_files([file:filename()]) -> [file:filename()]. +check_files(FileList) -> + [check_file(F) || F <- FileList]. + +check_file(File) -> + case filelib:is_regular(File) of + false -> ?ABORT("File ~p is missing, aborting\n", [File]); + true -> File + end. From c1a84da5e8208faf7bd3988c7380e775c3a2ef88 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 13:06:29 -0600 Subject: [PATCH 05/10] Added the LFE provider to rebar.app. --- src/rebar.app.src | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rebar.app.src b/src/rebar.app.src index 0341f7912..5976a6564 100644 --- a/src/rebar.app.src +++ b/src/rebar.app.src @@ -31,6 +31,7 @@ rebar_prv_install_deps, rebar_prv_packages, rebar_prv_erlydtl_compiler, + rebar_prv_lfe_compiler, rebar_prv_compile, rebar_prv_app_discovery, rebar_prv_shell, From d8b8b87576864f960a8a2907c784c339856ccfb0 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 15:37:41 -0600 Subject: [PATCH 06/10] Updates and fixes. This has been successfully tested to compile .lfe files. However, it's showing 'help' output when it shouldn't ... --- src/rebar_prv_lfe_compiler.erl | 43 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/rebar_prv_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl index 3befd2385..4fb1b3c33 100644 --- a/src/rebar_prv_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -26,7 +26,6 @@ %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN %% THE SOFTWARE. %% ------------------------------------------------------------------- - -module(rebar_prv_lfe_compiler). -behaviour(provider). @@ -46,29 +45,33 @@ %% =================================================================== %% Public API %% =================================================================== + -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> - State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER}, - {module, ?MODULE}, - {bare, false}, - {deps, ?DEPS}, - {example, "rebar lfe compile"}, - {short_desc, "Compile LFE source files."}, - {desc, ""}, - {opts, []}])), + Provider = providers:create([ + {name, ?PROVIDER}, + {module, ?MODULE}, + {bare, false}, + {deps, ?DEPS}, + {example, "rebar lfe compile"}, + {short_desc, "Compile LFE source files."}, + {desc, info()}, + {opts, []} + ]), + State1 = rebar_state:add_provider(State, Provider), {ok, State1}. -do(Config) -> +do(State) -> Cwd = rebar_utils:get_cwd(), - FirstFiles = check_files(rebar_state:get(Config, lfe_first_files, [])), - Result = rebar_base_compiler:run(Config, - FirstFiles + FirstFiles = check_files(rebar_state:get(State, lfe_first_files, [])), + Result = rebar_base_compiler:run(State, + FirstFiles, filename:join(Cwd, "src"), ".lfe", filename:join(Cwd, "ebin"), ".beam", fun compile_lfe/3), - {Result, Config}. + {Result, State}. -spec format_error(any()) -> iolist(). format_error(Reason) -> @@ -77,16 +80,18 @@ format_error(Reason) -> %% =================================================================== %% Internal functions %% =================================================================== +info() -> + info(help, compile). info(help, compile) -> ?CONSOLE( "Build Lisp Flavoured Erlang (*.lfe) sources.~n" "~n" "Valid rebar.config options:~n" - " erl_opts is reused.'~n", + " erl_opts is reused.~n", []). -compile_lfe(Source, _Target, Config) -> +compile_lfe(Source, _Target, State) -> case code:which(lfe_comp) of non_existing -> ?ERROR("~n" @@ -100,13 +105,13 @@ compile_lfe(Source, _Target, Config) -> "~n", []), ?FAIL; _ -> - ErlOpts = rebar_utils:erl_opts(Config), + ErlOpts = rebar_utils:erl_opts(State), Opts = [{i, "include"}, {outdir, "ebin"}, return] ++ ErlOpts, case lfe_comp:file(Source, Opts) of {ok, _Mod, Ws} -> - rebar_base_compiler:ok_tuple(Config, Source, Ws); + rebar_base_compiler:ok_tuple(State, Source, Ws); {error, Es, Ws} -> - rebar_base_compiler:error_tuple(Config, Source, + rebar_base_compiler:error_tuple(State, Source, Es, Ws, Opts); _ -> ?FAIL From 5c10cc0b38c728dd5d3bd532c0d5778be4a41313 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 15:48:18 -0600 Subject: [PATCH 07/10] Fixed the issues with display help info. --- src/rebar_prv_lfe_compiler.erl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/rebar_prv_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl index 4fb1b3c33..79003c931 100644 --- a/src/rebar_prv_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -55,7 +55,7 @@ init(State) -> {deps, ?DEPS}, {example, "rebar lfe compile"}, {short_desc, "Compile LFE source files."}, - {desc, info()}, + {desc, get_info()}, {opts, []} ]), State1 = rebar_state:add_provider(State, Provider), @@ -80,16 +80,19 @@ format_error(Reason) -> %% =================================================================== %% Internal functions %% =================================================================== -info() -> - info(help, compile). +get_info() -> + get_info(help, compile). -info(help, compile) -> - ?CONSOLE( +get_info(help, compile) -> + (io_lib:format( "Build Lisp Flavoured Erlang (*.lfe) sources.~n" "~n" "Valid rebar.config options:~n" " erl_opts is reused.~n", - []). + [])). + +info(help, compile) -> + ?CONSOLE(get_info(help, compile), []). compile_lfe(Source, _Target, State) -> case code:which(lfe_comp) of From c2992c788b3286ed34475bcb88f2ac1eb56618da Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 16:07:06 -0600 Subject: [PATCH 08/10] Tweaked the provider name. --- src/rebar_prv_lfe_compiler.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rebar_prv_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl index 79003c931..0eda84b05 100644 --- a/src/rebar_prv_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -39,7 +39,7 @@ -include("rebar.hrl"). --define(PROVIDER, lfe). +-define(PROVIDER, lfecompile). -define(DEPS, []). %% =================================================================== @@ -53,7 +53,7 @@ init(State) -> {module, ?MODULE}, {bare, false}, {deps, ?DEPS}, - {example, "rebar lfe compile"}, + {example, "rebar lfecompile"}, {short_desc, "Compile LFE source files."}, {desc, get_info()}, {opts, []} From be3650584b6170b7da92dea8a12c3109da6fbb67 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 16:51:54 -0600 Subject: [PATCH 09/10] Tweaked help info and functions. --- src/rebar_prv_lfe_compiler.erl | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/rebar_prv_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl index 0eda84b05..9bd20f4ea 100644 --- a/src/rebar_prv_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -34,12 +34,10 @@ do/1, format_error/1]). -%% for internal use only --export([info/2]). - -include("rebar.hrl"). -define(PROVIDER, lfecompile). +-define(DESC, "Compile LFE source files."). -define(DEPS, []). %% =================================================================== @@ -54,8 +52,8 @@ init(State) -> {bare, false}, {deps, ?DEPS}, {example, "rebar lfecompile"}, - {short_desc, "Compile LFE source files."}, - {desc, get_info()}, + {short_desc, ?DESC}, + {desc, info(?DESC)}, {opts, []} ]), State1 = rebar_state:add_provider(State, Provider), @@ -80,19 +78,15 @@ format_error(Reason) -> %% =================================================================== %% Internal functions %% =================================================================== -get_info() -> - get_info(help, compile). - -get_info(help, compile) -> - (io_lib:format( - "Build Lisp Flavoured Erlang (*.lfe) sources.~n" - "~n" - "Valid rebar.config options:~n" - " erl_opts is reused.~n", - [])). - -info(help, compile) -> - ?CONSOLE(get_info(help, compile), []). +info(Description) -> + io_lib:format( + "~n~s~n" + "~n" + "No additional configuration options are required to compile~n" + "LFE (*.lfe) files. The rebar 'erl_opts' setting is reused by~n" + "LFE. For more information, see the rebar documentation for~n" + "'erl_opts'.", + [Description]). compile_lfe(Source, _Target, State) -> case code:which(lfe_comp) of From 4d98ff9819d0f025be8491911c5afb9ff4932af5 Mon Sep 17 00:00:00 2001 From: "Duncan M. McGreggor" Date: Sat, 29 Nov 2014 17:32:10 -0600 Subject: [PATCH 10/10] Added opts work-around until issue #30 is fixed. --- src/rebar_prv_lfe_compiler.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rebar_prv_lfe_compiler.erl b/src/rebar_prv_lfe_compiler.erl index 9bd20f4ea..2bd5d5afc 100644 --- a/src/rebar_prv_lfe_compiler.erl +++ b/src/rebar_prv_lfe_compiler.erl @@ -54,7 +54,7 @@ init(State) -> {example, "rebar lfecompile"}, {short_desc, ?DESC}, {desc, info(?DESC)}, - {opts, []} + {opts, [{undefined, undefined, undefined, undefined, ""}]} ]), State1 = rebar_state:add_provider(State, Provider), {ok, State1}.