Proto 0.2.1
This commit is contained in:
parent
0b52119b3d
commit
2508b17637
@ -1 +1 @@
|
||||
0.2.0
|
||||
0.2.1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{application,zx,
|
||||
[{description,"Zomp client program"},
|
||||
{vsn,"0.2.0"},
|
||||
{vsn,"0.2.1"},
|
||||
{applications,[stdlib,kernel]},
|
||||
{modules,[zx,zx_auth,zx_conn,zx_conn_sup,zx_daemon,zx_key,
|
||||
zx_lib,zx_local,zx_net,zx_peer,zx_peer_man,
|
||||
@ -24,7 +24,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(application).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -42,7 +42,7 @@
|
||||
key_data/0, key_bin/0, key_id/0, key_name/0,
|
||||
user_id/0, user_name/0, contact_info/0, user_data/0,
|
||||
lower0_9/0, label/0,
|
||||
package_meta/0, ss_tag/0, search_tag/0,
|
||||
package_meta/0, ss_tag/0, search_tag/0, description/0, package_type/0,
|
||||
outcome/0]).
|
||||
|
||||
-include("zx_logger.hrl").
|
||||
@ -78,12 +78,33 @@
|
||||
-type lower0_9() :: [$a..$z | $0..$9 | $_].
|
||||
-type label() :: [$a..$z | $0..$9 | $_ | $- | $.].
|
||||
-type package_meta() :: #{package_id := package_id(),
|
||||
search_tags := [search_tag()],
|
||||
name := string(),
|
||||
desc := string(),
|
||||
author := string(),
|
||||
a_email := string(),
|
||||
copyright := string(),
|
||||
c_email := string(),
|
||||
ws_url := string(),
|
||||
repo_url := string(),
|
||||
prefix := string(),
|
||||
tags := [search_tag()],
|
||||
deps := [package_id()],
|
||||
type := app | lib}.
|
||||
type := package_type()}.
|
||||
-type ss_tag() :: {serial(), calendar:timestamp()}.
|
||||
-type search_tag() :: string().
|
||||
|
||||
-type description() :: {description,
|
||||
PackageID :: package_id(),
|
||||
DisplayName :: string(),
|
||||
Type :: package_type(),
|
||||
Desc :: string(),
|
||||
Author :: string(),
|
||||
AEmail :: string(),
|
||||
WebURL :: string(),
|
||||
RepoURL :: string(),
|
||||
Tags :: [zx:search_tag()]}.
|
||||
-type package_type() :: app | lib | gui | cli.
|
||||
|
||||
-type outcome() :: ok
|
||||
| {error, Reason :: term()}
|
||||
| {error, Code :: non_neg_integer()}
|
||||
@ -114,6 +135,8 @@ do(["help", "dev"]) ->
|
||||
done(help(dev));
|
||||
do(["help", "sysop"]) ->
|
||||
done(help(sysop));
|
||||
do(["--version"]) ->
|
||||
done(version());
|
||||
do(["run", PackageString | ArgV]) ->
|
||||
ok = zx_daemon:connect(),
|
||||
not_done(run(PackageString, ArgV));
|
||||
@ -128,6 +151,9 @@ do(["list", "versions", PackageName]) ->
|
||||
do(["latest", PackageString]) ->
|
||||
ok = zx_daemon:connect(),
|
||||
done(zx_local:latest(PackageString));
|
||||
do(["describe", PackageString]) ->
|
||||
ok = zx_daemon:connect(),
|
||||
done(zx_local:describe(PackageString));
|
||||
do(["upgrade"]) ->
|
||||
ok = zx_daemon:connect(),
|
||||
done(upgrade());
|
||||
@ -185,6 +211,8 @@ do(["set", "version", VersionString]) ->
|
||||
do(["provides", Module]) ->
|
||||
ok = zx_daemon:connect(),
|
||||
done(zx_local:provides(Module));
|
||||
do(["update", "meta"]) ->
|
||||
done(zx_local:update_meta());
|
||||
do(["update", ".app"]) ->
|
||||
done(zx_local:update_app_file());
|
||||
do(["package"]) ->
|
||||
@ -481,7 +509,7 @@ list() ->
|
||||
|
||||
list(Realm) ->
|
||||
{ok, ID} = zx_daemon:list(Realm),
|
||||
wait_result(ID).
|
||||
zx_daemon:wait_result(ID).
|
||||
|
||||
|
||||
-spec list(realm(), name()) -> Result
|
||||
@ -507,7 +535,7 @@ list(Realm, Name) ->
|
||||
|
||||
list(Realm, Name, Version) ->
|
||||
{ok, ID} = zx_daemon:list(Realm, Name, Version),
|
||||
wait_result(ID).
|
||||
zx_daemon:wait_result(ID).
|
||||
|
||||
|
||||
-spec latest(package_id()) -> Result
|
||||
@ -521,7 +549,7 @@ list(Realm, Name, Version) ->
|
||||
|
||||
latest(PackageID) ->
|
||||
{ok, ID} = zx_daemon:latest(PackageID),
|
||||
wait_result(ID).
|
||||
zx_daemon:wait_result(ID).
|
||||
|
||||
|
||||
|
||||
@ -620,7 +648,7 @@ resolve_version(PackageID = {_, _, {X, Y, Z}})
|
||||
end;
|
||||
resolve_version(PackageID = {Realm, Name, _}) ->
|
||||
{ok, ID} = zx_daemon:latest(PackageID),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Latest} -> resolve_version({Realm, Name, Latest});
|
||||
Error -> Error
|
||||
end.
|
||||
@ -722,7 +750,7 @@ upgrade() ->
|
||||
{ok, PackageString} = zx_lib:package_string(PackageID),
|
||||
ok = tell("Current version: ~s~n", [PackageString]),
|
||||
{ok, ID} = zx_daemon:latest({Realm, Name}),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Current} ->
|
||||
tell("Running latest version.~n");
|
||||
{ok, Latest} when Latest > Current ->
|
||||
@ -812,13 +840,6 @@ ensure_all_started(AppMod) ->
|
||||
end.
|
||||
|
||||
|
||||
wait_result(ID) ->
|
||||
receive
|
||||
{result, ID, Result} -> Result
|
||||
after 5000 -> {error, timeout}
|
||||
end.
|
||||
|
||||
|
||||
|
||||
%%% Usage
|
||||
|
||||
@ -849,6 +870,7 @@ usage_user() ->
|
||||
" zx list packages Realm~n"
|
||||
" zx list versions PackageID~n"
|
||||
" zx latest PackageID~n"
|
||||
" zx describe Package~n"
|
||||
" zx upgrade~n"
|
||||
" zx import realm RealmFile~n"
|
||||
" zx drop realm Realm~n"
|
||||
@ -869,6 +891,7 @@ usage_dev() ->
|
||||
" zx verup Level~n"
|
||||
" zx set version Version~n"
|
||||
" zx provides Module~n"
|
||||
" zx update meta~n"
|
||||
" zx update .app~n"
|
||||
" zx package [Path]~n"
|
||||
" zx submit ZSP~n"
|
||||
@ -922,3 +945,7 @@ usage_spec() ->
|
||||
" ZSP :: Path to a .zsp file (Zomp Source Package).~n"
|
||||
" ZPUF :: Path to a .zpuf file (Zomp Public User File).~n"
|
||||
" ZDUF :: Path to a .zduf file (Zomp DANGEROUS User File).~n".
|
||||
|
||||
|
||||
version() ->
|
||||
io:format("zx ~ts~n", [os:getenv("ZX_VERSION")]).
|
||||
@ -9,7 +9,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_auth).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -7,7 +7,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_conn).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -5,7 +5,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_conn_sup).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(supervisor).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -138,7 +138,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_daemon).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(gen_server).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -148,9 +148,10 @@
|
||||
-export([pass_meta/3, argv/0,
|
||||
subscribe/1, unsubscribe/1,
|
||||
list/0, list/1, list/2, list/3, latest/1,
|
||||
provides/2, list_deps/1,
|
||||
describe/1, provides/2, list_deps/1,
|
||||
list_sysops/1,
|
||||
fetch/1, install/1, build/1]).
|
||||
fetch/1, install/1, build/1,
|
||||
wait_result/1, wait_results/1]).
|
||||
-export([register_key/2, get_key/2, keybin/2,
|
||||
find_keypair/1, have_key/2, list_keys/2]).
|
||||
-export([report/1, result/2, notify/2]).
|
||||
@ -271,6 +272,7 @@
|
||||
| {list, zx:realm(), zx:name(), zx:version()}
|
||||
| {latest, zx:realm(), zx:name()}
|
||||
| {latest, zx:realm(), zx:name(), zx:version()}
|
||||
| {describe, zx:realm(), zx:name()}
|
||||
| {provides, zx:realm(), string()}
|
||||
| {list_deps, zx:realm(), zx:name(), zx:version()}
|
||||
| {list_sysops, zx:realm()}
|
||||
@ -292,6 +294,7 @@
|
||||
| package_list()
|
||||
| version_list()
|
||||
| latest_result()
|
||||
| desc_result()
|
||||
| fetch_result()
|
||||
| key_result()}.
|
||||
|
||||
@ -308,6 +311,11 @@
|
||||
| bad_package
|
||||
| bad_version
|
||||
| timeout}.
|
||||
-type desc_result() :: {ok, zx:description()}
|
||||
| {error, bad_realm
|
||||
| bad_package
|
||||
| bad_version
|
||||
| timeout}.
|
||||
-type fetch_result() :: {hops, non_neg_integer()}
|
||||
| {done, zx:package_id()}
|
||||
| {error, bad_realm
|
||||
@ -473,6 +481,14 @@ latest({Realm, Name, Version}) ->
|
||||
request({latest, Realm, Name, Version}).
|
||||
|
||||
|
||||
-spec describe(Package) -> {ok, RequestID}
|
||||
when Package :: zx:package(),
|
||||
RequestID :: integer().
|
||||
|
||||
describe({Realm, Name}) ->
|
||||
request({describe, Realm, Name}).
|
||||
|
||||
|
||||
-spec provides(Realm, Module) -> {ok, RequestID}
|
||||
when Realm :: zx:realm(),
|
||||
Module :: string(),
|
||||
@ -521,6 +537,59 @@ build(PackageID) ->
|
||||
gen_server:call(?MODULE, {build, PackageID}).
|
||||
|
||||
|
||||
-spec wait_result(ID) -> Result
|
||||
when ID :: id(),
|
||||
Result :: {ok, term()}
|
||||
| {error, Reason},
|
||||
Reason :: bad_realm
|
||||
| bad_package
|
||||
| bad_version
|
||||
| timeout
|
||||
| network
|
||||
| {unexpected, Message :: string()}.
|
||||
|
||||
wait_result(ID) ->
|
||||
receive
|
||||
{result, ID, Result} -> Result;
|
||||
Message -> {error, {unexpected, Message}}
|
||||
after 5000 -> {error, timeout}
|
||||
end.
|
||||
|
||||
|
||||
-spec wait_results(IDs) -> Outcome
|
||||
when IDs :: [id()],
|
||||
Outcome :: {ok, [Result]}
|
||||
| {error, Unexpected, [Result]}
|
||||
| {error, Reason},
|
||||
Result :: {id(), term()},
|
||||
Unexpected :: {unexpected, {result, id(), term()}},
|
||||
Reason :: bad_realm
|
||||
| bad_package
|
||||
| bad_version
|
||||
| timeout
|
||||
| network
|
||||
| {unexpected, Message :: string()}.
|
||||
|
||||
|
||||
wait_results(IDs) ->
|
||||
wait_results(IDs, []).
|
||||
|
||||
wait_results([], Results) ->
|
||||
{ok, Results};
|
||||
wait_results(IDs, Results) ->
|
||||
receive
|
||||
{result, ID, Result} ->
|
||||
case lists:member(ID, IDs) of
|
||||
true -> wait_results(lists:delete(ID, IDs), [{ID, Result} | Results]);
|
||||
false -> {error, {unexpected, {result, ID, Result}}, Results}
|
||||
end;
|
||||
Message ->
|
||||
{error, {unexpected, Message}}
|
||||
after 5000 ->
|
||||
{error, timeout}
|
||||
end.
|
||||
|
||||
|
||||
-spec add_mirror(zx:host()) -> ok.
|
||||
|
||||
add_mirror(Host) ->
|
||||
@ -1304,6 +1373,7 @@ local_request(R, {list, N}) -> zomp_realm:list(R, N);
|
||||
local_request(R, {list, N, V}) -> zomp_realm:list(R, {N, V});
|
||||
local_request(R, {latest, N}) -> zomp_realm:latest(R, N);
|
||||
local_request(R, {latest, N, V}) -> zomp_realm:latest(R, {N, V});
|
||||
local_request(R, {describe, N}) -> zomp_realm:describe(R, N);
|
||||
local_request(R, {provides, M}) -> zomp_realm:provides(R, M);
|
||||
local_request(R, {list_deps, N, V}) -> zomp_realm:list_deps(R, {N, V});
|
||||
local_request(R, {list_sysops}) -> zomp_realm:list_sysops(R).
|
||||
@ -8,7 +8,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_key).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -10,7 +10,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_lib).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -6,25 +6,27 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_local).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
|
||||
-export([initialize/0, set_version/1,
|
||||
list_realms/0, list_packages/1, list_versions/1,
|
||||
latest/1, provides/1,
|
||||
latest/1, describe/1, provides/1,
|
||||
list_keys/0, list_sysops/1,
|
||||
set_dep/1, list_deps/0, list_deps/1, drop_dep/1, verup/1, package/1,
|
||||
update_app_file/0,
|
||||
update_meta/0, update_app_file/0,
|
||||
import_realm/1, drop_realm/1, logpath/2,
|
||||
set_timeout/1, add_mirror/0, drop_mirror/0,
|
||||
set_timeout/1,
|
||||
add_mirror/0, add_mirror/1, add_mirror/2,
|
||||
drop_mirror/0, drop_mirror/1, drop_mirror/2,
|
||||
create_project/0,
|
||||
grow_a_pair/0, grow_a_pair/2, drop_key/1,
|
||||
create_user/0, create_userfile/0, export_user/0, import_user/1,
|
||||
create_realm/0, create_realmfile/0, create_realmfile/1]).
|
||||
|
||||
-export([select_realm/0, create_user/1, select_private_key/1]).
|
||||
-export([create_user/1, select_private_key/1]).
|
||||
|
||||
-include("zx_logger.hrl").
|
||||
|
||||
@ -50,7 +52,6 @@
|
||||
desc = none :: none | string(),
|
||||
repo_url = none :: none | string(),
|
||||
ws_url = none :: none | string(),
|
||||
url = none :: none | string(),
|
||||
id = none :: none | zx:package_id() | zx:name(),
|
||||
prefix = none :: none | zx:lower0_9(),
|
||||
appmod = none :: none | zx:lower0_9(),
|
||||
@ -59,7 +60,9 @@
|
||||
a_email = none :: none | string(),
|
||||
copyright = none :: none | string(),
|
||||
c_email = none :: none | string(),
|
||||
deps = [] :: [zx:package_id()]}).
|
||||
deps = [] :: [zx:package_id()],
|
||||
tags = [] :: [string()],
|
||||
file_exts = [] :: [string()]}).
|
||||
|
||||
|
||||
|
||||
@ -447,6 +450,170 @@ initialize_app_file({_, Name, Version}, AppMod, Type, Desc) ->
|
||||
zx_lib:write_terms(AppFile, [AppProfile]).
|
||||
|
||||
|
||||
-spec update_meta() -> zx:outcome().
|
||||
|
||||
update_meta() ->
|
||||
case zx_lib:read_project_meta() of
|
||||
{ok, Data} -> update_meta(Data);
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
update_meta(Data = #{package_id := {_, Name, _}}) ->
|
||||
P = #project{name = maps:get(name, Data, Name),
|
||||
author = maps:get(author, Data, ""),
|
||||
a_email = maps:get(a_email, Data, ""),
|
||||
copyright = maps:get(copyright, Data, ""),
|
||||
c_email = maps:get(c_email, Data, ""),
|
||||
repo_url = maps:get(repo_url, Data, ""),
|
||||
ws_url = maps:get(ws_url, Data, ""),
|
||||
desc = maps:get(desc, Data, ""),
|
||||
tags = sets:from_list(maps:get(tags, Data, [])),
|
||||
file_exts = sets:from_list(maps:get(file_exts, Data, []))},
|
||||
update_meta(Data, P).
|
||||
|
||||
update_meta(Data = #{type := gui},
|
||||
P = #project{name = Name,
|
||||
author = Author,
|
||||
a_email = AEmail,
|
||||
copyright = CR,
|
||||
c_email = CEmail,
|
||||
repo_url = RepoURL,
|
||||
ws_url = WebURL,
|
||||
desc = Desc,
|
||||
tags = Tags,
|
||||
file_exts = Exts}) ->
|
||||
Instructions =
|
||||
"~nDESCRIPTION DATA~n"
|
||||
"[ 1] Project Name : ~ts~n"
|
||||
"[ 2] Author : ~ts~n"
|
||||
"[ 3] Author's Email : ~ts~n"
|
||||
"[ 4] Copyright Holder : ~ts~n"
|
||||
"[ 5] Copyright Holder's Email : ~ts~n"
|
||||
"[ 6] Repo URL : ~ts~n"
|
||||
"[ 7] Website URL : ~ts~n"
|
||||
"[ 8] Description : ~ts~n"
|
||||
"[ 9] Search Tags : ~tp~n"
|
||||
"[10] File associations : ~tp~n"
|
||||
"Press a number to select something to change, or [ENTER] to continue.~n",
|
||||
ok = io:format(Instructions,
|
||||
[Name,
|
||||
Author, AEmail, CR, CEmail,
|
||||
RepoURL, WebURL,
|
||||
Desc, sets:to_list(Tags), sets:to_list(Exts)]),
|
||||
case zx_tty:get_input() of
|
||||
"1" ->
|
||||
update_meta(Data, P#project{name = ask_project_name()});
|
||||
"2" ->
|
||||
{A, E} = ask_author(),
|
||||
update_meta(Data, P#project{author = A, a_email = E});
|
||||
"3" ->
|
||||
update_meta(Data, P#project{a_email = ask_email_optional()});
|
||||
"4" ->
|
||||
{C, E} = ask_copyright(),
|
||||
update_meta(Data, P#project{copyright = C, c_email = E});
|
||||
"5" ->
|
||||
update_meta(Data, P#project{c_email = ask_email_optional()});
|
||||
"6" ->
|
||||
update_meta(Data, P#project{repo_url = ask_url(repo)});
|
||||
"7" ->
|
||||
update_meta(Data, P#project{ws_url = ask_url(website)});
|
||||
"8" ->
|
||||
update_meta(Data, P#project{desc = ask_description()});
|
||||
"9" ->
|
||||
update_meta(Data, P#project{tags = edit_tags(Tags)});
|
||||
"10" ->
|
||||
update_meta(Data, P#project{file_exts = edit_exts(Exts)});
|
||||
"" ->
|
||||
finalize_meta(Data, P);
|
||||
_ ->
|
||||
ok = zx_tty:derp(),
|
||||
update_meta(Data, P)
|
||||
end;
|
||||
update_meta(Data,
|
||||
P = #project{name = Name,
|
||||
author = Author,
|
||||
a_email = AEmail,
|
||||
copyright = CR,
|
||||
c_email = CEmail,
|
||||
repo_url = RepoURL,
|
||||
ws_url = WebURL,
|
||||
desc = Desc,
|
||||
tags = Tags}) ->
|
||||
Instructions =
|
||||
"~nDESCRIPTION DATA~n"
|
||||
"[1] Project Name : ~ts~n"
|
||||
"[2] Author : ~ts~n"
|
||||
"[3] Author's Email : ~ts~n"
|
||||
"[4] Copyright Holder : ~ts~n"
|
||||
"[5] Copyright Holder's Email : ~ts~n"
|
||||
"[6] Repo URL : ~ts~n"
|
||||
"[7] Website URL : ~ts~n"
|
||||
"[8] Description : ~ts~n"
|
||||
"[9] Search Tags : ~tp~n"
|
||||
"Press a number to select something to change, or [ENTER] to continue.~n",
|
||||
ok = io:format(Instructions,
|
||||
[Name,
|
||||
Author, AEmail, CR, CEmail,
|
||||
RepoURL, WebURL,
|
||||
Desc, sets:to_list(Tags)]),
|
||||
case zx_tty:get_input() of
|
||||
"1" ->
|
||||
update_meta(Data, P#project{name = ask_project_name()});
|
||||
"2" ->
|
||||
{A, E} = ask_author(),
|
||||
update_meta(Data, P#project{author = A, a_email = E});
|
||||
"3" ->
|
||||
update_meta(Data, P#project{a_email = ask_email_optional()});
|
||||
"4" ->
|
||||
{C, E} = ask_copyright(),
|
||||
update_meta(Data, P#project{copyright = C, c_email = E});
|
||||
"5" ->
|
||||
update_meta(Data, P#project{c_email = ask_email_optional()});
|
||||
"6" ->
|
||||
update_meta(Data, P#project{repo_url = ask_url(repo)});
|
||||
"7" ->
|
||||
update_meta(Data, P#project{ws_url = ask_url(website)});
|
||||
"8" ->
|
||||
update_meta(Data, P#project{desc = ask_description()});
|
||||
"9" ->
|
||||
update_meta(Data, P#project{tags = edit_tags(Tags)});
|
||||
"" ->
|
||||
finalize_meta(Data, P);
|
||||
_ ->
|
||||
ok = zx_tty:derp(),
|
||||
update_meta(Data, P)
|
||||
end.
|
||||
|
||||
finalize_meta(Data = #{type := Type},
|
||||
#project{name = Name,
|
||||
author = Author,
|
||||
a_email = AEmail,
|
||||
copyright = CR,
|
||||
c_email = CEmail,
|
||||
repo_url = RepoURL,
|
||||
ws_url = WebURL,
|
||||
desc = Desc,
|
||||
tags = Tags,
|
||||
file_exts = Exts}) ->
|
||||
Updated = Data#{name => Name,
|
||||
author => Author,
|
||||
a_email => AEmail,
|
||||
copyright => CR,
|
||||
c_email => CEmail,
|
||||
repo_url => RepoURL,
|
||||
ws_url => WebURL,
|
||||
desc => Desc,
|
||||
tags => sets:to_list(Tags),
|
||||
file_exts => sets:to_list(Exts)},
|
||||
NewData =
|
||||
case Type == gui of
|
||||
true -> Updated;
|
||||
false -> maps:remove(file_exts, Updated)
|
||||
end,
|
||||
ok = zx_lib:write_project_meta(NewData),
|
||||
update_app_file(NewData).
|
||||
|
||||
|
||||
-spec update_app_file() -> zx:outcome().
|
||||
|
||||
update_app_file() ->
|
||||
@ -457,6 +624,7 @@ update_app_file() ->
|
||||
|
||||
update_app_file(Meta) ->
|
||||
{_, Name, Version} = maps:get(package_id, Meta),
|
||||
Desc = maps:get(desc, Meta, ""),
|
||||
{ok, VersionString} = zx_lib:version_to_string(Version),
|
||||
AppName = list_to_atom(Name),
|
||||
AppFile = filename:join("ebin", Name ++ ".app"),
|
||||
@ -474,7 +642,7 @@ update_app_file(Meta) ->
|
||||
end,
|
||||
Grep = "grep -oP '^-module\\(\\K[^)]+' src/* | cut -d: -f2",
|
||||
Modules = [list_to_atom(M) || M <- string:lexemes(os:cmd(Grep), "\n")],
|
||||
Properties = [{vsn, VersionString}, {modules, Modules}],
|
||||
Properties = [{description, Desc}, {vsn, VersionString}, {modules, Modules}],
|
||||
Store = fun(T, L) -> lists:keystore(element(1, T), 1, L, T) end,
|
||||
AppData = lists:foldl(Store, RawAppData, Properties),
|
||||
AppProfile = {application, AppName, AppData},
|
||||
@ -525,7 +693,7 @@ update_version(Realm, Name, OldVersion, NewVersion, OldMeta) ->
|
||||
ok = update_app_vsn(Name, NewVersion),
|
||||
{ok, OldVS} = zx_lib:version_to_string(OldVersion),
|
||||
{ok, NewVS} = zx_lib:version_to_string(NewVersion),
|
||||
tell("Version changed from ~s to ~s~n.", [OldVS, NewVS]);
|
||||
tell("Version changed from ~s to ~s.~n", [OldVS, NewVS]);
|
||||
Error ->
|
||||
ok = tell(error, "Write to zomp.meta failed with: ~160tp", [Error]),
|
||||
Error
|
||||
@ -550,7 +718,7 @@ list_realms() ->
|
||||
|
||||
list_packages(Realm) ->
|
||||
{ok, ID} = zx_daemon:list(Realm),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, []} -> tell(error, "No packages available.~n");
|
||||
{ok, Packages} -> lists:foreach(print_package(Realm), Packages);
|
||||
{error, bad_realm} -> {error, "Unconfigured realm or bad realm name.", 22};
|
||||
@ -576,7 +744,7 @@ list_versions(PackageString) ->
|
||||
|
||||
list_versions2({Realm, Name, Version}) ->
|
||||
{ok, ID} = zx_daemon:list(Realm, Name, Version),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, []} -> tell(error, "No versions available.~n");
|
||||
{ok, Versions} -> lists:foreach(fun print_version/1, Versions);
|
||||
{error, bad_realm} -> {error, "Bad realm name.", 22};
|
||||
@ -600,12 +768,51 @@ latest(PackageString) ->
|
||||
|
||||
latest2(PackageID) ->
|
||||
{ok, ID} = zx_daemon:latest(PackageID),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Version} -> print_version(Version);
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
|
||||
-spec describe(PackageString :: string()) -> zx:outcome().
|
||||
|
||||
describe(PackageString) ->
|
||||
case zx_lib:package_id(PackageString) of
|
||||
{ok, {Realm, Name, _}} -> describe2({Realm, Name});
|
||||
{error, invalid_package_string} -> {error, "Invalid package name.", 22}
|
||||
end.
|
||||
|
||||
describe2(Package) ->
|
||||
{ok, ID} = zx_daemon:describe(Package),
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Description} -> describe3(Description);
|
||||
{error, bad_realm} -> {error, "Unconfigured realm or bad realm name.", 22};
|
||||
{error, timeout} -> {error, "Request timed out.", 62};
|
||||
{error, network} -> {error, "Network problem connecting to realm.", 101}
|
||||
end.
|
||||
|
||||
describe3({description,
|
||||
PackageID, DName, Type, Desc, Author, AEmail, WebURL, RepoURL, Tags}) ->
|
||||
{ok, PackageString} = zx_lib:package_string(PackageID),
|
||||
AuthorString =
|
||||
case {Author, AEmail} of
|
||||
{"", ""} -> "";
|
||||
_ -> copyright_holder(Author, AEmail)
|
||||
end,
|
||||
Format =
|
||||
"~n"
|
||||
"Package : ~ts~n"
|
||||
"Name : ~ts~n"
|
||||
"Type : ~tp~n"
|
||||
"Desc : ~ts~n"
|
||||
"Author : ~ts~n"
|
||||
"Web : ~ts~n"
|
||||
"Repo : ~ts~n"
|
||||
"Tags : ~tp~n",
|
||||
io:format(Format,
|
||||
[PackageString, DName, Type, Desc, AuthorString, WebURL, RepoURL, Tags]).
|
||||
|
||||
|
||||
-spec provides(Module :: string()) -> zx:outcome().
|
||||
|
||||
provides(Module) ->
|
||||
@ -616,7 +823,7 @@ provides(Module) ->
|
||||
ID
|
||||
end,
|
||||
IDs = [MakeRequest(R) || R <- Realms],
|
||||
case wait_results(IDs) of
|
||||
case zx_daemon:wait_results(IDs) of
|
||||
{ok, Results} ->
|
||||
Packages = lists:append([R || {_, {ok, R}} <- Results]),
|
||||
lists:foreach(fun print_packages/1, Packages);
|
||||
@ -632,10 +839,10 @@ print_packages(PackageID) ->
|
||||
-spec list_keys() -> zx:outcome().
|
||||
|
||||
list_keys() ->
|
||||
Realm = select_realm(),
|
||||
{ok, Realm} = pick_realm(),
|
||||
UserName = select_user(Realm),
|
||||
{ok, ID} = zx_daemon:list_keys({Realm, UserName}),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, RemoteKeys} ->
|
||||
Print = fun(KN) -> io:format("~ts~n", [KN]) end,
|
||||
lists:foreach(Print, RemoteKeys);
|
||||
@ -648,7 +855,7 @@ list_keys() ->
|
||||
|
||||
list_sysops(Realm) ->
|
||||
{ok, ID} = zx_daemon:list_sysops(Realm),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Sysops} -> lists:foreach(fun zx_lib:print_user/1, Sysops);
|
||||
Error -> Error
|
||||
end.
|
||||
@ -790,7 +997,7 @@ list_deps(PackageString) ->
|
||||
|
||||
list_deps2(PackageID) ->
|
||||
{ok, ID} = zx_daemon:list_deps(PackageID),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Deps} -> lists:foreach(fun print_package_id/1, Deps);
|
||||
Error -> Error
|
||||
end.
|
||||
@ -1515,7 +1722,7 @@ ask_module() ->
|
||||
|
||||
package_exists({Realm, Package, _}) ->
|
||||
{ok, ID} = zx_daemon:list(Realm),
|
||||
case wait_result(ID) of
|
||||
case zx_daemon:wait_result(ID) of
|
||||
{ok, Packages} -> lists:member(Package, Packages);
|
||||
_ -> maybe
|
||||
end.
|
||||
@ -1526,8 +1733,8 @@ package_exists({Realm, Package, _}) ->
|
||||
%% Execute the key generation procedure for 16k RSA keys once and then terminate.
|
||||
|
||||
grow_a_pair() ->
|
||||
case select_realm() of
|
||||
error -> {error, "No realms configured.", 61};
|
||||
case pick_realm() of
|
||||
{error, no_realms} -> {error, "No realms configured.", 61};
|
||||
Realm -> grow_a_pair(Realm)
|
||||
end.
|
||||
|
||||
@ -1756,7 +1963,7 @@ prompt_port_number(Current) ->
|
||||
|
||||
ask_url(realm) ->
|
||||
Message =
|
||||
"~nURL~n"
|
||||
"~nREALM COMMUNITY URL~n"
|
||||
"Most public realms have a website, IRC channel, or similar location where its "
|
||||
"community (or customers) communicate. If you have such a URL enter it here.~n"
|
||||
"NOTE: No checking is performed on the input here. Confuse your users at "
|
||||
@ -1765,7 +1972,7 @@ ask_url(realm) ->
|
||||
zx_tty:get_input(Message);
|
||||
ask_url(repo) ->
|
||||
Message =
|
||||
"~nURL~n"
|
||||
"~nPROJECT REPO URL~n"
|
||||
"Most projects have a hosted repo URL (gitlab, github, SF, self hosted, etc).~n"
|
||||
"If you have such a URL enter it here.~n"
|
||||
"NOTE: No checking is performed on the input here. Confuse your users at "
|
||||
@ -1774,7 +1981,7 @@ ask_url(repo) ->
|
||||
zx_tty:get_input(Message);
|
||||
ask_url(website) ->
|
||||
Message =
|
||||
"~nURL~n"
|
||||
"~nPROJECT WEBSITE URL~n"
|
||||
"Many project, particularly GUI applications, have a public website where "
|
||||
"documentation, user forums, etc. are hosted.~n"
|
||||
"If you have such a URL enter it here.~n"
|
||||
@ -1898,8 +2105,8 @@ store_user(#user_data{realm = Realm,
|
||||
-spec create_userfile() -> ok.
|
||||
|
||||
create_userfile() ->
|
||||
case select_realm() of
|
||||
error -> {error, "No realms configured.", 61};
|
||||
case pick_realm() of
|
||||
{error, no_realms} -> {error, "No realms configured.", 61};
|
||||
Realm -> create_userfile(Realm)
|
||||
end.
|
||||
|
||||
@ -1937,8 +2144,8 @@ create_userfile(Realm, UserName) ->
|
||||
-spec export_user() -> ok.
|
||||
|
||||
export_user() ->
|
||||
case select_realm() of
|
||||
error -> {error, "No realms configured.", 61};
|
||||
case pick_realm() of
|
||||
{error, no_realms} -> {error, "No realms configured.", 61};
|
||||
Realm -> export_user(Realm)
|
||||
end.
|
||||
|
||||
@ -2040,10 +2247,12 @@ pick_realm() ->
|
||||
[] ->
|
||||
ok = tell(warning, "No realms configured! Exiting..."),
|
||||
{error, no_realms};
|
||||
[Realm] ->
|
||||
ok = tell("Realm ~ts selected.", [Realm]),
|
||||
{ok, Realm};
|
||||
Realms ->
|
||||
ok = io:format("Select a realm:~n"),
|
||||
Options = lists:zip(Realms, Realms),
|
||||
Realm = zx_tty:select(Options),
|
||||
Realm = zx_tty:select_string(Realms),
|
||||
{ok, Realm}
|
||||
end.
|
||||
|
||||
@ -2233,6 +2442,61 @@ ask_description() ->
|
||||
unicode:characters_to_list(String, utf8).
|
||||
|
||||
|
||||
-spec edit_tags(Set) -> NewSet
|
||||
when Set :: sets:set(string()),
|
||||
NewSet :: sets:set(string()).
|
||||
|
||||
edit_tags(Set) ->
|
||||
ok = io:format("CURRENT TAGS:~n~tp~n", [sets:to_list(Set)]),
|
||||
Options =
|
||||
[{"Add a tag", 1},
|
||||
{"Remove a tag", 2},
|
||||
{"Return", 3}],
|
||||
case zx_tty:select(Options) of
|
||||
1 ->
|
||||
New = string:lowercase(zx_tty:get_input("~nEnter a new tag~n")),
|
||||
edit_tags(sets:add_element(New, Set));
|
||||
2 ->
|
||||
edit_tags(rem_item(Set));
|
||||
3 ->
|
||||
Set
|
||||
end.
|
||||
|
||||
|
||||
-spec edit_exts(Set) -> NewSet
|
||||
when Set :: sets:set(string()),
|
||||
NewSet :: sets:set(string()).
|
||||
|
||||
edit_exts(Set) ->
|
||||
ok = io:format("CURRENT ASSOCIATED FILE EXTENSIONS:~n~tp~n", [sets:to_list(Set)]),
|
||||
Options =
|
||||
[{"Add a tag", 1},
|
||||
{"Remove a tag", 2},
|
||||
{"Return", 3}],
|
||||
case zx_tty:select(Options) of
|
||||
1 ->
|
||||
New = dotify(string:lowercase(zx_tty:get_input("~nEnter a new tag~n"))),
|
||||
edit_tags(sets:add_element(New, Set));
|
||||
2 ->
|
||||
edit_tags(rem_item(Set));
|
||||
3 ->
|
||||
Set
|
||||
end.
|
||||
|
||||
dotify(S) ->
|
||||
Chars = lists:seq($a, $z) ++ lists:seq($0, $9),
|
||||
{_, T} = string:take(S, Chars, true),
|
||||
{H, _} = string:take(T, Chars, false),
|
||||
[$. | H].
|
||||
|
||||
|
||||
rem_item(Set) ->
|
||||
ok = io:format("~nSelect an item to drop.~n"),
|
||||
Picked = zx_tty:select_string(sets:to_list(Set)),
|
||||
sets:del_element(Picked, Set).
|
||||
|
||||
|
||||
|
||||
-spec realm_exists(zx:realm()) -> boolean().
|
||||
%% @private
|
||||
%% Checks for remnants of a realm.
|
||||
@ -2260,7 +2524,7 @@ make_realm_dirs(Realm) ->
|
||||
-spec create_realmfile() -> ok.
|
||||
|
||||
create_realmfile() ->
|
||||
Realm = select_realm(),
|
||||
{ok, Realm} = pick_realm(),
|
||||
create_realmfile(Realm).
|
||||
|
||||
|
||||
@ -2329,7 +2593,7 @@ logpath(_, Ago) when Ago < 1 ->
|
||||
set_timeout(String) ->
|
||||
case string:to_integer(String) of
|
||||
{Value, ""} when Value > 0 ->
|
||||
zx_sys_conf:save(zx_sys_conf:timeout(Value, zx_sys_conf:load()));
|
||||
zx_daemon:conf(timeout, Value);
|
||||
_ ->
|
||||
{error, "Enter a positive integer. Common values are 3, 5 and 10.", 22}
|
||||
end.
|
||||
@ -2357,6 +2621,33 @@ add_mirror() ->
|
||||
zx_daemon:add_mirror({Host, Port}).
|
||||
|
||||
|
||||
-spec add_mirror(Address) -> zx:outcome()
|
||||
when Address :: string().
|
||||
|
||||
add_mirror(Address) ->
|
||||
add_mirror(Address, "11311").
|
||||
|
||||
|
||||
-spec add_mirror(Address, PortString) -> zx:outcome()
|
||||
when Address :: string(),
|
||||
PortString :: string().
|
||||
|
||||
add_mirror(Address, PortString) ->
|
||||
Host = parse_maybe_address(Address),
|
||||
try
|
||||
case list_to_integer(PortString) of
|
||||
Port when 16#ffff >= Port, Port > 0 ->
|
||||
zx_daemon:add_mirror({Host, Port});
|
||||
Illegal ->
|
||||
F = "Provided port number ~w is out of bound (1~65535).",
|
||||
Message = io_lib:format(F, [Illegal]),
|
||||
{error, Message}
|
||||
end
|
||||
catch error:badarg ->
|
||||
{error, "Provided port value is not a port number."}
|
||||
end.
|
||||
|
||||
|
||||
-spec drop_mirror() -> ok.
|
||||
|
||||
drop_mirror() ->
|
||||
@ -2375,13 +2666,30 @@ drop_mirror() ->
|
||||
end.
|
||||
|
||||
|
||||
-spec select_realm() -> {ok, zx:realm()} | error.
|
||||
-spec drop_mirror(Address) -> zx:outcome()
|
||||
when Address :: string().
|
||||
|
||||
select_realm() ->
|
||||
case zx_lib:list_realms() of
|
||||
[] -> error;
|
||||
[Realm] -> Realm;
|
||||
Realms -> zx_tty:select_string(Realms)
|
||||
drop_mirror(Address) ->
|
||||
drop_mirror(Address, "11311").
|
||||
|
||||
|
||||
-spec drop_mirror(Address, PortString) -> zx:outcome()
|
||||
when Address :: string(),
|
||||
PortString :: string().
|
||||
|
||||
drop_mirror(Address, PortString) ->
|
||||
Host = parse_maybe_address(Address),
|
||||
try
|
||||
case list_to_integer(PortString) of
|
||||
Port when 16#ffff >= Port, Port > 0 ->
|
||||
zx_daemon:drop_mirror({Host, Port});
|
||||
Illegal ->
|
||||
F = "Provided port number ~w is out of bound (1~65535).",
|
||||
Message = io_lib:format(F, [Illegal]),
|
||||
{error, Message}
|
||||
end
|
||||
catch error:badarg ->
|
||||
{error, "Provided port value is not a port number."}
|
||||
end.
|
||||
|
||||
|
||||
@ -2424,33 +2732,3 @@ select_private_key2(Realm, [KeyName | Rest]) ->
|
||||
end;
|
||||
select_private_key2(_, []) ->
|
||||
error.
|
||||
|
||||
|
||||
|
||||
%%% Utility Functions
|
||||
|
||||
wait_result(ID) ->
|
||||
receive
|
||||
{result, ID, Result} -> Result;
|
||||
Message -> {error, {unexpected, Message}}
|
||||
after 5000 -> {error, timeout}
|
||||
end.
|
||||
|
||||
|
||||
wait_results(IDs) ->
|
||||
wait_results(IDs, []).
|
||||
|
||||
wait_results([], Results) ->
|
||||
{ok, Results};
|
||||
wait_results(IDs, Results) ->
|
||||
receive
|
||||
{result, ID, Result} ->
|
||||
case lists:member(ID, IDs) of
|
||||
true -> wait_results(lists:delete(ID, IDs), [{ID, Result} | Results]);
|
||||
false -> {error, {unexpected, {result, ID, Result}}, Results}
|
||||
end;
|
||||
Message ->
|
||||
{error, {unexpected, Message}}
|
||||
after 5000 ->
|
||||
{error, timeout}
|
||||
end.
|
||||
@ -5,7 +5,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_net).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -8,7 +8,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_peer).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -9,7 +9,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_peer_man).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(gen_server).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -6,7 +6,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_peer_sup).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behaviour(supervisor).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -10,7 +10,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_peers).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(supervisor).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -5,7 +5,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_proxy).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -5,7 +5,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_sup).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-behavior(supervisor).
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
@ -1,12 +1,12 @@
|
||||
%%% @doc
|
||||
%%% ZX TTY
|
||||
%%%
|
||||
%%% This module lets other parts of ZX interact (very clumsily) with the user via a text
|
||||
%%% This module lets other parts of ZX interact (clumsily) with the user via a text
|
||||
%%% interface. Hopefully this will never be called on Windows.
|
||||
%%% @end
|
||||
|
||||
-module(zx_tty).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -7,7 +7,7 @@
|
||||
%%% @end
|
||||
|
||||
-module(zx_zsp).
|
||||
-vsn("0.2.0").
|
||||
-vsn("0.2.1").
|
||||
-author("Craig Everett <zxq9@zxq9.com>").
|
||||
-copyright("Craig Everett <zxq9@zxq9.com>").
|
||||
-license("GPL-3.0").
|
||||
@ -26,6 +26,12 @@
|
||||
|
||||
-type meta() :: {PackageID :: zx:package_id(),
|
||||
KeyName :: zx:key_name(),
|
||||
DisplayName :: string(),
|
||||
Desc :: string(),
|
||||
Author :: string(),
|
||||
AEmail :: string(),
|
||||
WebURL :: string(),
|
||||
RepoURL :: string(),
|
||||
Tags :: [string()],
|
||||
Deps :: [zx:package_id()],
|
||||
Modules :: [string()]}.
|
||||
@ -71,9 +77,20 @@ pack3(TargetDir, PackageID, Meta, {KeyName, Key}, ZspFile) ->
|
||||
ok = erl_tar:create(TarGzPath, Targets, [compressed]),
|
||||
{ok, TgzBin} = file:read_file(TarGzPath),
|
||||
ok = file:delete(TarGzPath),
|
||||
Tags = maps:get(tags, Meta, []),
|
||||
Deps = maps:get(deps, Meta, []),
|
||||
MetaBin = term_to_binary({PackageID, KeyName, Tags, Deps, Modules}),
|
||||
MetaData =
|
||||
{PackageID,
|
||||
KeyName,
|
||||
maps:get(name, Meta, Name),
|
||||
maps:get(type, Meta),
|
||||
maps:get(desc, Meta, ""),
|
||||
maps:get(author, Meta, ""),
|
||||
maps:get(a_email, Meta, ""),
|
||||
maps:get(ws_url, Meta, ""),
|
||||
maps:get(repo_url, Meta, ""),
|
||||
maps:get(tags, Meta, []),
|
||||
maps:get(deps, Meta, []),
|
||||
Modules},
|
||||
MetaBin = term_to_binary(MetaData),
|
||||
MetaSize = byte_size(MetaBin),
|
||||
SignMe = <<MetaSize:24, MetaBin:MetaSize/binary, TgzBin/binary>>,
|
||||
Sig = public_key:sign(SignMe, sha512, Key),
|
||||
@ -1,5 +1,5 @@
|
||||
{deps,[]}.
|
||||
{package_id,{"otpr","zx",{0,2,0}}}.
|
||||
{package_id,{"otpr","zx",{0,2,1}}}.
|
||||
{prefix,"zx_"}.
|
||||
{tags,[]}.
|
||||
{type,app}.
|
||||
Loading…
x
Reference in New Issue
Block a user