Current section
Files
Jump to
Current section
Files
src/libero@cli@new.erl
-module(libero@cli@new).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/libero/cli/new.gleam").
-export([scaffold/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(" `libero new` — scaffold a new Libero project at the given path.\n").
-file("src/libero/cli/new.gleam", 133).
-spec map_err(
{ok, WMJ} | {error, simplifile:file_error()},
fun((WMJ) -> {ok, nil} | {error, binary()})
) -> {ok, nil} | {error, binary()}.
map_err(Result, Next) ->
case Result of
{ok, Value} ->
Next(Value);
{error, Err} ->
{error, simplifile:describe_error(Err)}
end.
-file("src/libero/cli/new.gleam", 85).
-spec scaffold_files(binary(), binary(), binary()) -> {ok, nil} |
{error, binary()}.
scaffold_files(Name, Path, Server_dir) ->
map_err(
simplifile:create_directory_all(Server_dir),
fun(_) ->
map_err(
simplifile:write(
<<Path/binary, "/gleam.toml"/utf8>>,
libero@cli@templates:gleam_toml(Name)
),
fun(_) ->
map_err(
simplifile:write(
<<Server_dir/binary, "/handler.gleam"/utf8>>,
libero@cli@templates:starter_handler()
),
fun(_) ->
map_err(
simplifile:write(
<<Server_dir/binary,
"/shared_state.gleam"/utf8>>,
libero@cli@templates:starter_shared_state()
),
fun(_) ->
map_err(
simplifile:write(
<<Server_dir/binary,
"/app_error.gleam"/utf8>>,
libero@cli@templates:starter_app_error(
)
),
fun(_) ->
Shared_dir = <<Path/binary,
"/shared/src/shared"/utf8>>,
map_err(
simplifile:create_directory_all(
Shared_dir
),
fun(_) ->
map_err(
simplifile:write(
<<Path/binary,
"/shared/gleam.toml"/utf8>>,
libero@cli@templates:shared_gleam_toml(
)
),
fun(_) ->
map_err(
simplifile:write(
<<Shared_dir/binary,
"/messages.gleam"/utf8>>,
libero@cli@templates:starter_messages(
)
),
fun(_) ->
Test_dir = <<Path/binary,
"/test"/utf8>>,
map_err(
simplifile:create_directory_all(
Test_dir
),
fun(_) ->
map_err(
simplifile:write(
<<<<<<Test_dir/binary,
"/"/utf8>>/binary,
Name/binary>>/binary,
"_test.gleam"/utf8>>,
libero@cli@templates:starter_test(
)
),
fun(
_
) ->
{ok,
nil}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/libero/cli/new.gleam", 30).
-spec scaffold_validated(binary(), binary()) -> {ok, nil} | {error, binary()}.
scaffold_validated(Name, Path) ->
case simplifile_erl:is_file(<<Path/binary, "/gleam.toml"/utf8>>) of
{ok, true} ->
{error,
<<<<"project already exists at "/utf8, Path/binary>>/binary,
" (gleam.toml found)"/utf8>>};
_ ->
Server_dir = <<Path/binary, "/src/server"/utf8>>,
scaffold_files(Name, Path, Server_dir)
end.
-file("src/libero/cli/new.gleam", 76).
-spec is_lowercase_letter(binary()) -> boolean().
is_lowercase_letter(Ch) ->
gleam_stdlib:contains_string(<<"abcdefghijklmnopqrstuvwxyz"/utf8>>, Ch).
-file("src/libero/cli/new.gleam", 80).
-spec is_digit(binary()) -> boolean().
is_digit(Ch) ->
gleam_stdlib:contains_string(<<"0123456789"/utf8>>, Ch).
-file("src/libero/cli/new.gleam", 46).
-spec validate_name(binary()) -> {ok, nil} | {error, binary()}.
validate_name(Name) ->
case gleam@string:to_graphemes(Name) of
[] ->
{error, <<"project name cannot be empty"/utf8>>};
[First | Rest] ->
case is_lowercase_letter(First) of
false ->
{error,
<<"project name must start with a lowercase letter, got: "/utf8,
Name/binary>>};
true ->
case gleam@list:all(
Rest,
fun(Ch) ->
(is_lowercase_letter(Ch) orelse is_digit(Ch)) orelse (Ch
=:= <<"_"/utf8>>)
end
) of
false ->
{error,
<<"project name must contain only lowercase letters, digits, and underscores, got: "/utf8,
Name/binary>>};
true ->
{ok, nil}
end
end
end.
-file("src/libero/cli/new.gleam", 17).
?DOC(
" Scaffold a new project under `path`.\n"
"\n"
" The project name is derived from the last segment of the path\n"
" (e.g. \"tmp/test_app\" → \"test_app\").\n"
"\n"
" Creates the directory tree and writes starter source files so the\n"
" project compiles and runs out of the box.\n"
" nolint: stringly_typed_error -- CLI module, String errors are user-facing messages\n"
).
-spec scaffold(binary(), binary()) -> {ok, nil} | {error, binary()}.
scaffold(_, Path) ->
Name = begin
_pipe = gleam@string:split(Path, <<"/"/utf8>>),
_pipe@1 = gleam@list:last(_pipe),
gleam@result:unwrap(_pipe@1, Path)
end,
case validate_name(Name) of
{error, Msg} ->
{error, Msg};
{ok, nil} ->
scaffold_validated(Name, Path)
end.