-module(olive). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([main/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/olive.gleam", 101). -spec is_main_file(olive@config:config(), binary()) -> boolean(). is_main_file(Config, File_name) -> gleam_stdlib:string_ends_with( File_name, <<<<"src/"/utf8, (erlang:element(7, Config))/binary>>/binary, ".gleam"/utf8>> ). -file("src/olive.gleam", 69). -spec listen_to_file_changes( olive@config:config(), gleam@erlang@process:subject(olive@watcher:message()), olive@client_registry:client_registry() ) -> nil. listen_to_file_changes(Config, Subject, Clients) -> Msg = gleam_erlang_ffi:'receive'(Subject), case Msg of {files_changed, File_name} -> case is_main_file(Config, File_name) of true -> olive@logging:warning( erlang:element(2, Config), <<"Main file changed. You need to restart olive for changes to be applied!"/utf8>> ); false -> olive@logging:notice( erlang:element(2, Config), <<"File changed: "/utf8, File_name/binary>> ), case olive@server_run:reload_server_code(Config) of {ok, _} -> olive@client_registry:trigger(Clients); {error, Msg@1} -> olive@logging:error( erlang:element(2, Config), Msg@1 ) end, listen_to_file_changes(Config, Subject, Clients) end end. -file("src/olive.gleam", 33). -spec run_olive(olive@config:config()) -> nil. run_olive(Config) -> Clients = olive@client_registry:start(erlang:element(2, Config)), Subject = gleam@erlang@process:new_subject(), case olive@watcher:start(Config, Subject) of {error, init_timeout} -> olive@logging:error( erlang:element(2, Config), <<"Watcher took too much time to initialize"/utf8>> ); {error, {init_crashed, _}} -> olive@logging:error( erlang:element(2, Config), <<"Watcher crashed!"/utf8>> ); {error, {init_failed, {abnormal, Msg}}} -> olive@logging:error(erlang:element(2, Config), Msg); {error, {init_failed, killed}} -> olive@logging:error( erlang:element(2, Config), <<"Watcher was killed before initialisation"/utf8>> ); {error, {init_failed, normal}} -> olive@logging:error( erlang:element(2, Config), <<"Watcher shutdown before end of initialisation"/utf8>> ); {ok, _} -> case olive@server_run:start_server(Config) of {ok, _} -> _assert_subject = olive@proxy:start_http(Config, Clients), {ok, _} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"olive"/utf8>>, function => <<"run_olive"/utf8>>, line => 54}) end, listen_to_file_changes(Config, Subject, Clients); {error, Reason} -> olive@logging:error( erlang:element(2, Config), <<"Could not start your server:\n"/utf8, Reason/binary>> ) end end. -file("src/olive.gleam", 19). ?DOC( " Process is as follow:\n" " - Start a client registry\n" " - Start watcher, giving it a subject we will listen to.\n" " - Every time watcher sends us a message:\n" " - Reload server code\n" " - Send reload message to clients\n" ). -spec main() -> nil. main() -> case olive@cli:get_options() of {error, nil} -> nil; {ok, Options} -> Logger = olive@logging:get_logger(erlang:element(5, Options)), case olive@config:read_config(Logger, Options) of {error, Error} -> olive@logging:error(Logger, Error); {ok, Config} -> run_olive(Config) end end.