diff options
Diffstat (limited to 'aoc2023/build/dev/erlang/gleam_httpc')
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@@compile.erl | 157 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache | bin | 0 -> 4263 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_meta | bin | 0 -> 199 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.erl | 118 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beam | bin | 0 -> 4888 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam_httpc.app | 10 |
6 files changed, 285 insertions, 0 deletions
diff --git a/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@@compile.erl b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@@compile.erl new file mode 100644 index 0000000..543db88 --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@@compile.erl @@ -0,0 +1,157 @@ +#!/usr/bin/env escript + +% TODO: Don't concurrently print warnings and errors +% TODO: Some tests + +-record(arguments, {lib = "./", out = "./", modules = []}). + +main(Args) -> + #arguments{out = Out, lib = Lib, modules = Modules} = parse(Args), + IsElixirModule = fun(Module) -> + filename:extension(Module) =:= ".ex" + end, + {ElixirModules, ErlangModules} = lists:partition(IsElixirModule, Modules), + ok = configure_logging(), + ok = add_lib_to_erlang_path(Lib), + ok = filelib:ensure_dir([Out, $/]), + {ErlangOk, _ErlangBeams} = compile_erlang(ErlangModules, Out), + {ElixirOk, _ElixirBeams} = case ErlangOk of + true -> compile_elixir(ElixirModules, Out); + false -> {false, []} + end, + case ErlangOk and ElixirOk of + true -> ok; + false -> erlang:halt(1) + end. + +compile_erlang(Modules, Out) -> + Workers = start_compiler_workers(Out), + ok = producer_loop(Modules, Workers), + collect_results({true, []}). + +collect_results(Acc = {Result, Beams}) -> + receive + {compiled, Beam} -> collect_results({Result, [Beam | Beams]}); + failed -> collect_results({false, Beams}) + after 0 -> Acc + end. + +producer_loop([], 0) -> + ok; +producer_loop([], Workers) -> + receive + {work_please, _} -> producer_loop([], Workers - 1) + end; +producer_loop([Module | Modules], Workers) -> + receive + {work_please, Worker} -> + erlang:send(Worker, {module, Module}), + producer_loop(Modules, Workers) + end. + +start_compiler_workers(Out) -> + Parent = self(), + NumSchedulers = erlang:system_info(schedulers), + SpawnWorker = fun(_) -> + erlang:spawn_link(fun() -> worker_loop(Parent, Out) end) + end, + lists:foreach(SpawnWorker, lists:seq(1, NumSchedulers)), + NumSchedulers. + +worker_loop(Parent, Out) -> + Options = [report_errors, report_warnings, debug_info, {outdir, Out}], + erlang:send(Parent, {work_please, self()}), + receive + {module, Module} -> + log({compiling, Module}), + case compile:file(Module, Options) of + {ok, ModuleName} -> + Beam = filename:join(Out, ModuleName) ++ ".beam", + Message = {compiled, Beam}, + log(Message), + erlang:send(Parent, Message); + error -> + log({failed, Module}), + erlang:send(Parent, failed) + end, + worker_loop(Parent, Out) + end. + +compile_elixir(Modules, Out) -> + Error = [ + "The program elixir was not found. Is it installed?", + $\n, + "Documentation for installing Elixir can be viewed here:", + $\n, + "https://elixir-lang.org/install.html" + ], + case Modules of + [] -> {true, []}; + _ -> + log({starting, "compiler.app"}), + ok = application:start(compiler), + log({starting, "elixir.app"}), + case application:start(elixir) of + ok -> do_compile_elixir(Modules, Out); + _ -> + io:put_chars(standard_error, [Error, $\n]), + {false, []} + end + end. + +do_compile_elixir(Modules, Out) -> + ModuleBins = lists:map(fun(Module) -> + log({compiling, Module}), + list_to_binary(Module) + end, Modules), + OutBin = list_to_binary(Out), + Options = [{dest, OutBin}], + % Silence "redefining module" warnings. + % Compiled modules in the build directory are added to the code path. + % These warnings result from recompiling loaded modules. + % TODO: This line can likely be removed if/when the build directory is cleaned before every compilation. + 'Elixir.Code':compiler_options([{ignore_module_conflict, true}]), + case 'Elixir.Kernel.ParallelCompiler':compile_to_path(ModuleBins, OutBin, Options) of + {ok, ModuleAtoms, _} -> + ToBeam = fun(ModuleAtom) -> + Beam = filename:join(Out, atom_to_list(ModuleAtom)) ++ ".beam", + log({compiled, Beam}), + Beam + end, + {true, lists:map(ToBeam, ModuleAtoms)}; + {error, Errors, _} -> + % Log all filenames associated with modules that failed to compile. + % Note: The compiler prints compilation errors upon encountering them. + ErrorFiles = lists:usort([File || {File, _, _} <- Errors]), + Log = fun(File) -> + log({failed, binary_to_list(File)}) + end, + lists:foreach(Log, ErrorFiles), + {false, []}; + _ -> {false, []} + end. + +add_lib_to_erlang_path(Lib) -> + code:add_paths(filelib:wildcard([Lib, "/*/ebin"])). + +parse(Args) -> + parse(Args, #arguments{}). + +parse([], Arguments) -> + Arguments; +parse(["--lib", Lib | Rest], Arguments) -> + parse(Rest, Arguments#arguments{lib = Lib}); +parse(["--out", Out | Rest], Arguments) -> + parse(Rest, Arguments#arguments{out = Out}); +parse([Module | Rest], Arguments = #arguments{modules = Modules}) -> + parse(Rest, Arguments#arguments{modules = [Module | Modules]}). + +configure_logging() -> + Enabled = os:getenv("GLEAM_LOG") /= false, + persistent_term:put(gleam_logging_enabled, Enabled). + +log(Term) -> + case persistent_term:get(gleam_logging_enabled) of + true -> erlang:display(Term), ok; + false -> ok + end. diff --git a/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache Binary files differnew file mode 100644 index 0000000..59082af --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache diff --git a/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_meta b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_meta Binary files differnew file mode 100644 index 0000000..a340156 --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_meta diff --git a/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.erl b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.erl new file mode 100644 index 0000000..1d634df --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.erl @@ -0,0 +1,118 @@ +-module(gleam@httpc). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([send_bits/1, send/1]). +-export_type([charlist/0, erl_http_option/0, body_format/0, erl_option/0]). + +-type charlist() :: any(). + +-type erl_http_option() :: any(). + +-type body_format() :: binary. + +-type erl_option() :: {body_format, body_format()}. + +-spec charlist_header({binary(), binary()}) -> {charlist(), charlist()}. +charlist_header(Header) -> + {K, V} = Header, + {erlang:binary_to_list(K), erlang:binary_to_list(V)}. + +-spec string_header({charlist(), charlist()}) -> {binary(), binary()}. +string_header(Header) -> + {K, V} = Header, + {erlang:list_to_binary(K), erlang:list_to_binary(V)}. + +-spec send_bits(gleam@http@request:request(bitstring())) -> {ok, + gleam@http@response:response(bitstring())} | + {error, gleam@dynamic:dynamic_()}. +send_bits(Req) -> + Erl_url = begin + _pipe = Req, + _pipe@1 = gleam@http@request:to_uri(_pipe), + _pipe@2 = gleam@uri:to_string(_pipe@1), + erlang:binary_to_list(_pipe@2) + end, + Erl_headers = gleam@list:map(erlang:element(3, Req), fun charlist_header/1), + Erl_http_options = [], + Erl_options = [{body_format, binary}], + gleam@result:then(case erlang:element(2, Req) of + options -> + Erl_req = {Erl_url, Erl_headers}, + httpc:request( + erlang:element(2, Req), + Erl_req, + Erl_http_options, + Erl_options + ); + + head -> + Erl_req = {Erl_url, Erl_headers}, + httpc:request( + erlang:element(2, Req), + Erl_req, + Erl_http_options, + Erl_options + ); + + get -> + Erl_req = {Erl_url, Erl_headers}, + httpc:request( + erlang:element(2, Req), + Erl_req, + Erl_http_options, + Erl_options + ); + + _ -> + Erl_content_type = begin + _pipe@3 = Req, + _pipe@4 = gleam@http@request:get_header( + _pipe@3, + <<"content-type"/utf8>> + ), + _pipe@5 = gleam@result:unwrap( + _pipe@4, + <<"application/octet-stream"/utf8>> + ), + erlang:binary_to_list(_pipe@5) + end, + Erl_req@1 = {Erl_url, + Erl_headers, + Erl_content_type, + erlang:element(4, Req)}, + httpc:request( + erlang:element(2, Req), + Erl_req@1, + Erl_http_options, + Erl_options + ) + end, fun(Response) -> + {{_, Status, _}, Headers, Resp_body} = Response, + {ok, + {response, + Status, + gleam@list:map(Headers, fun string_header/1), + Resp_body}} + end). + +-spec send(gleam@http@request:request(binary())) -> {ok, + gleam@http@response:response(binary())} | + {error, gleam@dynamic:dynamic_()}. +send(Req) -> + gleam@result:then( + begin + _pipe = Req, + _pipe@1 = gleam@http@request:map(_pipe, fun gleam_stdlib:identity/1), + send_bits(_pipe@1) + end, + fun(Resp) -> case gleam@bit_array:to_string(erlang:element(4, Resp)) of + {ok, Body} -> + {ok, gleam@http@response:set_body(Resp, Body)}; + + {error, _} -> + {error, + gleam@dynamic:from( + <<"Response body was not valid UTF-8"/utf8>> + )} + end end + ). diff --git a/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beam b/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beam Binary files differnew file mode 100644 index 0000000..1edf411 --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beam diff --git a/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam_httpc.app b/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam_httpc.app new file mode 100644 index 0000000..c99b5ea --- /dev/null +++ b/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam_httpc.app @@ -0,0 +1,10 @@ +{application, gleam_httpc, [ + {vsn, "2.1.1"}, + {applications, [gleam_http, + gleam_stdlib, + inets, + ssl]}, + {description, "Gleam bindings to Erlang's built in HTTP client, httpc"}, + {modules, []}, + {registered, []} +]}. |