Current section
Files
Jump to
Current section
Files
src/olive_ffi.erl
-module(olive_ffi).
-export([get_cwd/0, reload_modules/0, spawn_main_server/3, configure_logs/1, log/2,
format/2, check_watcher_installed/0, coerce/1]).
coerce(X) ->
X.
get_cwd() ->
case file:get_cwd() of
{ok, Dir} ->
{ok, list_to_binary(Dir)};
{error, Reason} ->
{error, Reason}
end.
spawn_main_server(Root, FullyQualifiedModule, Module) ->
% We want to make sure we execute the main server in the ROOT dir.
case file:set_cwd(Root) of
ok ->
{ok, spawn_link(FullyQualifiedModule, run, [Module])};
{error, Reason} ->
{error, Reason}
end.
reload_modules() ->
Modules = code:modified_modules(),
lists:foreach(fun(Mod) -> code:purge(Mod) end, Modules),
atomic_load(Modules).
atomic_load(Modules) ->
case code:atomic_load(Modules) of
ok ->
{ok, nil};
otherwise ->
otherwise
end.
configure_logs(Level) ->
logger:add_handler(olive_log,
logger_std_h,
#{formatter => {olive_ffi, #{}},
filters =>
[{olive_filter_domain,
{fun logger_filters:domain/2, {stop, not_equal, [olive]}}},
{olive_filter_level,
{fun logger_filters:level/2, {stop, lt, Level}}}],
config => #{type => standard_io}}).
log(Level, Message) ->
logger:log(Level, Message, #{domain => [olive]}).
format(#{level := Level,
msg := Msg,
meta := _Meta},
_Config) ->
[format_level(Level), format_msg(Msg), $\n].
format_level(Level) ->
case Level of
emergency ->
"\x1b[1;41mOLIVE - EMRG\x1b[0m";
alert ->
"\x1b[1;41mOLIVE - ALRT\x1b[0m";
critical ->
"\x1b[1;41mOLIVE - CRIT\x1b[0m";
error ->
"\x1b[1;31mOLIVE - ERROR\x1b[0m";
warning ->
"\x1b[1;33mOLIVE - WARN\x1b[0m";
notice ->
"\x1b[1;32mOLIVE - NTCE\x1b[0m";
info ->
"\x1b[1;34mOLIVE - INFO\x1b[0m";
debug ->
"\x1b[1;36mOLIVE - DEBG\x1b[0m"
end.
format_msg(Report0) ->
case Report0 of
{string, Msg} ->
[$\s, Msg];
_ ->
[$\s, gleam@string:inspect(Report0)]
end.
% From: https://github.com/lustre-labs/dev-tools
% This is what the underlying `fs` library does to check if it has support for
% a given os:
%
% https://github.com/5HT/fs/blob/23a5b46b033437a3d69504811ae6c72f7704a78a/src/fs_sup.erl#L18-L46
%
% Sadly the library doesn't expose such a function and just logs any error
% instead of surfacing it as a value, so we have to implement a slightly
% modified version of it to have proper error messages.
check_watcher_installed() ->
Watcher =
case os:type() of
{unix, darwin} ->
fsevents;
{unix, linux} ->
inotifywait;
{unix, sunos} ->
undefined;
{unix, _} ->
kqueue;
{win32, nt} ->
inotifywait_win32;
_ ->
undefined
end,
case Watcher of
undefined ->
{error, no_file_watcher_supported_for_os};
_ ->
case Watcher:find_executable() of
false ->
{error, {no_file_watcher_installed, Watcher}};
_ ->
{ok, nil}
end
end.