Merge pull request #2 from zxq9/dev

Where is fancy bred, in the heart or in the head?
This commit is contained in:
Craig Everett 2018-05-30 23:30:45 +09:00 committed by GitHub
commit 9c79ab2889
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 659 additions and 590 deletions

View File

@ -19,7 +19,7 @@
-license("GPL-3.0").
-export([run/0, run/1]).
-export([do/0, do/1]).
-export([subscribe/1, unsubscribe/0]).
-export([start/2, stop/1, stop/0]).
-export([usage_exit/1]).
@ -69,105 +69,131 @@
%%% Command Dispatch
-spec run() -> no_return().
-spec do() -> no_return().
run() ->
run([]).
do() ->
do([]).
-spec run(Args) -> no_return()
-spec do(Args) -> no_return()
when Args :: [string()].
%% Dispatch work functions based on the nature of the input arguments.
run(["help"]) ->
do(["help"]) ->
usage_exit(0);
run(["run", PackageString | Args]) ->
do(["run", PackageString | Args]) ->
ok = start(),
run(PackageString, Args);
run(["runlocal" | ArgV]) ->
do(["runlocal" | ArgV]) ->
ok = start(),
run_local(ArgV);
run(["init", "app", PackageString]) ->
do(["init", "app", PackageString]) ->
ok = compatibility_check([unix]),
zx_local:initialize(app, PackageString);
run(["init", "lib", PackageString]) ->
ok = zx_local:initialize(app, PackageString),
halt(0);
do(["init", "lib", PackageString]) ->
ok = compatibility_check([unix]),
zx_local:initialize(lib, PackageString);
run(["install", PackageFile]) ->
zx_local:assimilate(PackageFile);
run(["set", "dep", PackageString]) ->
zx_local:set_dep(PackageString);
run(["set", "version", VersionString]) ->
ok = zx_local:initialize(lib, PackageString),
halt(0);
do(["install", PackageFile]) ->
ok = zx_local:assimilate(PackageFile),
halt(0);
do(["set", "dep", PackageString]) ->
ok = zx_local:set_dep(PackageString),
halt(0);
do(["set", "version", VersionString]) ->
ok = compatibility_check([unix]),
zx_local:set_version(VersionString);
run(["verup", Level]) ->
ok = zx_local:set_version(VersionString),
halt(0);
do(["verup", Level]) ->
ok = compatibility_check([unix]),
zx_local:verup(Level);
run(["list", "realms"]) ->
zx_loca:list_realms();
run(["list", "packages", Realm]) ->
ok = zx_local:verup(Level),
halt(0);
do(["list", "realms"]) ->
ok = zx_local:list_realms(),
halt(0);
do(["list", "packages", Realm]) ->
ok = start(),
zx_local:list_packages(Realm);
run(["list", "versions", PackageName]) ->
ok = zx_local:list_packages(Realm),
halt(0);
do(["list", "versions", PackageName]) ->
ok = start(),
zx_local:list_versions(PackageName);
run(["add", "realm", RealmFile]) ->
zx_local:add_realm(RealmFile);
run(["drop", "dep", PackageString]) ->
ok = zx_local:list_versions(PackageName),
halt(0);
do(["add", "realm", RealmFile]) ->
ok = zx_local:add_realm(RealmFile),
halt(0);
do(["drop", "dep", PackageString]) ->
PackageID = zx_lib:package_id(PackageString),
zx_local:drop_dep(PackageID);
run(["drop", "key", Realm, KeyName]) ->
zx_key:drop({Realm, KeyName});
run(["drop", "realm", Realm]) ->
zx_local:drop_realm(Realm);
run(["package"]) ->
ok = zx_local:drop_dep(PackageID),
halt(0);
do(["package"]) ->
{ok, TargetDir} = file:get_cwd(),
zx_local:package(TargetDir);
run(["package", TargetDir]) ->
do(["package", TargetDir]) ->
case filelib:is_dir(TargetDir) of
true ->
zx_local:package(TargetDir);
ok = zx_local:package(TargetDir),
halt(0);
false ->
ok = log(error, "Target directory ~tp does not exist!", [TargetDir]),
halt(22)
end;
run(["dialyze"]) ->
zx_local:dialyze();
run(["create", "user", Realm, Name]) ->
zx_local:create_user(Realm, Name);
run(["create", "keypair"]) ->
zx_key:grow_a_pair();
run(["create", "plt"]) ->
zx_local:create_plt();
run(["create", "realm"]) ->
zx_local:create_realm();
run(["create", "realmfile", Realm]) ->
zx_local:create_realmfile(Realm);
run(["list", "pending", PackageName]) ->
do(["dialyze"]) ->
ok = zx_local:dialyze(),
halt(0);
do(["create", "user", Realm, Name]) ->
ok = zx_local:create_user(Realm, Name),
halt(0);
do(["create", "keypair"]) ->
ok = zx_local:grow_a_pair(),
halt(0);
do(["drop", "key", Realm, KeyName]) ->
ok = zx_local:drop_key({Realm, KeyName}),
halt(0);
do(["create", "plt"]) ->
ok = zx_local:create_plt(),
halt(0);
do(["create", "realm"]) ->
ok = zx_local:create_realm(),
halt(0);
do(["create", "realmfile", Realm]) ->
ok = zx_local:create_realmfile(Realm, "."),
halt(0);
do(["takeover", Realm]) ->
ok = zx_local:takeover(Realm),
halt(0);
do(["abdicate", Realm]) ->
ok = zx_local:abdicate(Realm),
halt(0);
do(["drop", "realm", Realm]) ->
ok = zx_local:drop_realm(Realm),
halt(0);
do(["list", "pending", PackageName]) ->
zx_auth:list_pending(PackageName);
run(["list", "resigns", Realm]) ->
do(["list", "resigns", Realm]) ->
zx_auth:list_resigns(Realm);
run(["submit", PackageFile]) ->
do(["submit", PackageFile]) ->
zx_auth:submit(PackageFile);
run(["review", PackageString]) ->
do(["review", PackageString]) ->
zx_auth:review(PackageString);
run(["approve", PackageString]) ->
do(["approve", PackageString]) ->
PackageID = zx_lib:package_id(PackageString),
zx_auth:approve(PackageID);
run(["reject", PackageString]) ->
do(["reject", PackageString]) ->
PackageID = zx_lib:package_id(PackageString),
zx_auth:reject(PackageID);
run(["accept", PackageString]) ->
do(["accept", PackageString]) ->
zx_auth:accept(PackageString);
run(["add", "packager", Package, UserName]) ->
do(["add", "packager", Package, UserName]) ->
zx_auth:add_packager(Package, UserName);
run(["add", "maintainer", Package, UserName]) ->
do(["add", "maintainer", Package, UserName]) ->
zx_auth:add_maintainer(Package, UserName);
run(["add", "sysop", Package, UserName]) ->
do(["add", "sysop", Package, UserName]) ->
zx_auth:add_sysop(Package, UserName);
run(["add", "package", PackageName]) ->
do(["add", "package", PackageName]) ->
zx_auth:add_package(PackageName);
run(_) ->
do(_) ->
usage_exit(22).
@ -300,7 +326,6 @@ unsubscribe() ->
run(Identifier, RunArgs) ->
ok = file:set_cwd(zx_lib:zomp_dir()),
ok = start(),
FuzzyID =
case zx_lib:package_id(Identifier) of
{ok, Fuzzy} ->
@ -312,12 +337,9 @@ run(Identifier, RunArgs) ->
ok = build(PackageID),
Dir = zx_lib:package_dir(PackageID),
{ok, Meta} = zx_lib:read_project_meta(Dir),
execute(PackageID, Meta, Dir, RunArgs).
prepare(PackageID, Meta, Dir, RunArgs).
%%% Execution of local project
-spec run_local(RunArgs) -> no_return()
when RunArgs :: [term()].
%% @private
@ -335,11 +357,10 @@ run_local(RunArgs) ->
ok = zx_lib:build(),
{ok, Dir} = file:get_cwd(),
ok = file:set_cwd(zx_lib:zomp_dir()),
ok = start(),
execute(PackageID, Meta, Dir, RunArgs).
prepare(PackageID, Meta, Dir, RunArgs).
-spec execute(PackageID, Meta, Dir, RunArgs) -> no_return()
-spec prepare(PackageID, Meta, Dir, RunArgs) -> no_return()
when PackageID :: package_id(),
Meta :: package_meta(),
Dir :: file:filename(),
@ -347,21 +368,43 @@ run_local(RunArgs) ->
%% @private
%% Execution prep common to all packages.
execute(PackageID, Meta, Dir, RunArgs) ->
PackageString = zx_lib:package_string(PackageID),
prepare(PackageID, Meta, Dir, RunArgs) ->
{ok, PackageString} = zx_lib:package_string(PackageID),
ok = log(info, "Preparing ~ts...", [PackageString]),
Type = maps:get(type, Meta),
Deps = maps:get(deps, Meta),
case zx_daemon:fetch(Deps) of
{{ok, _}, {error, []}} ->
ok = lists:foreach(fun install/1, Deps),
ok = lists:foreach(fun build/1, Deps),
execute(Type, PackageID, Dir, Meta, RunArgs);
{{ok, _}, {error, Errors}} ->
NotInstalled = fun(P) -> not filelib:is_dir(zx_lib:ppath(lib, P)) end,
Needed = lists:filter(NotInstalled, Deps),
Pending = lists:map(fun zx_daemon:fetch/1, Needed),
case await_fetches(Pending) of
ok ->
ok = lists:foreach(fun install/1, Needed),
ok = lists:foreach(fun build/1, Needed),
execute(Type, PackageID, Meta, Dir, RunArgs);
{error, Errors} ->
error_exit("Failed package fetches: ~tp", [Errors], ?LINE)
end.
await_fetches([]) -> ok;
await_fetches(Pending) -> await_fetches(Pending, []).
await_fetches([], []) ->
ok;
await_fetches([], Errors) ->
{error, Errors};
await_fetches(Pending, Errors) ->
{NewPending, NewErrors} =
receive
{z_reply, ID, ok} ->
{lists:delete(ID, Pending), Errors};
{z_reply, ID, {error, Package, Reason}} ->
{lists:delete(ID, Pending), [{Package, Reason} | Errors]}
end,
await_fetches(NewPending, NewErrors).
-spec execute(Type, PackageID, Meta, Dir, RunArgs) -> no_return()
when Type :: app | lib,
PackageID :: package_id(),
@ -373,12 +416,13 @@ execute(PackageID, Meta, Dir, RunArgs) ->
%% the exec_wait/1 loop to wait for any queries from the application.
execute(app, PackageID, Meta, Dir, RunArgs) ->
PackageString = zx_lib:package_string(PackageID),
{ok, PackageString} = zx_lib:package_string(PackageID),
ok = log(info, "Starting ~ts.", [PackageString]),
Name = element(2, PackageID),
AppMod = list_to_atom(Name),
ok = zx_daemon:pass_meta(Meta, Dir),
ok = ensure_all_started(AppMod),
AppTag = list_to_atom(Name),
{AppMod, _} = maps:get(appmod, Meta),
ok = zx_daemon:pass_meta(Meta, Dir, RunArgs),
ok = ensure_all_started(AppTag),
ok = pass_argv(AppMod, RunArgs),
log(info, "Launcher complete.");
execute(lib, PackageID, _, _, _) ->

