Packages

A library for downloading Gleam packages

Current section

Files

Jump to
pack src pack.erl
Raw

src/pack.erl

-module(pack).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pack.gleam").
-export([describe_error/1, packages/1, packages_directory/1, load/1, download/1, download_to_disc/1, main/0]).
-export_type([package/0, release/0, pack/0, error/0, options/0, command/0, file/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.
-type package() :: {package,
binary(),
binary(),
binary(),
gleam@option:option(binary()),
integer(),
list(release())}.
-type release() :: {release, binary(), integer(), integer()}.
-opaque pack() :: {pack, binary(), options(), list(package())}.
-type error() :: failed_to_get_directory |
{failed_to_create_directory, binary(), simplifile:file_error()} |
{failed_to_write_to_file, binary(), simplifile:file_error()} |
{failed_to_read_file, binary(), simplifile:file_error()} |
{failed_to_delete_directory, binary(), simplifile:file_error()} |
{failed_to_read_directory, binary(), simplifile:file_error()} |
{request_failed, binary(), gleam@httpc:http_error()} |
{request_returned_incorrect_response, binary(), integer()} |
{response_json_invalid, gleam@json:decode_error()} |
{file_contained_invalid_json, gleam@json:decode_error()} |
{failed_to_decode_hex_tarball, binary()}.
-type options() :: {options,
boolean(),
boolean(),
boolean(),
boolean(),
boolean()}.
-type command() :: help | {fetch, options()} | {download, options()} | directory.
-type file() :: {text_file, binary(), binary()} |
{binary_file, binary(), bitstring()}.
-file("src/pack.gleam", 77).
-spec release_to_json(release()) -> gleam@json:json().
release_to_json(Release) ->
{release, Version, Downloads, Updated_at} = Release,
gleam@json:object(
[{<<"version"/utf8>>, gleam@json:string(Version)},
{<<"downloads"/utf8>>, gleam@json:int(Downloads)},
{<<"updated-at"/utf8>>, gleam@json:int(Updated_at)}]
).
-file("src/pack.gleam", 32).
-spec package_to_json(package()) -> gleam@json:json().
package_to_json(Package) ->
{package,
Name,
Description,
Latest_version,
Repository,
Updated_at,
Releases} = Package,
gleam@json:object(
[{<<"name"/utf8>>, gleam@json:string(Name)},
{<<"description"/utf8>>, gleam@json:string(Description)},
{<<"latest-version"/utf8>>, gleam@json:string(Latest_version)},
{<<"repository"/utf8>>, case Repository of
none ->
gleam@json:null();
{some, Value} ->
gleam@json:string(Value)
end},
{<<"updated-at"/utf8>>, gleam@json:int(Updated_at)},
{<<"releases"/utf8>>,
gleam@json:array(Releases, fun release_to_json/1)}]
).
-file("src/pack.gleam", 86).
-spec release_decoder() -> gleam@dynamic@decode:decoder(release()).
release_decoder() ->
gleam@dynamic@decode:field(
<<"version"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Version) ->
gleam@dynamic@decode:field(
<<"downloads"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Downloads) ->
gleam@dynamic@decode:field(
<<"updated-at"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Updated_at) ->
gleam@dynamic@decode:success(
{release, Version, Downloads, Updated_at}
)
end
)
end
)
end
).
-file("src/pack.gleam", 54).
-spec package_decoder() -> gleam@dynamic@decode:decoder(package()).
package_decoder() ->
gleam@dynamic@decode:field(
<<"name"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:field(
<<"description"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Description) ->
gleam@dynamic@decode:field(
<<"latest-version"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Latest_version) ->
gleam@dynamic@decode:field(
<<"repository"/utf8>>,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Repository) ->
gleam@dynamic@decode:field(
<<"updated-at"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_int/1},
fun(Updated_at) ->
gleam@dynamic@decode:field(
<<"releases"/utf8>>,
gleam@dynamic@decode:list(
release_decoder()
),
fun(Releases) ->
gleam@dynamic@decode:success(
{package,
Name,
Description,
Latest_version,
Repository,
Updated_at,
Releases}
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/pack.gleam", 178).
-spec connect_error(gleam@httpc:connect_error()) -> binary().
connect_error(Error) ->
case Error of
{posix, Code} ->
<<"Posix error: "/utf8, Code/binary>>;
{tls_alert, Code@1, Detail} ->
<<<<<<"TLS alert: "/utf8, Code@1/binary>>/binary, ", "/utf8>>/binary,
Detail/binary>>
end.
-file("src/pack.gleam", 169).
-spec httpc_error(gleam@httpc:http_error()) -> binary().
httpc_error(Error) ->
case Error of
{failed_to_connect, Ip4, _} ->
<<"Failed to connect: "/utf8, (connect_error(Ip4))/binary>>;
invalid_utf8_response ->
<<"Invalid Utf-8 response"/utf8>>;
response_timeout ->
<<"Response timed out"/utf8>>
end.
-file("src/pack.gleam", 195).
-spec decode_error(gleam@dynamic@decode:decode_error()) -> binary().
decode_error(Error) ->
{decode_error, Expected, Found, Path} = Error,
<<<<<<<<<<"Expected "/utf8, Expected/binary>>/binary, " at "/utf8>>/binary,
(gleam@string:join(Path, <<"."/utf8>>))/binary>>/binary,
", but found "/utf8>>/binary,
Found/binary>>.
-file("src/pack.gleam", 185).
-spec json_error(gleam@json:decode_error()) -> binary().
json_error(Error) ->
case Error of
{unable_to_decode, Errors} ->
<<"Unable to decode: "/utf8,
(gleam@string:join(
gleam@list:map(Errors, fun decode_error/1),
<<"; "/utf8>>
))/binary>>;
{unexpected_byte, Byte} ->
<<<<"Unexpected byte `"/utf8, Byte/binary>>/binary, "`"/utf8>>;
unexpected_end_of_input ->
<<"Unexpected end of input"/utf8>>;
{unexpected_sequence, Byte@1} ->
<<<<"Unexpected sequence: `"/utf8, Byte@1/binary>>/binary,
"`"/utf8>>
end.
-file("src/pack.gleam", 125).
?DOC(" Turn an error into a human-readable string.\n").
-spec describe_error(error()) -> binary().
describe_error(Error) ->
case Error of
{failed_to_create_directory, Path, Error@1} ->
<<<<<<"Failed to create directory "/utf8, Path/binary>>/binary,
". The error message was: "/utf8>>/binary,
(simplifile:describe_error(Error@1))/binary>>;
{failed_to_delete_directory, Path@1, Error@2} ->
<<<<<<"Failed to delete "/utf8, Path@1/binary>>/binary,
". The error message was: "/utf8>>/binary,
(simplifile:describe_error(Error@2))/binary>>;
{failed_to_read_directory, Path@2, Error@3} ->
<<<<<<"Failed to read directory "/utf8, Path@2/binary>>/binary,
". The error message was: "/utf8>>/binary,
(simplifile:describe_error(Error@3))/binary>>;
{failed_to_read_file, Path@3, Error@4} ->
<<<<<<"Failed to read "/utf8, Path@3/binary>>/binary,
". The error message was: "/utf8>>/binary,
(simplifile:describe_error(Error@4))/binary>>;
{failed_to_write_to_file, Path@4, Error@5} ->
<<<<<<"Failed to write to "/utf8, Path@4/binary>>/binary,
". The error message was: "/utf8>>/binary,
(simplifile:describe_error(Error@5))/binary>>;
{failed_to_decode_hex_tarball, Package} ->
<<"Failed to decode Hex tarball for "/utf8, Package/binary>>;
failed_to_get_directory ->
<<"Failed to find suitable directory for storing data"/utf8>>;
{file_contained_invalid_json, Error@6} ->
<<"Data file contained invalid JSON. The error message was: "/utf8,
(json_error(Error@6))/binary>>;
{request_failed, Url, Error@7} ->
<<<<<<"Request to "/utf8, Url/binary>>/binary,
" failed. The error was: "/utf8>>/binary,
(httpc_error(Error@7))/binary>>;
{request_returned_incorrect_response, Url@1, Status_code} ->
<<<<<<"Request to "/utf8, Url@1/binary>>/binary,
" return invalid response, status code "/utf8>>/binary,
(erlang:integer_to_binary(Status_code))/binary>>;
{response_json_invalid, Error@8} ->
<<"Response JSON invalid: "/utf8, (json_error(Error@8))/binary>>
end.
-file("src/pack.gleam", 246).
?DOC(" Get the list of packages from the package index.\n").
-spec packages(pack()) -> list(package()).
packages(Pack) ->
erlang:element(4, Pack).
-file("src/pack.gleam", 332).
-spec do_index_try_map(
list(JAO),
integer(),
fun((JAO, integer()) -> {ok, JAQ} | {error, JAR}),
list(JAQ)
) -> {ok, list(JAQ)} | {error, JAR}.
do_index_try_map(List, Index, F, Acc) ->
case List of
[] ->
{ok, lists:reverse(Acc)};
[First | Rest] ->
case F(First, Index) of
{error, Error} ->
{error, Error};
{ok, Value} ->
do_index_try_map(Rest, Index + 1, F, [Value | Acc])
end
end.
-file("src/pack.gleam", 325).
-spec index_try_map(
list(JAF),
fun((JAF, integer()) -> {ok, JAH} | {error, JAI})
) -> {ok, list(JAH)} | {error, JAI}.
index_try_map(List, F) ->
do_index_try_map(List, 0, F, []).
-file("src/pack.gleam", 378).
-spec check_response_status(binary(), gleam@http@response:response(any())) -> {ok,
nil} |
{error, error()}.
check_response_status(Url, Response) ->
case erlang:element(2, Response) of
200 ->
{ok, nil};
Status ->
{error, {request_returned_incorrect_response, Url, Status}}
end.
-file("src/pack.gleam", 388).
-spec pack_directory() -> {ok, binary()} | {error, error()}.
pack_directory() ->
begin
Result = gleam@result:replace_error(
directories:data_local_dir(),
failed_to_get_directory
),
case Result of
{ok, X} ->
{ok, filepath:join(X, <<"pack"/utf8>>)};
{error, E} ->
{error, E}
end
end.
-file("src/pack.gleam", 396).
?DOC(" Returns the path to the directory containing downloaded package source code.\n").
-spec packages_directory(pack()) -> binary().
packages_directory(Pack) ->
filepath:join(erlang:element(2, Pack), <<"packages"/utf8>>).
-file("src/pack.gleam", 425).
-spec packages_file(binary()) -> binary().
packages_file(Pack_directory) ->
filepath:join(Pack_directory, <<"packages.json"/utf8>>).
-file("src/pack.gleam", 470).
-spec parse_options(list(binary()), options()) -> options().
parse_options(Arguments, Options) ->
case Arguments of
[] ->
Options;
[<<"--refresh"/utf8>> | Arguments@1] ->
parse_options(
Arguments@1,
{options,
erlang:element(2, Options),
true,
erlang:element(4, Options),
erlang:element(5, Options),
erlang:element(6, Options)}
);
[<<"--redownload-all"/utf8>> | Arguments@2] ->
parse_options(
Arguments@2,
{options,
erlang:element(2, Options),
erlang:element(3, Options),
erlang:element(4, Options),
false,
erlang:element(6, Options)}
);
[<<"--quiet"/utf8>> | Arguments@3] ->
parse_options(
Arguments@3,
{options,
erlang:element(2, Options),
erlang:element(3, Options),
erlang:element(4, Options),
erlang:element(5, Options),
false}
);
[_ | Arguments@4] ->
parse_options(Arguments@4, Options)
end.
-file("src/pack.gleam", 486).
-spec print_help() -> nil.
print_help() ->
gleam_stdlib:println(
<<"
USAGE: pack <command> [flags]
Commands:
- help: Print this help message
- fetch: Fetch package information from the Gleam package index without downloading
any source code
- download: Download all Gleam packages from Hex
- directory: Print the directory `pack` uses to store data
Flags:
--refresh If `pack` has been run before, the information from the Gleam package
index is cached in a file to avoid querying the API every time. `--refresh`
causes `pack` to re-fetch all information from the package index.
--redownload-all Normally, when downloading packages, `pack` will skip any which
already are on disc. Instead, all packages will be re-downloaded.
--quiet Run the desired command without logging progress.
"/utf8>>
).
-file("src/pack.gleam", 681).
-spec write_package_files_to_disc(
pack(),
binary(),
list({binary(), bitstring()})
) -> {ok, nil} | {error, error()}.
write_package_files_to_disc(Pack, Package_name, Files) ->
Packages_directory = packages_directory(Pack),
Directory_path = filepath:join(Packages_directory, Package_name),
gleam@list:try_each(
Files,
fun(File) ->
{Name, Contents} = File,
Path = filepath:join(Directory_path, Name),
Containing_directory = filepath:directory_name(Path),
gleam@result:'try'(
gleam@result:map_error(
simplifile:create_directory_all(Containing_directory),
fun(_capture) ->
{failed_to_create_directory,
Containing_directory,
_capture}
end
),
fun(_use0) ->
nil = _use0,
_pipe = simplifile_erl:write_bits(Path, Contents),
gleam@result:map_error(
_pipe,
fun(_capture@1) ->
{failed_to_write_to_file, Path, _capture@1}
end
)
end
)
end
).
-file("src/pack.gleam", 711).
-spec do_log(options(), binary()) -> nil.
do_log(Options, Text) ->
case erlang:element(6, Options) of
false ->
nil;
true ->
gleam_stdlib:print_error(Text)
end.
-file("src/pack.gleam", 270).
-spec load_pack_from_file(binary(), options()) -> {ok, pack()} |
{error, error()}.
load_pack_from_file(Pack_directory, Options) ->
do_log(Options, <<"Reading packages file..."/utf8>>),
File_path = packages_file(Pack_directory),
begin
Result@1 = begin
Result = simplifile:read(File_path),
case Result of
{ok, X} ->
{ok, X};
{error, Error} ->
{error, {failed_to_read_file, File_path, Error}}
end
end,
case Result@1 of
{ok, X@1} ->
begin
Result@3 = begin
Result@2 = gleam@json:parse(
X@1,
gleam@dynamic@decode:at(
[<<"packages"/utf8>>],
gleam@dynamic@decode:list(package_decoder())
)
),
case Result@2 of
{ok, X@2} ->
{ok, X@2};
{error, Error@1} ->
{error, {file_contained_invalid_json, Error@1}}
end
end,
case Result@3 of
{ok, X@3} ->
do_log(Options, <<" Done\n"/utf8>>),
{ok, {pack, Pack_directory, Options, X@3}};
{error, E} ->
{error, E}
end
end;
{error, E@1} ->
{error, E@1}
end
end.
-file("src/pack.gleam", 707).
-spec log(pack(), binary()) -> nil.
log(Pack, Text) ->
do_log(erlang:element(3, Pack), Text).
-file("src/pack.gleam", 400).
-spec write_to_file(pack()) -> {ok, nil} | {error, error()}.
write_to_file(Pack) ->
log(Pack, <<"Writing packages to file..."/utf8>>),
Json = begin
_pipe = gleam@json:object(
[{<<"packages"/utf8>>,
gleam@json:array(
erlang:element(4, Pack),
fun package_to_json/1
)}]
),
gleam@json:to_string(_pipe)
end,
begin
Result@1 = begin
Result = simplifile:create_directory_all(erlang:element(2, Pack)),
case Result of
{ok, X} ->
{ok, X};
{error, Error} ->
{error,
{failed_to_create_directory,
erlang:element(2, Pack),
Error}}
end
end,
case Result@1 of
{ok, X@1} ->
nil = X@1,
Packages_file = packages_file(erlang:element(2, Pack)),
begin
Result@3 = begin
Result@2 = simplifile:write(Packages_file, Json),
case Result@2 of
{ok, X@2} ->
{ok, X@2};
{error, Error@1} ->
{error,
{failed_to_write_to_file,
Packages_file,
Error@1}}
end
end,
case Result@3 of
{ok, X@3} ->
{ok,
begin
nil = X@3,
log(Pack, <<" Done\n"/utf8>>)
end};
{error, E} ->
{error, E}
end
end;
{error, E@1} ->
{error, E@1}
end
end.
-file("src/pack.gleam", 460).
-spec parse_arguments(list(binary())) -> command().
parse_arguments(Arguments) ->
case Arguments of
[<<"download"/utf8>> | Arguments@1] ->
{download,
parse_options(
Arguments@1,
{options, true, false, true, true, true}
)};
[<<"fetch"/utf8>> | Arguments@2] ->
{fetch,
parse_options(
Arguments@2,
{options, true, false, true, true, true}
)};
[<<"directory"/utf8>> | _] ->
directory;
_ ->
help
end.
-file("src/pack.gleam", 348).
-spec fetch_package(binary(), integer(), options(), binary()) -> {ok, package()} |
{error, error()}.
fetch_package(Name, Index, Options, Total_packages) ->
do_log(
Options,
<<<<"Fetching information for "/utf8, Name/binary>>/binary, "..."/utf8>>
),
Url = <<"https://packages.gleam.run/api/packages/"/utf8, Name/binary>>,
Request@1 = case gleam@http@request:to(Url) of
{ok, Request} -> Request;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"URL parsing should always succeed"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"fetch_package"/utf8>>,
line => 357,
value => _assert_fail,
start => 11536,
'end' => 11576,
pattern_start => 11547,
pattern_end => 11558})
end,
begin
Result = begin
_pipe = gleam@httpc:send(Request@1),
case _pipe of
{ok, X} ->
{ok, X};
{error, Error} ->
{error, {request_failed, Url, Error}}
end
end,
case Result of
{ok, X@1} ->
Response = X@1,
case check_response_status(Url, Response) of
{ok, X@2} ->
nil = X@2,
begin
Result@2 = begin
Result@1 = gleam@json:parse(
erlang:element(4, Response),
gleam@dynamic@decode:at(
[<<"data"/utf8>>],
package_decoder()
)
),
case Result@1 of
{ok, X@3} ->
{ok, X@3};
{error, Error@1} ->
{error,
{response_json_invalid, Error@1}}
end
end,
case Result@2 of
{ok, X@4} ->
{ok,
begin
do_log(
Options,
<<<<<<<<" Done ("/utf8,
(erlang:integer_to_binary(
Index + 1
))/binary>>/binary,
"/"/utf8>>/binary,
Total_packages/binary>>/binary,
")\n"/utf8>>
),
X@4
end};
{error, E} ->
{error, E}
end
end;
{error, E@1} ->
{error, E@1}
end;
{error, E@2} ->
{error, E@2}
end
end.
-file("src/pack.gleam", 292).
-spec fetch_packages(options()) -> {ok, list(package())} | {error, error()}.
fetch_packages(Options) ->
do_log(Options, <<"Fetching package list..."/utf8>>),
Request@1 = case gleam@http@request:to(
<<"https://packages.gleam.run/api/packages/"/utf8>>
) of
{ok, Request} -> Request;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"URL parsing should always succeed"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"fetch_packages"/utf8>>,
line => 295,
value => _assert_fail,
start => 9868,
'end' => 9921,
pattern_start => 9879,
pattern_end => 9890})
end,
begin
Result = begin
_pipe = gleam@httpc:send(Request@1),
case _pipe of
{ok, X} ->
{ok, X};
{error, Error} ->
{error,
{request_failed,
<<"https://packages.gleam.run/api/packages/"/utf8>>,
Error}}
end
end,
case Result of
{ok, X@1} ->
Response = X@1,
case check_response_status(
<<"https://packages.gleam.run/api/packages/"/utf8>>,
Response
) of
{ok, X@2} ->
nil = X@2,
Parsed_json = gleam@json:parse(
erlang:element(4, Response),
gleam@dynamic@decode:at(
[<<"data"/utf8>>],
gleam@dynamic@decode:list(
gleam@dynamic@decode:at(
[<<"name"/utf8>>],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
)
)
),
case case Parsed_json of
{ok, X@3} ->
{ok, X@3};
{error, Error@1} ->
{error, {response_json_invalid, Error@1}}
end of
{ok, X@4} ->
Package_names = X@4,
do_log(Options, <<" Done\n"/utf8>>),
Package_count = erlang:integer_to_binary(
erlang:length(Package_names)
),
index_try_map(
Package_names,
fun(Package, Index) ->
fetch_package(
Package,
Index,
Options,
Package_count
)
end
);
{error, E} ->
{error, E}
end;
{error, E@1} ->
{error, E@1}
end;
{error, E@2} ->
{error, E@2}
end
end.
-file("src/pack.gleam", 252).
?DOC(
" Load state, either from a file or by fetching data from the Gleam package index,\n"
" depending on the options and whether `pack` has been run before.\n"
).
-spec load(options()) -> {ok, pack()} | {error, error()}.
load(Options) ->
begin
Result = pack_directory(),
case Result of
{ok, X} ->
Pack_directory = X,
case not erlang:element(3, Options) andalso (simplifile_erl:is_file(
packages_file(Pack_directory)
)
=:= {ok, true}) of
true ->
load_pack_from_file(Pack_directory, Options);
false ->
begin
Result@1 = fetch_packages(Options),
case Result@1 of
{ok, X@1} ->
Pack = {pack, Pack_directory, Options, X@1},
begin
Result@2 = write_to_file(Pack),
case Result@2 of
{ok, X@2} ->
nil = X@2,
{ok, Pack};
{error, E} ->
{error, E}
end
end;
{error, E@1} ->
{error, E@1}
end
end
end;
{error, E@2} ->
{error, E@2}
end
end.
-file("src/pack.gleam", 631).
-spec download_package(pack(), package(), integer(), binary()) -> {ok,
gleam@option:option({binary(), list({binary(), bitstring()})})} |
{error, error()}.
download_package(Pack, Package, Index, Package_count) ->
File_name = <<<<<<(erlang:element(2, Package))/binary, "-"/utf8>>/binary,
(erlang:element(4, Package))/binary>>/binary,
".tar"/utf8>>,
log(Pack, <<<<"Downloading "/utf8, File_name/binary>>/binary, "..."/utf8>>),
Url = <<"https://repo.hex.pm/tarballs/"/utf8, File_name/binary>>,
Request@1 = case gleam@http@request:to(Url) of
{ok, Request} -> Request;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"URL parsing failed"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"download_package"/utf8>>,
line => 642,
value => _assert_fail,
start => 19650,
'end' => 19690,
pattern_start => 19661,
pattern_end => 19672})
end,
begin
Result = begin
_pipe = Request@1,
_pipe@1 = gleam@http@request:set_body(_pipe, <<>>),
_pipe@2 = gleam@httpc:send_bits(_pipe@1),
case _pipe@2 of
{ok, X} ->
{ok, X};
{error, Error} ->
{error, {request_failed, Url, Error}}
end
end,
case Result of
{ok, X@1} ->
Response = X@1,
case erlang:element(2, Response) =:= 404 of
true ->
log(Pack, <<" Package missing on Hex\n"/utf8>>),
{ok, none};
false ->
case check_response_status(Url, Response) of
{ok, X@2} ->
nil = X@2,
begin
Result@1 = gleam@result:replace_error(
pack_ffi:extract_files(
erlang:element(4, Response)
),
{failed_to_decode_hex_tarball,
erlang:element(2, Package)}
),
case Result@1 of
{ok, X@3} ->
Files = X@3,
begin
Result@2 = case erlang:element(
4,
erlang:element(3, Pack)
) of
false ->
{ok, nil};
true ->
write_package_files_to_disc(
Pack,
erlang:element(
2,
Package
),
Files
)
end,
case Result@2 of
{ok, X@4} ->
nil = X@4,
log(
Pack,
<<<<<<<<" Done ("/utf8,
(erlang:integer_to_binary(
Index
))/binary>>/binary,
"/"/utf8>>/binary,
Package_count/binary>>/binary,
")\n"/utf8>>
),
{ok,
{some,
{erlang:element(
2,
Package
),
Files}}};
{error, E} ->
{error, E}
end
end;
{error, E@1} ->
{error, E@1}
end
end;
{error, E@2} ->
{error, E@2}
end
end;
{error, E@3} ->
{error, E@3}
end
end.
-file("src/pack.gleam", 559).
-spec do_download_packages(pack()) -> {ok,
list({binary(), list({binary(), bitstring()})})} |
{error, error()}.
do_download_packages(Pack) ->
Packages_directory = packages_directory(Pack),
Package_count = erlang:integer_to_binary(
erlang:length(erlang:element(4, Pack))
),
Result = gleam@list:try_fold(
erlang:element(4, Pack),
{[], 0},
fun(Acc, Package) ->
{Packages, Index} = Acc,
Directory_path = filepath:join(
Packages_directory,
erlang:element(2, Package)
),
With_slash = <<Directory_path/binary, "/"/utf8>>,
Index@1 = Index + 1,
case simplifile_erl:is_directory(Directory_path) of
{ok, true} when erlang:element(5, erlang:element(3, Pack)) ->
log(
Pack,
<<<<"Reading package "/utf8,
(erlang:element(2, Package))/binary>>/binary,
"from disc..."/utf8>>
),
gleam@result:'try'(
gleam@result:map_error(
simplifile:get_files(Directory_path),
fun(_capture) ->
{failed_to_read_directory,
Directory_path,
_capture}
end
),
fun(Files) ->
gleam@result:'try'(
gleam@list:try_map(
Files,
fun(Path) ->
Name = pack_ffi:strip_prefix(
Path,
With_slash
),
case simplifile_erl:read_bits(Path) of
{error, Error} ->
{error,
{failed_to_read_file,
Path,
Error}};
{ok, Contents} ->
{ok, {Name, Contents}}
end
end
),
fun(Files@1) ->
log(
Pack,
<<<<<<<<" Done ("/utf8,
(erlang:integer_to_binary(
Index@1
))/binary>>/binary,
"/"/utf8>>/binary,
Package_count/binary>>/binary,
")\n"/utf8>>
),
{ok,
{[{erlang:element(2, Package), Files@1} |
Packages],
Index@1}}
end
)
end
);
{ok, true} ->
gleam@result:'try'(
gleam@result:map_error(
simplifile_erl:delete(Directory_path),
fun(_capture@1) ->
{failed_to_delete_directory,
Directory_path,
_capture@1}
end
),
fun(_use0) ->
nil = _use0,
case download_package(
Pack,
Package,
Index@1,
Package_count
) of
{ok, none} ->
{ok, {Packages, Index@1}};
{ok, {some, Package@1}} ->
{ok, {[Package@1 | Packages], Index@1}};
{error, Error@1} ->
{error, Error@1}
end
end
);
{error, _} ->
case download_package(Pack, Package, Index@1, Package_count) of
{ok, none} ->
{ok, {Packages, Index@1}};
{ok, {some, Package@2}} ->
{ok, {[Package@2 | Packages], Index@1}};
{error, Error@2} ->
{error, Error@2}
end;
{ok, false} ->
case download_package(Pack, Package, Index@1, Package_count) of
{ok, none} ->
{ok, {Packages, Index@1}};
{ok, {some, Package@2}} ->
{ok, {[Package@2 | Packages], Index@1}};
{error, Error@2} ->
{error, Error@2}
end
end
end
),
case Result of
{error, Error@3} ->
{error, Error@3};
{ok, {Packages@1, _}} ->
{ok, Packages@1}
end.
-file("src/pack.gleam", 534).
?DOC(
" Download packages, returning a dict containing a mapping of package names to\n"
" the files within the package.\n"
).
-spec download(pack()) -> {ok, gleam@dict:dict(binary(), list(file()))} |
{error, error()}.
download(Pack) ->
begin
Result = do_download_packages(Pack),
case Result of
{ok, X} ->
{ok,
begin
log(Pack, <<"Extracting package files..."/utf8>>),
Result@1 = gleam@list:fold(
X,
maps:new(),
fun(Packages, Package) ->
{Name, Files} = Package,
Files@1 = gleam@list:map(
Files,
fun(File) ->
{Name@1, Contents} = File,
case gleam@bit_array:to_string(Contents) of
{error, _} ->
{binary_file, Name@1, Contents};
{ok, Contents@1} ->
{text_file, Name@1, Contents@1}
end
end
),
gleam@dict:insert(Packages, Name, Files@1)
end
),
log(Pack, <<" Done\n"/utf8>>),
Result@1
end};
{error, E} ->
{error, E}
end
end.
-file("src/pack.gleam", 677).
?DOC(" Download packages to disc without returning information about them.\n").
-spec download_to_disc(pack()) -> {ok, nil} | {error, error()}.
download_to_disc(Pack) ->
_pipe = do_download_packages(Pack),
gleam@result:replace(_pipe, nil).
-file("src/pack.gleam", 437).
?DOC(false).
-spec main() -> nil.
main() ->
Arguments = erlang:element(4, argv:load()),
Command = parse_arguments(Arguments),
case Command of
help ->
print_help();
{download, Options} ->
Pack@1 = case load(Options) of
{ok, Pack} -> Pack;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"main"/utf8>>,
line => 445,
value => _assert_fail,
start => 13631,
'end' => 13666,
pattern_start => 13642,
pattern_end => 13650})
end,
case download_to_disc(Pack@1) of
{ok, nil} -> nil;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"main"/utf8>>,
line => 446,
value => _assert_fail@1,
start => 13673,
'end' => 13716,
pattern_start => 13684,
pattern_end => 13691})
end,
nil;
{fetch, Options@1} ->
case load(Options@1) of
{ok, _} -> nil;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"main"/utf8>>,
line => 450,
value => _assert_fail@2,
start => 13764,
'end' => 13796,
pattern_start => 13775,
pattern_end => 13780})
end,
nil;
directory ->
Directory@1 = case pack_directory() of
{ok, Directory} -> Directory;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pack"/utf8>>,
function => <<"main"/utf8>>,
line => 454,
value => _assert_fail@3,
start => 13838,
'end' => 13881,
pattern_start => 13849,
pattern_end => 13862})
end,
gleam_stdlib:println(
<<"Pack files are stored in "/utf8, Directory@1/binary>>
)
end.