|
@@ -0,0 +1,252 @@
|
|
|
+-module(active_compile_files).
|
|
|
+
|
|
|
+-export([do_compile/4, compile_one_erl/3, compile_all_dtl/2, compile_one_dtl/4]).
|
|
|
+
|
|
|
+
|
|
|
+%do_compile(Rest, Path, Emakefile_Paths, Emakefile_Settings) ->
|
|
|
+do_compile([File], Path, Emakefile_Paths, Emakefile_Settings) ->
|
|
|
+ case lists:reverse(File) of
|
|
|
+ "lre." ++ _ ->
|
|
|
+ % .erl
|
|
|
+
|
|
|
+ % get path like in Emakefile and compare
|
|
|
+ RP = filename:absname(""),
|
|
|
+ % erlang:tl(lists:flatten(string:replace("/home/user/my_app/deps/active/src/active.erl", "/home/user/my_app", ""))) =
|
|
|
+ % "deps/active/src/active.erl"
|
|
|
+ % lists:flatten(string:replace("deps/active/src/active.erl", "active.erl", "")) =
|
|
|
+ % "deps/active/src/"
|
|
|
+ Path1 = erlang:tl(lists:flatten(string:replace(Path, RP, ""))),
|
|
|
+ Path2 = lists:flatten(string:replace(Path1, File, "")),
|
|
|
+
|
|
|
+ Is_In = is_in_emakefile_paths(Emakefile_Paths, Path1, lists:reverse(Path2)),
|
|
|
+
|
|
|
+ case Is_In of
|
|
|
+ true -> compile_one_erl(File, Path2, Emakefile_Settings);
|
|
|
+ _ -> skip
|
|
|
+ end;
|
|
|
+
|
|
|
+ "ltd." ++ _ ->
|
|
|
+ % .dtl
|
|
|
+
|
|
|
+ RP = filename:absname(""),
|
|
|
+ File_Path = erlang:tl(lists:flatten(string:replace(Path, RP, ""))),
|
|
|
+ Path2 = lists:flatten(string:replace(File_Path, File, "")),
|
|
|
+ Ebin_Dir = get_emakefile_param(Emakefile_Settings, outdir),
|
|
|
+
|
|
|
+ compile_one_dtl(File_Path, Path2, Ebin_Dir, ".dtl");
|
|
|
+
|
|
|
+ "lmth." ++ _ ->
|
|
|
+ % .html = .dtl
|
|
|
+
|
|
|
+ RP = filename:absname(""),
|
|
|
+ File_Path = erlang:tl(lists:flatten(string:replace(Path, RP, ""))),
|
|
|
+ Path2 = lists:flatten(string:replace(File_Path, File, "")),
|
|
|
+ Ebin_Dir = get_emakefile_param(Emakefile_Settings, outdir),
|
|
|
+
|
|
|
+ compile_one_dtl(File_Path, Path2, Ebin_Dir, ".html");
|
|
|
+
|
|
|
+ "lrx." ++ _ ->
|
|
|
+ % .xrl
|
|
|
+
|
|
|
+ RP = filename:absname(""),
|
|
|
+ File_Path = erlang:tl(lists:flatten(string:replace(Path, RP, ""))),
|
|
|
+
|
|
|
+ io:format("~nCompiling ~p~n", [File_Path]),
|
|
|
+ leex:file(File_Path),
|
|
|
+ ok;
|
|
|
+
|
|
|
+ "lry." ++ _ ->
|
|
|
+ % .yrl
|
|
|
+
|
|
|
+ RP = filename:absname(""),
|
|
|
+ File_Path = erlang:tl(lists:flatten(string:replace(Path, RP, ""))),
|
|
|
+
|
|
|
+ io:format("~nCompiling ~p~n", [File_Path]),
|
|
|
+ yecc:file(File_Path),
|
|
|
+ ok;
|
|
|
+
|
|
|
+ _ -> skip
|
|
|
+ end.
|
|
|
+
|
|
|
+is_in_emakefile_paths([], _, _) -> false;
|
|
|
+%is_in_emakefile_paths(Emakefile_Paths, Path1, Reversed_Path2) ->
|
|
|
+is_in_emakefile_paths([H|T], Path1, Reversed_Path2) ->
|
|
|
+ V = lists:reverse(H) =:= ("*" ++ Reversed_Path2),
|
|
|
+ case V of
|
|
|
+ true -> true;
|
|
|
+ _ ->
|
|
|
+ V2 = Path1 =:= H,
|
|
|
+ case V2 of
|
|
|
+ true -> true;
|
|
|
+ _ -> is_in_emakefile_paths(T, Path1, Reversed_Path2)
|
|
|
+ end
|
|
|
+ end.
|
|
|
+
|
|
|
+
|
|
|
+compile_one_erl(File, Path2, Emakefile_Settings) ->
|
|
|
+ Inc_Dir = get_emakefile_param(Emakefile_Settings, i),
|
|
|
+ Ebin_Dir = get_emakefile_param(Emakefile_Settings, outdir),
|
|
|
+
|
|
|
+ File_Path = filename:join(Path2, File),
|
|
|
+ BeamName = beam_path_name2(Ebin_Dir, File),
|
|
|
+
|
|
|
+ case is_compiled(BeamName, File_Path) of
|
|
|
+ false ->
|
|
|
+ % todo : Options debug_info etc
|
|
|
+ Options = if Inc_Dir =:= undefined ->
|
|
|
+ [report, return, {outdir, Ebin_Dir}];
|
|
|
+ true ->
|
|
|
+ [report, return, {i, [Inc_Dir]}, {outdir, Ebin_Dir}]
|
|
|
+ end,
|
|
|
+
|
|
|
+ io:format("~nCompiling ~p: ", [File_Path]),
|
|
|
+
|
|
|
+ case compile:file(File_Path, Options) of
|
|
|
+ error ->
|
|
|
+ io:format("~nError!~n", []);
|
|
|
+ {error, [], Warning} ->
|
|
|
+ io:format("~nWarning: ~p~n", [Warning]);
|
|
|
+ {error, Error, Warning} ->
|
|
|
+ io:format("~nErrors and warnings:~n ~p~n ~p~n", [Error, Warning]);
|
|
|
+ _ ->
|
|
|
+ io:format("ok~n", []),
|
|
|
+ Module = erlang:list_to_atom(lists:flatten(string:replace(File, ".erl", ""))),
|
|
|
+ code:purge(Module),
|
|
|
+ code:load_file(Module)
|
|
|
+ end,
|
|
|
+ ok;
|
|
|
+ _ ->
|
|
|
+ ok
|
|
|
+ end.
|
|
|
+
|
|
|
+%get_emakefile_param(Emakefile_Settings, Param) ->
|
|
|
+get_emakefile_param([], _) -> undefined;
|
|
|
+get_emakefile_param([{K, V}|T], Param) ->
|
|
|
+ case K =:= Param of
|
|
|
+ true -> V;
|
|
|
+ _ -> get_emakefile_param(T, Param)
|
|
|
+ end;
|
|
|
+get_emakefile_param([H|T], Param) ->
|
|
|
+ case H =:= Param of
|
|
|
+ true -> H;
|
|
|
+ _ -> get_emakefile_param(T, Param)
|
|
|
+ end.
|
|
|
+
|
|
|
+
|
|
|
+%{erlydtl_opts, [
|
|
|
+% {doc_root, "priv/templates"},
|
|
|
+% {out_dir, "ebin"},
|
|
|
+% {compiler_options, [report, return, debug_info]},
|
|
|
+% {auto_escape, false},
|
|
|
+% {source_ext, ".html"},
|
|
|
+% {module_ext, "_view"}
|
|
|
+%]}
|
|
|
+
|
|
|
+% [ {doc_root, "priv/templates"}, {out_dir, "ebin"}, {compiler_options, [report, return, debug_info]}, {auto_escape, false}, {source_ext, ".html"}, {module_ext, "_view"} ]
|
|
|
+
|
|
|
+dtl_opts(DocRoot, OutDir, SourceExt, ModuleExt) ->
|
|
|
+ [ {doc_root, DocRoot}, {out_dir, OutDir}, {source_ext, SourceExt}, {module_ext, ModuleExt}, {auto_escape, false},
|
|
|
+ {compiler_options, [report, return]} ].
|
|
|
+ %{compiler_options, [report, return, debug_info]} ].
|
|
|
+
|
|
|
+
|
|
|
+compile_all_dtl(DTL_Dir, Ebin_Dir) ->
|
|
|
+ %DocRoot = "priv/templates",
|
|
|
+ DocRoot = DTL_Dir,
|
|
|
+ %OutDir = "ebin",
|
|
|
+ OutDir = Ebin_Dir,
|
|
|
+ SourceExt = ".html",
|
|
|
+ ModuleExt = "_view",
|
|
|
+
|
|
|
+
|
|
|
+ %https://erlang.org/doc/man/filelib.html#fold_files-5
|
|
|
+ %fold_files(Dir, RegExp, Recursive, Fun, AccIn) -> AccOut
|
|
|
+
|
|
|
+ Files = filelib:fold_files(DocRoot, SourceExt, true,
|
|
|
+ fun(F, Acc) ->
|
|
|
+ [F|Acc]
|
|
|
+ end, []),
|
|
|
+
|
|
|
+ Opts = dtl_opts(DocRoot, OutDir, SourceExt, ModuleExt),
|
|
|
+
|
|
|
+ io:format("DTL compiling:~n", []),
|
|
|
+
|
|
|
+ lists:foldl(
|
|
|
+ fun(F, _Acc) ->
|
|
|
+ ModuleName = module_name(F, SourceExt, ModuleExt),
|
|
|
+ BeamName = beam_path_name(OutDir, erlang:atom_to_list(ModuleName)),
|
|
|
+ case is_compiled(BeamName, F) of
|
|
|
+ false ->
|
|
|
+ case erlydtl:compile(F, ModuleName, Opts) of
|
|
|
+ {error, Error} ->
|
|
|
+ io:format("Error: ~p~n", [Error]);
|
|
|
+ _ ->
|
|
|
+ file:change_time(BeamName, calendar:local_time()),
|
|
|
+ io:format("~p: ok~n", [F])
|
|
|
+ end;
|
|
|
+ _ ->
|
|
|
+ ok
|
|
|
+ end,
|
|
|
+
|
|
|
+ []
|
|
|
+ end, [], Files),
|
|
|
+ [].
|
|
|
+
|
|
|
+
|
|
|
+compile_one_dtl(File_Path, Path, Ebin_Dir, SourceExt) ->
|
|
|
+ %DocRoot = "priv/templates",
|
|
|
+ DocRoot = Path,
|
|
|
+ %OutDir = "ebin",
|
|
|
+ OutDir = Ebin_Dir,
|
|
|
+ %SourceExt = ".html", % ".html" | ".dtl"
|
|
|
+ ModuleExt = "_view",
|
|
|
+
|
|
|
+ Opts = dtl_opts(DocRoot, OutDir, SourceExt, ModuleExt),
|
|
|
+
|
|
|
+ ModuleName = module_name(File_Path, SourceExt, ModuleExt),
|
|
|
+ BeamName = beam_path_name(OutDir, erlang:atom_to_list(ModuleName)),
|
|
|
+
|
|
|
+ case is_compiled(BeamName, File_Path) of
|
|
|
+ false ->
|
|
|
+ io:format("~nCompiling ~p: ", [File_Path]),
|
|
|
+
|
|
|
+ case erlydtl:compile(File_Path, ModuleName, Opts) of
|
|
|
+ {error, Error} ->
|
|
|
+ io:format("~nError: ~p~n", [Error]);
|
|
|
+ _ ->
|
|
|
+ file:change_time(BeamName, calendar:local_time()),
|
|
|
+ io:format("ok~n", [])
|
|
|
+ end;
|
|
|
+ _ ->
|
|
|
+ ok
|
|
|
+ end,
|
|
|
+ ok.
|
|
|
+
|
|
|
+
|
|
|
+% https://erlang.org/doc/man/filename.html#basename-2
|
|
|
+% > filename:basename("src/test.txt", ".txt").
|
|
|
+% "test"
|
|
|
+module_name(File, SourceExt, ModuleExt) ->
|
|
|
+ erlang:list_to_atom(filename:basename(File, SourceExt) ++ ModuleExt).
|
|
|
+
|
|
|
+
|
|
|
+beam_path_name(OutDir, ModuleName) ->
|
|
|
+ filename:join(OutDir, filename:basename(ModuleName) ++ ".beam").
|
|
|
+
|
|
|
+
|
|
|
+beam_path_name2(OutDir, File) ->
|
|
|
+ filename:join(OutDir, filename:basename(File, ".erl") ++ ".beam").
|
|
|
+
|
|
|
+
|
|
|
+is_compiled(BeamFile, File) ->
|
|
|
+ last_modified(BeamFile) >= last_modified(File).
|
|
|
+
|
|
|
+
|
|
|
+last_modified(File) ->
|
|
|
+ case filelib:last_modified(File) of
|
|
|
+ 0 -> 0;
|
|
|
+ N ->
|
|
|
+ calendar:datetime_to_gregorian_seconds(N)
|
|
|
+ end.
|
|
|
+
|
|
|
+
|