Types
This commit is contained in:
parent
20f27cbcab
commit
eeac89c4c9
141
zx
141
zx
@ -31,7 +31,7 @@
|
||||
|
||||
|
||||
-type state() :: #s{}.
|
||||
-type serial() :: pos_integer().
|
||||
-type serial() :: integer().
|
||||
-type package_id() :: {realm(), name(), version()}.
|
||||
-type package() :: {realm(), name()}.
|
||||
-type realm() :: lower0_9().
|
||||
@ -48,7 +48,7 @@
|
||||
-type key_name() :: label().
|
||||
-type lower0_9() :: [$a..$z | $0..$9 | $_].
|
||||
-type label() :: [$a..$z | $0..$9 | $_ | $- | $.].
|
||||
-type package_meta() :: #{}.
|
||||
-type package_meta() :: map().
|
||||
|
||||
|
||||
|
||||
@ -178,9 +178,10 @@ run(Identifier, Args) ->
|
||||
initialize(Type, PackageID) ->
|
||||
PackageString = package_string(PackageID),
|
||||
ok = log(info, "Initializing ~s...", [PackageString]),
|
||||
Meta = [{package_id, PackageID},
|
||||
{deps, []},
|
||||
{type, Type}],
|
||||
MetaList = [{package_id, PackageID},
|
||||
{deps, []},
|
||||
{type, Type}],
|
||||
Meta = maps:from_list(MetaList),
|
||||
ok = write_meta(Meta),
|
||||
ok = log(info, "Project ~tp initialized.", [PackageString]),
|
||||
Message =
|
||||
@ -312,7 +313,7 @@ ensure_installed(PackageID = {Realm, Name, Version}) ->
|
||||
Name :: name(),
|
||||
Version :: version(),
|
||||
Result :: exact
|
||||
| {ok, version()}
|
||||
| {ok, package_id()}
|
||||
| not_found.
|
||||
%% @private
|
||||
%% Fetch and install the latest compatible version of the given package ID, whether
|
||||
@ -482,7 +483,7 @@ set_version(VersionString) ->
|
||||
|
||||
update_version(Arg) ->
|
||||
Meta = read_meta(),
|
||||
{package_id, PackageID} = lists:keyfind(package_id, 1, Meta),
|
||||
PackageID = maps:get(package_id, Meta),
|
||||
update_version(Arg, PackageID, Meta).
|
||||
|
||||
|
||||
@ -528,7 +529,7 @@ update_version(NewVersion, {Realm, Name, OldVersion}, OldMeta) ->
|
||||
|
||||
update_version(Realm, Name, OldVersion, NewVersion, OldMeta) ->
|
||||
PackageID = {Realm, Name, NewVersion},
|
||||
NewMeta = lists:keystore(package_id, 1, OldMeta, {package_id, PackageID}),
|
||||
NewMeta = maps:put(package_id, PackageID, OldMeta),
|
||||
ok = write_meta(NewMeta),
|
||||
ok = log(info,
|
||||
"Version changed from ~s to ~s.",
|
||||
@ -546,11 +547,11 @@ update_version(Realm, Name, OldVersion, NewVersion, OldMeta) ->
|
||||
drop_dep(PackageID) ->
|
||||
PackageString = package_string(PackageID),
|
||||
Meta = read_meta(),
|
||||
{deps, Deps} = lists:keyfind(deps, 1, Meta),
|
||||
Deps = maps:get(deps, Meta),
|
||||
case lists:member(PackageID, Deps) of
|
||||
true ->
|
||||
NewDeps = lists:delete(PackageID, Deps),
|
||||
NewMeta = lists:keystore(deps, 1, Meta, {deps, NewDeps}),
|
||||
NewMeta = maps:put(deps, NewDeps, Meta),
|
||||
ok = write_meta(NewMeta),
|
||||
Message = "~ts removed from dependencies.",
|
||||
ok = log(info, Message, [PackageString]),
|
||||
@ -660,7 +661,7 @@ execute(#s{type = lib, realm = Realm, name = Name, version = Version}, _) ->
|
||||
package(TargetDir) ->
|
||||
ok = log(info, "Packaging ~ts", [TargetDir]),
|
||||
Meta = read_meta(TargetDir),
|
||||
{package_id, {Realm, _, _}} = lists:keyfind(package_id, 1, Meta),
|
||||
{Realm, _, _} = maps:get(package_id, Meta),
|
||||
KeyDir = filename:join([zomp_dir(), "key", Realm]),
|
||||
ok = force_dir(KeyDir),
|
||||
Pattern = KeyDir ++ "/*.key.der",
|
||||
@ -689,7 +690,7 @@ package(TargetDir) ->
|
||||
|
||||
package(KeyID, TargetDir) ->
|
||||
Meta = read_meta(TargetDir),
|
||||
{package_id, PackageID} = lists:keyfind(package_id, 1, Meta),
|
||||
PackageID = maps:get(package_id, Meta),
|
||||
true = element(1, PackageID) == element(1, KeyID),
|
||||
PackageString = package_string(PackageID),
|
||||
ZrpFile = PackageString ++ ".zrp",
|
||||
@ -710,7 +711,8 @@ package(KeyID, TargetDir) ->
|
||||
{ok, Key} = loadkey(private, KeyID),
|
||||
{ok, TgzBin} = file:read_file(TgzFile),
|
||||
Sig = public_key:sign(TgzBin, sha512, Key),
|
||||
FinalMeta = [{modules, Modules}, {sig, {KeyID, Sig}} | Meta],
|
||||
Add = fun({K, V}, M) -> maps:put(K, V, M) end,
|
||||
FinalMeta = lists:foldl(Add, Meta, [{modules, Modules}, {sig, {KeyID, Sig}}]),
|
||||
ok = file:write_file("zomp.meta", term_to_binary(FinalMeta)),
|
||||
ok = erl_tar:create(ZrpFile, ["zomp.meta", TgzFile]),
|
||||
ok = file:delete(TgzFile),
|
||||
@ -946,7 +948,7 @@ confirm_serial(Realm, Socket, Hosts) ->
|
||||
Socket;
|
||||
{ok, Current} when Current > Serial ->
|
||||
ok = log(info, "Node's serial newer than ours. Storing."),
|
||||
NewSerials = lists:keystore(Realm, 1, Current, Serials),
|
||||
NewSerials = lists:keystore(Realm, 1, Current, {Realm, Serials}),
|
||||
{ok, Host} = inet:peername(Socket),
|
||||
ok = write_terms(hosts_cache_file(Realm), [Host | Hosts]),
|
||||
ok = write_terms(SerialFile, NewSerials),
|
||||
@ -1402,6 +1404,12 @@ dialyze() ->
|
||||
|
||||
%%% Create Realm & Sysop
|
||||
|
||||
-spec create_realm() -> no_return().
|
||||
%% @private
|
||||
%% Prompt the user to input the information necessary to create a new zomp realm,
|
||||
%% package the data appropriately for the server and deliver the final keys and
|
||||
%% realm file to the user.
|
||||
|
||||
create_realm() ->
|
||||
ConfFile = filename:join(zomp_dir(), "zomp.conf"),
|
||||
case file:consult(ConfFile) of
|
||||
@ -1409,6 +1417,10 @@ create_realm() ->
|
||||
{error, enoent} -> create_realm([])
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}].
|
||||
|
||||
create_realm(ZompConf) ->
|
||||
Instructions =
|
||||
"~n"
|
||||
@ -1432,6 +1444,11 @@ create_realm(ZompConf) ->
|
||||
create_realm(ZompConf)
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm().
|
||||
|
||||
create_realm(ZompConf, Realm) ->
|
||||
ExAddress =
|
||||
case lists:keyfind(external_address, 1, ZompConf) of
|
||||
@ -1441,6 +1458,10 @@ create_realm(ZompConf, Realm) ->
|
||||
end,
|
||||
create_realm(ZompConf, Realm, ExAddress).
|
||||
|
||||
|
||||
-spec prompt_external_address() -> Result
|
||||
when Result :: inet:hostname() | inet:ip_address().
|
||||
|
||||
prompt_external_address() ->
|
||||
Message = external_address_prompt(),
|
||||
ok = io:format(Message),
|
||||
@ -1452,6 +1473,11 @@ prompt_external_address() ->
|
||||
parse_address(String)
|
||||
end.
|
||||
|
||||
|
||||
-spec prompt_external_address(Current) -> Result
|
||||
when Current :: inet:hostname() | inet:ip_address(),
|
||||
Result :: inet:hostname() | inet:ip_address().
|
||||
|
||||
prompt_external_address(Current) ->
|
||||
XAString =
|
||||
case inet:ntoa(Current) of
|
||||
@ -1467,6 +1493,9 @@ prompt_external_address(Current) ->
|
||||
String -> parse_address(String)
|
||||
end.
|
||||
|
||||
|
||||
-spec external_address_prompt() -> string().
|
||||
|
||||
external_address_prompt() ->
|
||||
"~n"
|
||||
" Enter a static, valid hostname or IPv4 or IPv6 address at which this host "
|
||||
@ -1474,12 +1503,21 @@ external_address_prompt() ->
|
||||
"need to be reached from the internet).~n"
|
||||
" DO NOT INCLUDE A PORT NUMBER IN THIS STEP~n".
|
||||
|
||||
|
||||
-spec parse_address(string()) -> inet:hostname() | inet:ip_address().
|
||||
|
||||
parse_address(String) ->
|
||||
case inet:parse_address(String) of
|
||||
{ok, Address} -> Address;
|
||||
{error, einval} -> String
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm, ExAddress) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm(),
|
||||
ExAddress :: inet:hostname() | inet:ip_address().
|
||||
|
||||
create_realm(ZompConf, Realm, ExAddress) ->
|
||||
Current =
|
||||
case lists:keyfind(external_port, 1, ZompConf) of
|
||||
@ -1496,6 +1534,13 @@ create_realm(ZompConf, Realm, ExAddress) ->
|
||||
ExPort = prompt_port_number(Current),
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort).
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm, ExAddress, ExPort) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm(),
|
||||
ExAddress :: inet:hostname() | inet:ip_address(),
|
||||
ExPort :: inet:port_number().
|
||||
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort) ->
|
||||
Current =
|
||||
case lists:keyfind(internal_port, 1, ZompConf) of
|
||||
@ -1512,6 +1557,11 @@ create_realm(ZompConf, Realm, ExAddress, ExPort) ->
|
||||
InPort = prompt_port_number(Current),
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort).
|
||||
|
||||
|
||||
-spec prompt_port_number(Current) -> Result
|
||||
when Current :: inet:port_number(),
|
||||
Result :: inet:port_number().
|
||||
|
||||
prompt_port_number(Current) ->
|
||||
Instructions =
|
||||
" A valid port is any number from 1 to 65535."
|
||||
@ -1536,6 +1586,14 @@ prompt_port_number(Current) ->
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm, ExAddress, ExPort, InPort) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm(),
|
||||
ExAddress :: inet:hostname() | inet:ip_address(),
|
||||
ExPort :: inet:port_number(),
|
||||
InPort :: inet:port_number().
|
||||
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort) ->
|
||||
Instructions =
|
||||
"~n"
|
||||
@ -1552,6 +1610,15 @@ create_realm(ZompConf, Realm, ExAddress, ExPort, InPort) ->
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort)
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName) -> no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm(),
|
||||
ExAddress :: inet:hostname() | inet:ip_address(),
|
||||
ExPort :: inet:port_number(),
|
||||
InPort :: inet:port_number(),
|
||||
UserName :: string().
|
||||
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName) ->
|
||||
Instructions =
|
||||
"~n"
|
||||
@ -1579,6 +1646,17 @@ create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName) ->
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName)
|
||||
end.
|
||||
|
||||
|
||||
-spec create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName, Email) ->
|
||||
no_return()
|
||||
when ZompConf :: [{Key :: atom(), Value :: term()}],
|
||||
Realm :: realm(),
|
||||
ExAddress :: inet:hostname() | inet:ip_address(),
|
||||
ExPort :: inet:port_number(),
|
||||
InPort :: inet:port_number(),
|
||||
UserName :: string(),
|
||||
Email :: string().
|
||||
|
||||
create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName, Email) ->
|
||||
Instructions =
|
||||
"~n"
|
||||
@ -1671,6 +1749,8 @@ create_realm(ZompConf, Realm, ExAddress, ExPort, InPort, UserName, Email) ->
|
||||
halt(0).
|
||||
|
||||
|
||||
-spec create_sysop() -> no_return().
|
||||
|
||||
create_sysop() ->
|
||||
ok = log(info, "Fo' realz, yo! We be sysoppin up in hurr!"),
|
||||
halt(0).
|
||||
@ -1749,9 +1829,9 @@ verify(Data, Signature, PubKey) ->
|
||||
%% Download a package to the local cache.
|
||||
|
||||
fetch(Socket, PackageID) ->
|
||||
ok = request_zrp(Socket, PackageID),
|
||||
ok = receive_zrp(Socket, PackageID),
|
||||
log(info, "Fetched ~ts", [package_string(PackageID)]).
|
||||
{ok, LatestID} = request_zrp(Socket, PackageID),
|
||||
ok = receive_zrp(Socket, LatestID),
|
||||
log(info, "Fetched ~ts", [package_string(LatestID)]).
|
||||
|
||||
|
||||
request_zrp(Socket, PackageID) ->
|
||||
@ -2183,33 +2263,6 @@ hurr() -> io:format("That isn't an option.~n").
|
||||
|
||||
%%% Directory & File Management
|
||||
|
||||
%-spec move_file(From, To) -> Result
|
||||
% when From :: file:filename(),
|
||||
% To :: file:filename(),
|
||||
% Result :: ok
|
||||
% | {error, Reason},
|
||||
% Reason :: bad_source
|
||||
% | destination_exists
|
||||
% | file:posix().
|
||||
%%% @private
|
||||
%%% Utility function to safely copy a file From one path To another without clobbering the
|
||||
%%% destination in the event it already exists. Both the source and the destination must be
|
||||
%%% complete filenames, not directories.
|
||||
%
|
||||
%move_file(From, To) ->
|
||||
% case {filelib:is_regular(From), filelib:is_file(To)} of
|
||||
% {false, false} ->
|
||||
% case file:copy(From, To) of
|
||||
% {ok, _} -> file:delete(From);
|
||||
% Error -> Error
|
||||
% end;
|
||||
% {true, _} ->
|
||||
% {error, bad_source};
|
||||
% {false, true} ->
|
||||
% {error, destination_exists}
|
||||
% end.
|
||||
|
||||
|
||||
-spec ensure_zomp_home() -> ok.
|
||||
%% @private
|
||||
%% Ensure the zomp home directory exists and is populated.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user