diff --git a/lib/elixir/lib/code.ex b/lib/elixir/lib/code.ex index 6ae72648b7..09b604489a 100644 --- a/lib/elixir/lib/code.ex +++ b/lib/elixir/lib/code.ex @@ -284,6 +284,14 @@ defmodule Code do :elixir_compiler.quoted [quoted], file end + @doc """ + Loads the compile status from the code server. Returns :ok if all is + well. Returns :error if an error has ben generated. + """ + def compilation_status do + :elixir_code_server.call :compilation_status + end + @doc """ Ensures the given module is loaded. If the module is already loaded, it works as no-op. If the module was not loaded yet, diff --git a/lib/elixir/lib/kernel/cli.ex b/lib/elixir/lib/kernel/cli.ex index aaeb9fcf54..601c498fa8 100644 --- a/lib/elixir/lib/kernel/cli.ex +++ b/lib/elixir/lib/kernel/cli.ex @@ -328,8 +328,13 @@ defmodule Kernel.CLI do if files != [] do Code.compiler_options(config.compiler_options) Kernel.ParallelCompiler.files_to_path(files, config.output, - fn file -> IO.puts "Compiled #{file}" end) - :ok + fn file -> + if Code.compilation_status == :ok do IO.puts "Compiled #{file}" end + end) + case Code.compilation_status do + :ok -> :ok + :error -> { :error, "--compile generated an error" } + end else { :error, "--compile : No files matched patterns #{Enum.join(patterns, ",")}" } end diff --git a/lib/elixir/src/elixir_code_server.erl b/lib/elixir/src/elixir_code_server.erl index 4e64f9eef0..70a8f61019 100644 --- a/lib/elixir/src/elixir_code_server.erl +++ b/lib/elixir/src/elixir_code_server.erl @@ -5,11 +5,12 @@ -behavior(gen_server). -record(elixir_code_server, { argv=[], + compilation_status=ok, loaded=[], at_exit=[], pool=[], counter=0, - compiler_options=[{docs,true},{debug_info,true}], + compiler_options=[{docs,true},{debug_info,true},{warnings_as_errors,false}], waiting=[] }). @@ -58,6 +59,9 @@ handle_call(argv, _From, Config) -> handle_call(compiler_options, _From, Config) -> { reply, Config#elixir_code_server.compiler_options, Config }; +handle_call(compilation_status, _From, Config) -> + { reply, Config#elixir_code_server.compilation_status, Config }; + handle_call(retrieve_module_name, _From, Config) -> case Config#elixir_code_server.pool of [H|T] -> @@ -80,6 +84,9 @@ handle_cast({ compiler_options, Options }, Config) -> Final = orddict:merge(fun(_,_,V) -> V end, Config#elixir_code_server.compiler_options, Options), { noreply, Config#elixir_code_server{compiler_options=Final} }; +handle_cast({ compilation_status, Value }, Config) -> + { noreply, Config#elixir_code_server{compilation_status=Value} }; + handle_cast({ loaded, Path }, Config) -> Current = Config#elixir_code_server.loaded, case orddict:find(Path, Current) of diff --git a/lib/elixir/src/elixir_compiler.erl b/lib/elixir/src/elixir_compiler.erl index 12498d886c..5a5255ef9d 100644 --- a/lib/elixir/src/elixir_compiler.erl +++ b/lib/elixir/src/elixir_compiler.erl @@ -241,7 +241,13 @@ format_error({ skip_native, Module }) -> [elixir_errors:inspect(Module)]). format_errors(_File, []) -> - exit({ nocompile, "compilation failed but no error was raised" }); + case get_opt(warnings_as_errors) of + % If we get here we are treating warnings as errors and we + % have warnngs, but no errors + true -> ok; + false -> exit({ nocompile, "compilation failed but no error was raised" }) + end; + format_errors(File, Errors) -> lists:foreach(fun ({_, Each}) -> diff --git a/lib/elixir/src/elixir_errors.erl b/lib/elixir/src/elixir_errors.erl index 8d05abb29b..e2b1061cf9 100644 --- a/lib/elixir/src/elixir_errors.erl +++ b/lib/elixir/src/elixir_errors.erl @@ -78,7 +78,9 @@ deprecation(Meta, File, Message, Args) -> %% output warning based on warnings going to stdout or stderr. output_warning(Warning) -> case elixir_compiler:get_opt(warnings_as_errors) of - true -> io:format(standard_error, Warning); + true -> + io:format(standard_error, Warning, []), + elixir_code_server:cast({ compilation_status, error }); false -> io:format(Warning) end. @@ -107,7 +109,7 @@ handle_file_warning(_, File, {Line,erl_lint,{undefined_behaviour,Module}}) -> true -> []; false -> Message = io_lib:format("behaviour ~ts undefined", [inspect(Module)]), - io:format(file_format(Line, File, Message)) + output_warning(file_format(Line, File, Message)) end; handle_file_warning(_, _File, {Line,erl_lint,{unused_var,_Var}}) when Line =< 0 -> @@ -115,16 +117,16 @@ handle_file_warning(_, _File, {Line,erl_lint,{unused_var,_Var}}) when Line =< 0 handle_file_warning(_, File, {Line,erl_lint,{unused_var,Var}}) -> Message = format_error(erl_lint, { unused_var, format_var(Var) }), - io:format(file_format(Line, File, Message)); + output_warning(file_format(Line, File, Message)); handle_file_warning(_, File, {Line,erl_lint,{shadowed_var,Var,Where}}) -> Message = format_error(erl_lint, { shadowed_var, format_var(Var), Where }), - io:format(file_format(Line, File, Message)); + output_warning(file_format(Line, File, Message)); %% Default behavior handle_file_warning(_, File, {Line,Module,Desc}) -> Message = format_error(Module, Desc), - io:format(file_format(Line, File, Message)). + output_warning(file_format(Line, File, Message)). handle_file_warning(File, Desc) -> handle_file_warning(false, File, Desc).