Current section
Files
Jump to
Current section
Files
src/embeds@files.erl
-module(embeds@files).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([default_filter/2, generate/1, get_files/1, main/0]).
-export_type([options/0, source/0, flatten/0]).
-type options() :: {options,
list(source()),
binary(),
fun((binary(), embeds@generate:data()) -> embeds@generate:code()),
boolean()}.
-type source() :: {source,
binary(),
binary(),
flatten(),
gleam@option:option(integer()),
fun((boolean(), binary()) -> boolean())}.
-type flatten() :: dont_flatten | flatten_all | {flatten_first, integer()}.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 84).
-spec default_filter(boolean(), binary()) -> boolean().
default_filter(_, Path) ->
Is_hidden = begin
_pipe = filepath:base_name(Path),
gleam_stdlib:string_starts_with(_pipe, <<"."/utf8>>)
end,
Is_hidden =:= false.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 416).
-spec do_split_last(list(JJJ), list(JJJ), JJJ) -> {list(JJJ), JJJ}.
do_split_last(List, Init, Last) ->
case List of
[] ->
{lists:reverse(Init), Last};
[First | Rest] ->
do_split_last(Rest, [Last | Init], First)
end.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 409).
-spec split_last(list(JJE)) -> {ok, {list(JJE), JJE}} | {error, nil}.
split_last(List) ->
case List of
[] ->
{error, nil};
[First | List@1] ->
{ok, do_split_last(List@1, [], First)}
end.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 313).
-spec do_get_files(source(), binary(), integer()) -> {ok,
list(embeds@generate:definition())} |
{error, simplifile:file_error()}.
do_get_files(Src, Nested, Depth) ->
gleam@result:'try'(
simplifile_erl:read_directory(
filepath:join(erlang:element(2, Src), Nested)
),
fun(Contents) ->
gleam@list:try_fold(
Contents,
[],
fun(Acc, Content) ->
Relative_path = filepath:join(Nested, Content),
Absolute_path = filepath:join(
erlang:element(2, Src),
Relative_path
),
gleam@result:'try'(
simplifile_erl:file_info(Absolute_path),
fun(Info) ->
File_type = simplifile:file_info_type(Info),
gleam@bool:guard(
not (erlang:element(6, Src))(
File_type =:= directory,
Relative_path
),
{ok, Acc},
fun() ->
case {File_type, erlang:element(5, Src)} of
{file, _} ->
{Module_name, Var_name} = get_file_name(
Src,
Relative_path
),
Definition = {definition,
Absolute_path,
fun() ->
read_file(Absolute_path)
end,
erlang:element(10, Info),
Module_name,
Var_name},
{ok, [Definition | Acc]};
{directory, none} ->
gleam@result:'try'(
do_get_files(
Src,
Relative_path,
Depth + 1
),
fun(Nested_files) ->
{ok,
lists:append(
Acc,
Nested_files
)}
end
);
{directory, {some, Max_depth}} when Depth < Max_depth ->
gleam@result:'try'(
do_get_files(
Src,
Relative_path,
Depth + 1
),
fun(Nested_files@1) ->
{ok,
lists:append(
Acc,
Nested_files@1
)}
end
);
{_, _} ->
{ok, Acc}
end
end
)
end
)
end
)
end
).
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 121).
-spec generate(options()) -> {ok, nil} | {error, list(embeds@generate:error())}.
generate(Options) ->
embeds@generate:guard_gleam_project(
fun() ->
{options, Sources, Header, Print, Force} = Options,
gleam@result:'try'(
(embeds@internal:traverse_map(
Sources,
fun(Spec) -> _pipe = get_files(Spec),
gleam@result:map_error(
_pipe,
fun(E) ->
[{could_not_list_files,
erlang:element(2, Spec),
E}]
end
) end
)),
fun(Defs) ->
embeds@generate:generate(
gleam@list:flatten(Defs),
Header,
Print,
Force
)
end
)
end
).
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 309).
-spec get_files(source()) -> {ok, list(embeds@generate:definition())} |
{error, simplifile:file_error()}.
get_files(Src) ->
do_get_files(Src, <<""/utf8>>, 0).
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 272).
-spec parse_path_spec(
binary(),
flatten(),
gleam@option:option(integer()),
fun((boolean(), binary()) -> boolean())
) -> {ok, source()} | {error, nil}.
parse_path_spec(Spec, Flatten, Max_depth, Filter) ->
case gleam@string:split(Spec, <<":"/utf8>>) of
[Src] ->
gleam@result:map(
filepath:expand(Src),
fun(Src@1) ->
{source,
Src@1,
embeds@generate:to_gleam_module_name(Src@1),
Flatten,
Max_depth,
Filter}
end
);
[Module, Src@2] ->
gleam@result:map(
filepath:expand(Src@2),
fun(Src@3) ->
{source,
Src@3,
embeds@generate:to_gleam_module_name(Module),
Flatten,
Max_depth,
Filter}
end
);
_ ->
{error, nil}
end.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 151).
-spec generate_cmd() -> glint:command(nil).
generate_cmd() ->
glint:command_help(
<<<<<<<<<<<<"Generate Gleam modules containing String/BitArray constants of static files.\n\n\n"/utf8,
"By default, looks for a directory called assets, and generates a Gleam module called assets. The directory structure is preserved in the module structure.\n\n\n"/utf8>>/binary,
"ARGS can be a list of any of the following:\n\n\n"/utf8>>/binary,
"- ./path/to/files:\n\n"/utf8>>/binary,
" List all files in ./path/to/files, generating a Gleam module called `files` (following the directory name).\n\n"/utf8>>/binary,
"- assets:./path/to/files\n\n"/utf8>>/binary,
" Rename the top-level module to `assets`\n\n"/utf8>>,
fun() ->
glint:flag(
begin
_pipe = glint:bool_flag(<<"force"/utf8>>),
_pipe@1 = glint:flag_default(_pipe, false),
glint:flag_help(
_pipe@1,
<<"Do not skip generating based on timestamps"/utf8>>
)
end,
fun(Force) ->
glint:flag(
begin
_pipe@2 = glint:bool_flag(<<"flatten"/utf8>>),
_pipe@3 = glint:flag_default(_pipe@2, false),
glint:flag_help(
_pipe@3,
<<"Do not generate nested modules reflecting the directory tree"/utf8>>
)
end,
fun(Flatten_bool) ->
glint:flag(
begin
_pipe@4 = glint:int_flag(<<"strip"/utf8>>),
_pipe@5 = glint:flag_default(_pipe@4, 0),
glint:flag_help(
_pipe@5,
<<"Like flatten, but only strip the first N levels from the directory tree. If both are given, flatten takes precedence."/utf8>>
)
end,
fun(Flatten_int) ->
glint:flag(
begin
_pipe@6 = glint:int_flag(
<<"max-depth"/utf8>>
),
glint:flag_help(
_pipe@6,
<<"The maximum level of nesting before stopping looking for files."/utf8>>
)
end,
fun(Max_depth) ->
glint:flag(
begin
_pipe@7 = glint:string_flag(
<<"filter"/utf8>>
),
glint:flag_help(
_pipe@7,
<<"A regular expression that needs to match the relative file path."/utf8>>
)
end,
fun(Filter) ->
glint:command(
fun(_, Args, Flags) ->
_assert_subject = Force(
Flags
),
{ok, Force@1} = 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 => <<"embeds/files"/utf8>>,
function => <<"generate_cmd"/utf8>>,
line => 200}
)
end,
_assert_subject@1 = Flatten_bool(
Flags
),
{ok, Flatten_bool@1} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@1,
module => <<"embeds/files"/utf8>>,
function => <<"generate_cmd"/utf8>>,
line => 201}
)
end,
_assert_subject@2 = Flatten_int(
Flags
),
{ok, Flatten_int@1} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail@2,
module => <<"embeds/files"/utf8>>,
function => <<"generate_cmd"/utf8>>,
line => 202}
)
end,
Max_depth@1 = begin
_pipe@8 = Max_depth(
Flags
),
gleam@option:from_result(
_pipe@8
)
end,
Filter@1 = begin
_pipe@9 = Filter(
Flags
),
gleam@option:from_result(
_pipe@9
)
end,
Flatten = case {Flatten_bool@1,
Flatten_int@1} of
{true, _} ->
flatten_all;
{false, 0} ->
dont_flatten;
{false, N} ->
{flatten_first,
N}
end,
Result = (gleam@result:'try'(
case Filter@1 of
{some,
Filter@2} ->
case gleam@regexp:from_string(
Filter@2
) of
{ok,
Regex} ->
{ok,
fun(
Is_dir,
Path
) ->
case {default_filter(
Is_dir,
Path
),
Is_dir} of
{false,
_} ->
false;
{true,
false} ->
gleam@regexp:check(
Regex,
Path
);
{true,
true} ->
true
end
end};
{error,
{compile_error,
Error,
_}} ->
{error,
[{invalid_argument,
<<"filter"/utf8>>,
Filter@2,
Error}]}
end;
none ->
{ok,
fun default_filter/2}
end,
fun(Filter@3) ->
gleam@result:'try'(
case Args of
[] ->
{ok,
[{source,
<<"./assets"/utf8>>,
<<"assets"/utf8>>,
Flatten,
Max_depth@1,
Filter@3}]};
_ ->
embeds@internal:traverse_map(
Args,
fun(
Spec
) ->
_pipe@10 = parse_path_spec(
Spec,
Flatten,
Max_depth@1,
Filter@3
),
gleam@result:replace_error(
_pipe@10,
[{invalid_argument,
<<""/utf8>>,
Spec,
<<"Invalid spec string"/utf8>>}]
)
end
)
end,
fun(
Path_specs
) ->
Options = {options,
Path_specs,
<<"//// Generated by `embeds`, manual edits are futile"/utf8>>,
fun embeds@generate:default_print/2,
Force@1},
generate(
Options
)
end
)
end
)),
case Result of
{ok, nil} ->
nil;
{error, Errs} ->
gleam_stdlib:println_error(
embeds@generate:describe_errors(
Errs
)
)
end,
nil
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 142).
-spec main() -> nil.
main() ->
_pipe = glint:new(),
_pipe@1 = glint:with_name(_pipe, <<"embeds/files"/utf8>>),
_pipe@2 = glint:as_module(_pipe@1),
_pipe@3 = glint:pretty_help(_pipe@2, glint:default_pretty_help()),
_pipe@4 = glint:add(_pipe@3, [], generate_cmd()),
glint:run(_pipe@4, erlang:element(4, argv:load())).
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 367).
-spec read_file(binary()) -> {ok, embeds@generate:data()} | {error, binary()}.
read_file(Path) ->
case simplifile_erl:read_bits(Path) of
{ok, Bits} ->
{ok, embeds@generate:bits_to_data(Bits)};
{error, Err} ->
{error, simplifile:describe_error(Err)}
end.
-file("/home/arkan/Projects/private/embeds/src/embeds/files.gleam", 375).
-spec get_file_name(source(), binary()) -> {binary(), binary()}.
get_file_name(Src, Relative_path) ->
_assert_subject = begin
_pipe = Relative_path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:filter(
_pipe@1,
fun(Part) ->
((Part /= <<""/utf8>>) andalso (Part /= <<"."/utf8>>)) andalso (Part
/= <<".."/utf8>>)
end
),
split_last(_pipe@2)
end,
{ok, {Module_parts, File_name}} = 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 => <<"embeds/files"/utf8>>,
function => <<"get_file_name"/utf8>>,
line => 376})
end,
Var_name = begin
_pipe@3 = File_name,
_pipe@4 = filepath:strip_extension(_pipe@3),
embeds@generate:to_gleam_identifier(_pipe@4)
end,
Module_name = embeds@generate:to_gleam_module_name(
case erlang:element(4, Src) of
flatten_all ->
erlang:element(3, Src);
{flatten_first, N} ->
_pipe@5 = Module_parts,
_pipe@6 = gleam@list:drop(_pipe@5, N),
_pipe@7 = gleam@list:prepend(_pipe@6, erlang:element(3, Src)),
gleam@string:join(_pipe@7, <<"/"/utf8>>);
dont_flatten ->
_pipe@8 = Module_parts,
_pipe@9 = gleam@list:prepend(_pipe@8, erlang:element(3, Src)),
gleam@string:join(_pipe@9, <<"/"/utf8>>)
end
),
{Module_name, Var_name}.