View File

@ -127,14 +127,14 @@ timeout(#d{timeout = Timeout}) ->
Timeout.
-spec timeout(Data, Value) -> NewData
when Data :: data(),
Value :: pos_integer(),
-spec timeout(Value, Data) -> NewData
when Value :: pos_integer(),
Data :: data(),
NewData :: data().
%% @doc
%% Set the timeout attribute to a new value.
timeout(Data, Value)
timeout(Value, Data)
when is_integer(Value) and Value > 0 ->
Data#d{timeout = Value}.
@ -147,14 +147,14 @@ retries(#d{retries = {_, Retries}}) ->
Retries.
-spec retries(Data, Value) -> NewData
when Data :: data(),
Value :: non_neg_integer(),
-spec retries(Value, Data) -> NewData
when Value :: non_neg_integer(),
Data :: data(),
NewData :: data().
%% @doc
%% Set the retries attribute to a new value.
retries(Data = #d{retries = {Remaining, _}}, Value)
retries(Value, Data = #d{retries = {Remaining, _}})
when is_integer(Value) and Value >= 0 ->
Data#d{retries = {Remaining, Value}}.
@ -192,14 +192,14 @@ maxconn(#d{maxconn = MaxConn}) ->
MaxConn.
-spec maxconn(Data, Value) -> NewData
when Data :: data(),
Value :: pos_integer(),
-spec maxconn(Value, Data) -> NewData
when Value :: pos_integer(),
Data :: data(),
NewData :: data().
%% @doc
%% Set the value of maxconn.
maxconn(Data, Value)
maxconn(Value, Data)
when is_integer(Value) and Value > 0 ->
Data#d{maxconn = Value}.
@ -212,24 +212,24 @@ managed(#d{managed = Managed}) ->
sets:to_list(Managed).
-spec managed(Data, List) -> NewData
when Data :: data(),
List :: [zx:realm()],
-spec managed(List, Data) -> NewData
when List :: [zx:realm()],
Data :: data(),
NewData :: data().
%% @doc
%% Reset the set of managed realms entirely.
%% The realms must be configured on the current realm at a minimum.
managed(Data, List) ->
managed(List, Data) ->
Desired = sets:from_list(List),
Configured = sets:from_list(zx_lib:list_realms()),
NewManaged = sets:intersection(Desired, Configured),
Data#d{managed = NewManaged}.
-spec add_managed(Data, Realm) -> Result
when Data :: data(),
Realm :: zx:realm(),
-spec add_managed(Realm, Data) -> Result
when Realm :: zx:realm(),
Data :: data(),
Result :: {ok, NewData}
| {error, unconfigured},
NewData :: data().
@ -238,8 +238,8 @@ managed(Data, List) ->
%% the current node. This node will then behave as the prime node for the realm (whether
%% it is or not).
add_managed(Data = #d{managed = Managed}, Realm) ->
case lists:member(Realm, zx_lib:list_realms()) of
add_managed(Realm, Data = #d{managed = Managed}) ->
case zx_lib:realm_exists(Realm) of
true ->
NewData = Data#d{managed = sets:add_element(Realm, Managed)},
ok = log(info, "Now managing realm: ~tp", [Realm]),
@ -250,16 +250,16 @@ add_managed(Data = #d{managed = Managed}, Realm) ->
end.
-spec rem_managed(Data, Realm) -> Result
when Data :: data(),
Realm :: zx:realm(),
-spec rem_managed(Realm, Data) -> Result
when Realm :: zx:realm(),
Data :: data(),
Result :: {ok, NewData}
| {error, unmanaged},
NewData :: data().
%% @doc
%% Stop managing a realm.
rem_managed(Data = #d{managed = Managed}, Realm) ->
rem_managed(Realm, Data = #d{managed = Managed}) ->
case sets:is_element(Realm, Managed) of
true ->
NewData = Data#d{managed = sets:del_element(Realm, Managed)},
@ -279,20 +279,20 @@ mirrors(#d{mirrors = Mirrors}) ->
Mirrors.
-spec mirrors(Data, Hosts) -> NewData
when Data :: data(),
Hosts :: [zx:host()],
-spec mirrors(Hosts, Data) -> NewData
when Hosts :: [zx:host()],
Data :: data(),
NewData :: data().
%% @private
%% Reset the mirror configuration.
mirrors(Data, Hosts) ->
mirrors(Hosts, Data) ->
Data#d{mirrors = Hosts}.
-spec add_mirror(Data, Host) -> NewData
when Data :: data(),
Host :: zx:host(),
-spec add_mirror(Host, Data) -> NewData
when Host :: zx:host(),
Data :: data(),
NewData :: data().
%% @doc
%% Add a mirror to the permanent configuration.
@ -304,14 +304,14 @@ add_mirror(Data = #d{mirrors = Mirrors}, Host) ->
end.
-spec rem_mirror(Data, Host) -> NewData
when Data :: data(),
Host :: zx:host(),
-spec rem_mirror(Host, Data) -> NewData
when Host :: zx:host(),
Data :: data(),
NewData :: data().
%% @private
%% Remove a host from the list of permanent mirrors.
rem_mirror(Data = #d{mirrors = Mirrors}, Host) ->
rem_mirror(Host, Data = #d{mirrors = Mirrors}) ->
Data#d{mirrors = lists:delete(Host, Mirrors)}.

View File

@ -147,7 +147,7 @@
-export([pass_meta/3,
subscribe/1, unsubscribe/1,
list/0, list/1, list/2, list/3, latest/1,
fetch_zsp/1, fetch_key/1,
fetch/1, verify_key/1,
pending/1, packagers/1, maintainers/1, sysops/1]).
-export([report/1, result/2, notify/2]).
-export([start_link/0, stop/0]).
@ -326,6 +326,9 @@
%% references.
pass_meta(Meta, Dir, ArgV) ->
ok = log(info, "Meta: ~tp", [Meta]),
ok = log(info, "Dir : ~tp", [Dir]),
ok = log(info, "ArgV: ~tp", [ArgV]),
gen_server:cast(?MODULE, {pass_meta, Meta, Dir, ArgV}).
@ -446,7 +449,7 @@ latest({Realm, Name, Version}) ->
request({latest, Realm, Name, Version}).
-spec fetch_zsp(PackageID) -> {ok, RequestID}
-spec fetch(PackageID) -> {ok, RequestID}
when PackageID :: zx:package_id(),
RequestID :: integer().
%% @doc
@ -458,27 +461,28 @@ latest({Realm, Name, Version}) ->
%% Response messages are of the type `result()' where the third element is of the
%% type `fetch_result()'.
fetch_zsp(PackageID = {Realm, Name, Version}) ->
fetch({Realm, Name, Version}) ->
true = zx_lib:valid_lower0_9(Realm),
true = zx_lib:valid_lower0_9(Name),
true = zx_lib:valid_version(Version),
request({fetch, zsp, PackageID}).
request({fetch, Realm, Name, Version}).
-spec fetch_key(KeyID) -> {ok, RequestID}
-spec verify_key(KeyID) -> {ok, RequestID}
when KeyID :: zx:key_id(),
RequestID :: id().
%% @doc
%% Request a public key be fetched from its relevant realm.
%% Request a public key be fetched from its upstream, and pursue the key validation
%% chain until a key in possession is found or the chain is proven to be broken.
%% Crashes the caller if either component of the KeyID is illegal.
%%
%% Response messages are of the type `result()' where the third element is of the
%% type `key_result()'.
fetch_key(KeyID = {Realm, KeyName}) ->
verify_key({Realm, KeyName}) ->
true = zx_lib:valid_lower0_9(Realm),
true = zx_lib:valid_lower0_9(KeyName),
request({fetch, key, KeyID}).
request({verify_key, Realm, KeyName}).
-spec pending(Package) -> {ok, RequestID}

View File

@ -13,7 +13,7 @@
-license("GPL-3.0").
-export([ensure_keypair/1, have_public_key/1, have_private_key/1,
prompt_keygen/0, grow_a_pair/0, generate_rsa/1,
prompt_keygen/0, generate_rsa/1,
load/2, verify/3]).
-include("zx_logger.hrl").
@ -102,25 +102,10 @@ prompt_keygen() ->
end.
-spec grow_a_pair() -> no_return().
%% @private
%% Execute the key generation procedure for 16k RSA keys once and then terminate.
grow_a_pair() ->
ok = file:set_cwd(zx_lib:zomp_dir()),
KeyID = prompt_keygen(),
case generate_rsa(KeyID) of
{ok, _, _} -> halt(0);
Error -> error_exit("grow_a_pair/0 error: ~tp", [Error], ?LINE)
end.
-spec generate_rsa(KeyID) -> Result
when KeyID :: zx:key_id(),
Result :: {ok, KeyFile, PubFile}
| {error, keygen_fail},
KeyFile :: file:filename(),
PubFile :: file:filename().
Result :: ok
| {error, keygen_fail}.
%% @private
%% Generate an RSA keypair and write them in der format to the current directory, using
%% filenames derived from Prefix.
@ -144,10 +129,7 @@ generate_rsa({Realm, KeyName}) ->
case check_key(KeyFile, PubFile) of
true ->
ok = file:delete(PemFile),
ok = log(info, "~ts and ~ts agree", [KeyFile, PubFile]),
ok = log(info, "Wrote private key to: ~ts.", [KeyFile]),
ok = log(info, "Wrote public key to: ~ts.", [PubFile]),
{ok, KeyFile, PubFile};
log(info, "~ts and ~ts agree", [KeyFile, PubFile]);
false ->
ok = lists:foreach(fun file:delete/1, [PemFile, KeyFile, PubFile]),
ok = log(error, "Something has gone wrong."),

View File

@ -15,8 +15,8 @@
-license("GPL-3.0").
-export([zomp_dir/0, find_zomp_dir/0,
path/1, path/2, path/3,
force_dir/1,
path/1, path/2, path/3, path/4, ppath/2,
force_dir/1, mktemp_dir/1,
list_realms/0,
hosts_cache_file/1, get_prime/1, realm_meta/1,
read_project_meta/0, read_project_meta/1, read_package_meta/1,
@ -71,13 +71,13 @@ find_zomp_dir() ->
end.
-spec path(Type) -> Result
when Type :: etc
| var
| tmp
| log
| lib,
Result :: file:filename().
-spec path(Type) -> Path
when Type :: etc
| var
| tmp
| log
| lib,
Path :: file:filename().
%% @private
%% Return the top-level path of the given type in the Zomp/ZX system.
@ -85,17 +85,19 @@ path(etc) -> filename:join(zomp_dir(), "etc");
path(var) -> filename:join(zomp_dir(), "var");
path(tmp) -> filename:join(zomp_dir(), "tmp");
path(log) -> filename:join(zomp_dir(), "log");
path(key) -> filename:join(zomp_dir(), "key");
path(zsp) -> filename:join(zomp_dir(), "zsp");
path(lib) -> filename:join(zomp_dir(), "lib").
-spec path(Type, Realm) -> Result
when Type :: etc
| var
| tmp
| log
| lib,
Realm :: zx:realm(),
Result :: file:filename().
-spec path(Type, Realm) -> Path
when Type :: etc
| var
| tmp
| log
| lib,
Realm :: zx:realm(),
Path :: file:filename().
%% @private
%% Return the realm-level path of the given type in the Zomp/ZX system.
@ -103,15 +105,15 @@ path(Type, Realm) ->
filename:join(path(Type), Realm).
-spec path(Type, Realm, Name) -> Result
when Type :: etc
| var
| tmp
| log
| lib,
Realm :: zx:realm(),
Name :: zx:name(),
Result :: file:filename().
-spec path(Type, Realm, Name) -> Path
when Type :: etc
| var
| tmp
| log
| lib,
Realm :: zx:realm(),
Name :: zx:name(),
Path :: file:filename().
%% @private
%% Return the package-level path of the given type in the Zomp/ZX system.
@ -119,6 +121,40 @@ path(Type, Realm, Name) ->
filename:join([path(Type), Realm, Name]).
-spec path(Type, Realm, Name, Version) -> Path
when Type :: etc
| var
| tmp
| log
| lib,
Realm :: zx:realm(),
Name :: zx:name(),
Version :: zx:version(),
Path :: file:filename().
%% @private
%% Return the version-specific level path of the given type in the Zomp/ZX system.
path(Type, Realm, Name, Version) ->
{ok, VersionString} = version_to_string(Version),
filename:join([path(Type), Realm, Name, VersionString]).
-spec ppath(Type, PackageID) -> Path
when Type :: etc
| var
| tmp
| log
| lib,
PackageID :: zx:package_id(),
Path :: file:filename().
%% @private
%% An alias for path/4, but more convenient when needing a path from a closed
%% package_id().
ppath(Type, {Realm, Name, Version}) ->
path(Type, Realm, Name, Version).
-spec force_dir(Path) -> Result
when Path :: file:filename(),
Result :: ok
@ -134,6 +170,20 @@ force_dir(Path) ->
end.
-spec mktemp_dir(Package) -> Result
when Package :: zx:package(),
Result :: {ok, TempDir :: file:filename()}
| {error, Reason :: file:posix()}.
mktemp_dir({Realm, Name}) ->
Rand = integer_to_list(binary:decode_unsigned(crypto:strong_rand_bytes(8)), 36),
TempDir = filename:join(path(etc, Realm, Name), Rand),
case force_dir(TempDir) of
ok -> {ok, TempDir};
Error -> Error
end.
-spec hosts_cache_file(zx:realm()) -> file:filename().
%% @private
%% Given a Realm name, construct a realm's .hosts filename and return it.

File diff suppressed because it is too large Load Diff

2
zx_dev
View File

@ -12,4 +12,4 @@ export ZX_DIR="$ZOMP_DIR/lib/otpr/zx/$VERSION"
pushd "$ZX_DIR" > /dev/null
./make_zx
popd > /dev/null
erl -pa "$ZX_DIR/ebin" -run zx run $@
erl -noshell -pa "$ZX_DIR/ebin" -run zx do $@

15
zxh_dev Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
pushd $(dirname $BASH_SOURCE) > /dev/null
ZX_DEV_ROOT=$PWD
popd > /dev/null
export ZOMP_DIR="$ZX_DEV_ROOT/tester"
rm -rf "$ZOMP_DIR"
cp -r "$ZX_DEV_ROOT/zomp" "$ZOMP_DIR"
VERSION=$(cat "$ZOMP_DIR/etc/version.txt")
export ZX_DIR="$ZOMP_DIR/lib/otpr/zx/$VERSION"
pushd "$ZX_DIR" > /dev/null
./make_zx
popd > /dev/null
erl -pa "$ZX_DIR/ebin" -run zx do $@