aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/dev/erlang/gleam_httpc
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/dev/erlang/gleam_httpc')
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@@compile.erl157
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cachebin0 -> 4263 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_metabin0 -> 199 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.erl118
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beambin0 -> 4888 bytes
-rw-r--r--aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam_httpc.app10
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
new file mode 100644
index 0000000..59082af
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache
Binary files differ
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
new file mode 100644
index 0000000..a340156
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_httpc/_gleam_artefacts/gleam@httpc.cache_meta
Binary files differ
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
new file mode 100644
index 0000000..1edf411
--- /dev/null
+++ b/aoc2023/build/dev/erlang/gleam_httpc/ebin/gleam@httpc.beam
Binary files differ
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, []}
+]}.