Current section

Files

Jump to
cosmo_cli src cosmo_cli.erl
Raw

src/cosmo_cli.erl

-module(cosmo_cli).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new_flag_int/2, new_flag_string/2, new_flag_bool/2, with_flag_short/1, with_flag_description/1, with_flag_default_int/1, with_flag_default_string/1, with_flag_default_bool/1, new_command/3, get_flag_int/2, get_flag_string/2, get_flag_bool/2, with_command_short/1, with_command_long/1, with_command_sub_commands/1, with_command_flags/1, main/0, run/2, run_with_argv/1]).
-export_type([flag/0, command/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.
-opaque flag() :: {flag_int,
gleam@option:option(binary()),
binary(),
gleam@option:option(binary()),
integer()} |
{flag_string,
gleam@option:option(binary()),
binary(),
gleam@option:option(binary()),
binary()} |
{flag_bool,
gleam@option:option(binary()),
binary(),
gleam@option:option(binary()),
boolean()}.
-opaque command() :: {command,
binary(),
gleam@option:option(binary()),
gleam@option:option(binary()),
fun((command()) -> {ok, nil} | {error, binary()}),
gleam@dict:dict(binary(), command()),
list(flag())}.
-file("src/cosmo_cli.gleam", 34).
-spec find_flag(binary()) -> fun((flag()) -> boolean()).
find_flag(Flag_name) ->
fun(Flag) -> case Flag of
{flag_int, Short, Long, _, _} ->
case Long =:= Flag_name of
true ->
true;
false ->
case Short of
{some, Short@1} ->
Short@1 =:= Flag_name;
none ->
false
end
end;
{flag_string, Short@2, Long@1, _, _} ->
case Long@1 =:= Flag_name of
true ->
true;
false ->
case Short@2 of
{some, Short@3} ->
Short@3 =:= Flag_name;
none ->
false
end
end;
{flag_bool, Short@4, Long@2, _, _} ->
case Long@2 =:= Flag_name of
true ->
true;
false ->
case Short@4 of
{some, Short@5} ->
Short@5 =:= Flag_name;
none ->
false
end
end
end end.
-file("src/cosmo_cli.gleam", 69).
?DOC(" new_flag_int creates a new int flag with the given long name and options.\n").
-spec new_flag_int(binary(), list(fun((flag()) -> flag()))) -> flag().
new_flag_int(Long_name, Option_fns) ->
Flag = {flag_int, none, Long_name, none, 0},
gleam@list:fold(
Option_fns,
Flag,
fun(Flag@1, Option_fn) -> Option_fn(Flag@1) end
).
-file("src/cosmo_cli.gleam", 79).
?DOC(" new_flag_string creates a new string flag with the given long name and options.\n").
-spec new_flag_string(binary(), list(fun((flag()) -> flag()))) -> flag().
new_flag_string(Long_name, Option_fns) ->
Flag = {flag_string, none, Long_name, none, <<""/utf8>>},
gleam@list:fold(
Option_fns,
Flag,
fun(Flag@1, Option_fn) -> Option_fn(Flag@1) end
).
-file("src/cosmo_cli.gleam", 90).
?DOC(" new_flag_bool creates a new boolean flag with the given long name and options.\n").
-spec new_flag_bool(binary(), list(fun((flag()) -> flag()))) -> flag().
new_flag_bool(Long_name, Option_fns) ->
Flag = {flag_bool, none, Long_name, none, false},
gleam@list:fold(
Option_fns,
Flag,
fun(Flag@1, Option_fn) -> Option_fn(Flag@1) end
).
-file("src/cosmo_cli.gleam", 101).
?DOC(" with_flag_long sets the long name for a flag.\n").
-spec with_flag_short(binary()) -> fun((flag()) -> flag()).
with_flag_short(Short) ->
fun(Flag) -> case Flag of
{flag_int, _, _, _, _} ->
_record = Flag,
{flag_int,
{some, Short},
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record)};
{flag_string, _, _, _, _} ->
_record@1 = Flag,
{flag_string,
{some, Short},
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1)};
{flag_bool, _, _, _, _} ->
_record@2 = Flag,
{flag_bool,
{some, Short},
erlang:element(3, _record@2),
erlang:element(4, _record@2),
erlang:element(5, _record@2)}
end end.
-file("src/cosmo_cli.gleam", 112).
?DOC(" with_flag_description sets the description for a flag.\n").
-spec with_flag_description(binary()) -> fun((flag()) -> flag()).
with_flag_description(Description) ->
fun(Flag) -> case Flag of
{flag_int, _, _, _, _} ->
_record = Flag,
{flag_int,
erlang:element(2, _record),
erlang:element(3, _record),
{some, Description},
erlang:element(5, _record)};
{flag_string, _, _, _, _} ->
_record@1 = Flag,
{flag_string,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
{some, Description},
erlang:element(5, _record@1)};
{flag_bool, _, _, _, _} ->
_record@2 = Flag,
{flag_bool,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
{some, Description},
erlang:element(5, _record@2)}
end end.
-file("src/cosmo_cli.gleam", 123).
?DOC(" with_flag_default_int sets the default value for an int flag.\n").
-spec with_flag_default_int(integer()) -> fun((flag()) -> flag()).
with_flag_default_int(Default) ->
fun(Flag) -> case Flag of
{flag_int, _, _, _, _} ->
_record = Flag,
{flag_int,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
Default};
{flag_string, _, _, _, _} ->
Flag;
{flag_bool, _, _, _, _} ->
Flag
end end.
-file("src/cosmo_cli.gleam", 134).
?DOC(" with_flag_default_string sets the default value for a string flag.\n").
-spec with_flag_default_string(binary()) -> fun((flag()) -> flag()).
with_flag_default_string(Default) ->
fun(Flag) -> case Flag of
{flag_int, _, _, _, _} ->
Flag;
{flag_string, _, _, _, _} ->
_record = Flag,
{flag_string,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
Default};
{flag_bool, _, _, _, _} ->
Flag
end end.
-file("src/cosmo_cli.gleam", 145).
?DOC(" with_flag_default_bool sets the default value for a boolean flag.\n").
-spec with_flag_default_bool(boolean()) -> fun((flag()) -> flag()).
with_flag_default_bool(Default) ->
fun(Flag) -> case Flag of
{flag_int, _, _, _, _} ->
Flag;
{flag_string, _, _, _, _} ->
Flag;
{flag_bool, _, _, _, _} ->
_record = Flag,
{flag_bool,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
Default}
end end.
-file("src/cosmo_cli.gleam", 171).
?DOC(" new_command creates a new command with the given name, run function, and options.\n").
-spec new_command(
binary(),
fun((command()) -> {ok, nil} | {error, binary()}),
list(fun((command()) -> command()))
) -> command().
new_command(Name, Run, Option_fns) ->
Command = {command, Name, none, none, Run, maps:new(), gleam@list:new()},
gleam@list:fold(
Option_fns,
Command,
fun(Command@1, Option_fn) -> Option_fn(Command@1) end
).
-file("src/cosmo_cli.gleam", 190).
?DOC(
" get_flag_int returns the value of an int flag.\n"
" the flag key must be the long name with double-hyphen.\n"
).
-spec get_flag_int(command(), binary()) -> {ok, integer()} | {error, binary()}.
get_flag_int(Command, Flag_name) ->
case gleam@list:find(erlang:element(7, Command), find_flag(Flag_name)) of
{ok, Flag} ->
case Flag of
{flag_int, _, _, _, Value} ->
{ok, Value};
{flag_string, _, _, _, _} ->
{error, <<"Flag is not an int"/utf8>>};
{flag_bool, _, _, _, _} ->
{error, <<"Flag is not an int"/utf8>>}
end;
{error, _} ->
{error, <<"Flag not found"/utf8>>}
end.
-file("src/cosmo_cli.gleam", 204).
?DOC(
" get_flag_string returns the value of a string flag.\n"
" the flag key must be the long name with double-hyphen.\n"
).
-spec get_flag_string(command(), binary()) -> {ok, binary()} | {error, binary()}.
get_flag_string(Command, Flag_name) ->
case gleam@list:find(erlang:element(7, Command), find_flag(Flag_name)) of
{ok, Flag} ->
case Flag of
{flag_int, _, _, _, _} ->
{error, <<"Flag is not a string"/utf8>>};
{flag_string, _, _, _, Value} ->
{ok, Value};
{flag_bool, _, _, _, _} ->
{error, <<"Flag is not a string"/utf8>>}
end;
{error, _} ->
{error, <<"Flag not found"/utf8>>}
end.
-file("src/cosmo_cli.gleam", 221).
?DOC(
" get_flag_bool returns the value of a boolean flag.\n"
" the flag key must be the long name with double-hyphen.\n"
).
-spec get_flag_bool(command(), binary()) -> {ok, boolean()} | {error, binary()}.
get_flag_bool(Command, Flag_name) ->
case gleam@list:find(erlang:element(7, Command), find_flag(Flag_name)) of
{ok, Flag} ->
case Flag of
{flag_int, _, _, _, _} ->
{error, <<"Flag is not a boolean"/utf8>>};
{flag_string, _, _, _, _} ->
{error, <<"Flag is not a boolean"/utf8>>};
{flag_bool, _, _, _, Value} ->
{ok, Value}
end;
{error, _} ->
{error, <<"Flag not found"/utf8>>}
end.
-file("src/cosmo_cli.gleam", 237).
?DOC(" with_command_short sets the short description for a command.\n").
-spec with_command_short(binary()) -> fun((command()) -> command()).
with_command_short(Short) ->
fun(Command) -> _record = Command,
{command,
erlang:element(2, _record),
{some, Short},
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record)} end.
-file("src/cosmo_cli.gleam", 242).
?DOC(" with_command_long sets the long description for a command.\n").
-spec with_command_long(binary()) -> fun((command()) -> command()).
with_command_long(Long) ->
fun(Command) -> _record = Command,
{command,
erlang:element(2, _record),
erlang:element(3, _record),
{some, Long},
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record)} end.
-file("src/cosmo_cli.gleam", 247).
?DOC(" with_command_run sets the run function for a command.\n").
-spec with_command_sub_commands(gleam@dict:dict(binary(), command())) -> fun((command()) -> command()).
with_command_sub_commands(Sub_commands) ->
fun(Command) ->
Sub_commands@1 = maps:merge(erlang:element(6, Command), Sub_commands),
_record = Command,
{command,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
Sub_commands@1,
erlang:element(7, _record)}
end.
-file("src/cosmo_cli.gleam", 257).
?DOC(" with_command_sub_commands sets the sub commands for a command.\n").
-spec with_command_flags(list(flag())) -> fun((command()) -> command()).
with_command_flags(Flags) ->
fun(Command) -> _record = Command,
{command,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
Flags} end.
-file("src/cosmo_cli.gleam", 362).
-spec main() -> nil.
main() ->
gleam_stdlib:println(<<"Hello from cosmo_cli!"/utf8>>).
-file("src/cosmo_cli.gleam", 320).
-spec run_command(command(), list(binary())) -> {ok, nil} | {error, binary()}.
run_command(Command, Args) ->
case Args of
[] ->
(erlang:element(5, Command))(Command);
[First | _] ->
gleam_stdlib:println(<<"First: "/utf8, First/binary>>),
case gleam@list:find(erlang:element(7, Command), find_flag(First)) of
{ok, Flag} ->
parse_flag_and_run(Command, First, Flag, Args);
{error, _} ->
case gleam_stdlib:map_get(erlang:element(6, Command), First) of
{ok, Sub_command} ->
Sub_args = gleam@list:drop(Args, 1),
run_command(Sub_command, Sub_args);
{error, _} ->
{error,
<<<<"Command "/utf8, First/binary>>/binary,
" not found"/utf8>>}
end
end
end.
-file("src/cosmo_cli.gleam", 261).
-spec parse_flag_and_run(command(), binary(), flag(), list(binary())) -> {ok,
nil} |
{error, binary()}.
parse_flag_and_run(Command, Flag_name, Flag, Args) ->
Sub_args = gleam@list:drop(Args, 1),
case {Flag, Sub_args} of
{{flag_int, _, _, _, _}, []} ->
{error,
<<<<"Flag "/utf8, Flag_name/binary>>/binary,
" requires a value because it is an int"/utf8>>};
{{flag_string, _, _, _, _}, []} ->
{error,
<<<<"Flag "/utf8, Flag_name/binary>>/binary,
" requires a value because it is a string"/utf8>>};
{{flag_bool, _, _, _, _}, _} ->
Updated_flag = begin
_record = Flag,
{flag_bool,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
true}
end,
Updated_command = begin
_record@1 = Command,
{command,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
cosmo_cli@list_wrapper:replace_by(
erlang:element(7, Command),
find_flag(Flag_name),
Updated_flag
)}
end,
run_command(Updated_command, Sub_args);
{{flag_string, _, _, _, _}, [Value | Tail]} ->
Updated_flag@1 = begin
_record@2 = Flag,
{flag_string,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
erlang:element(4, _record@2),
Value}
end,
Updated_command@1 = begin
_record@3 = Command,
{command,
erlang:element(2, _record@3),
erlang:element(3, _record@3),
erlang:element(4, _record@3),
erlang:element(5, _record@3),
erlang:element(6, _record@3),
cosmo_cli@list_wrapper:replace_by(
erlang:element(7, Command),
find_flag(Flag_name),
Updated_flag@1
)}
end,
run_command(Updated_command@1, Tail);
{{flag_int, _, _, _, _}, [Value@1 | Tail@1]} ->
case gleam_stdlib:parse_int(Value@1) of
{ok, Value@2} ->
Updated_flag@2 = begin
_record@4 = Flag,
{flag_int,
erlang:element(2, _record@4),
erlang:element(3, _record@4),
erlang:element(4, _record@4),
Value@2}
end,
Updated_command@2 = begin
_record@5 = Command,
{command,
erlang:element(2, _record@5),
erlang:element(3, _record@5),
erlang:element(4, _record@5),
erlang:element(5, _record@5),
erlang:element(6, _record@5),
cosmo_cli@list_wrapper:replace_by(
erlang:element(7, Command),
find_flag(Flag_name),
Updated_flag@2
)}
end,
run_command(Updated_command@2, Tail@1);
{error, _} ->
{error,
<<<<"Flag "/utf8, Flag_name/binary>>/binary,
" requires a valid int value"/utf8>>}
end
end.
-file("src/cosmo_cli.gleam", 345).
?DOC(
" run executes the root command with the given arguments.\n"
" It can be called with os argv that has the command name as the first argument.\n"
).
-spec run(command(), list(binary())) -> {ok, nil} | {error, binary()}.
run(Command, Args) ->
case Args of
[] ->
{error, <<"No command provided"/utf8>>};
[_ | Rest] ->
run_command(Command, Rest)
end.
-file("src/cosmo_cli.gleam", 357).
-spec run_with_argv(command()) -> {ok, nil} | {error, binary()}.
run_with_argv(Command) ->
Argv_all = argv:load(),
run(Command, [erlang:element(3, Argv_all) | erlang:element(4, Argv_all)]).