Thinking about fetch
This commit is contained in:
parent
34656bef64
commit
3e3f72359a
164
zx
164
zx
@ -21,7 +21,7 @@
|
|||||||
{realm = "otpr" :: name(),
|
{realm = "otpr" :: name(),
|
||||||
name = none :: none | name(),
|
name = none :: none | name(),
|
||||||
version = {z, z, z} :: version(),
|
version = {z, z, z} :: version(),
|
||||||
type = app :: app | lib
|
type = app :: app | lib,
|
||||||
deps = [] :: [package_id()],
|
deps = [] :: [package_id()],
|
||||||
dir = none :: none | file:filename(),
|
dir = none :: none | file:filename(),
|
||||||
socket = none :: none | gen_tcp:socket(),
|
socket = none :: none | gen_tcp:socket(),
|
||||||
@ -139,49 +139,49 @@ start(_) ->
|
|||||||
%% procedure the runtime will halt with an error message.
|
%% procedure the runtime will halt with an error message.
|
||||||
|
|
||||||
run(Identifier, Args) ->
|
run(Identifier, Args) ->
|
||||||
PackageID = {Realm, Name, Version} = package_id(Identifier),
|
{Realm, Name, Version} = package_id(Identifier),
|
||||||
ok = file:set_cwd(zomp_dir()),
|
ok = file:set_cwd(zomp_dir()),
|
||||||
PackageRoot = filename:join("lib", Identifier),
|
|
||||||
State = #s{realm = Realm,
|
State = #s{realm = Realm,
|
||||||
name = Name,
|
name = Name,
|
||||||
version = Version,
|
version = Version},
|
||||||
dir = PackageRoot},
|
NextState = #s{version = Installed} = ensure_installed(State),
|
||||||
NextState = ensure_installed(State),
|
PackageID = {Realm, Name, Installed},
|
||||||
Meta = read_meta(PackageRoot),
|
Dir = filename:join("lib", package_string(PackageID)),
|
||||||
|
Meta = read_meta(Dir),
|
||||||
Deps = maps:get(deps, Meta),
|
Deps = maps:get(deps, Meta),
|
||||||
NewState = ensure_deps(NextState#s{deps = Deps}),
|
NewState = ensure_deps(NextState#s{dir = Dir, deps = Deps}),
|
||||||
execute(State).
|
execute(NewState).
|
||||||
|
|
||||||
|
|
||||||
Required = [PackageID | Deps],
|
% Required = [PackageID | Deps],
|
||||||
Needed = scrub(Required),
|
% Needed = scrub(Required),
|
||||||
Host = {"localhost", 11411},
|
% Host = {"localhost", 11411},
|
||||||
Socket = connect(Host, user),
|
% Socket = connect(Host, user),
|
||||||
ok = fetch(Socket, Needed),
|
% ok = fetch(Socket, Needed),
|
||||||
ok = lists:foreach(fun install/1, Needed),
|
% ok = lists:foreach(fun install/1, Needed),
|
||||||
ok = lists:foreach(fun build/1, Required),
|
% ok = lists:foreach(fun build/1, Required),
|
||||||
ok = file:set_cwd(PackageRoot),
|
% ok = file:set_cwd(PackageRoot),
|
||||||
case maps:get(type, Meta) of
|
% case maps:get(type, Meta) of
|
||||||
app ->
|
% app ->
|
||||||
true = register(zx, self()),
|
% true = register(zx, self()),
|
||||||
ok = inets:start(),
|
% ok = inets:start(),
|
||||||
ok = log(info, "Starting ~ts", [package_string(PackageID)]),
|
% ok = log(info, "Starting ~ts", [package_string(PackageID)]),
|
||||||
PackageMod = list_to_atom(Name),
|
% PackageMod = list_to_atom(Name),
|
||||||
{ok, Pid} = PackageMod:start(normal, Args),
|
% {ok, Pid} = PackageMod:start(normal, Args),
|
||||||
Mon = monitor(process, Pid),
|
% Mon = monitor(process, Pid),
|
||||||
Shell = spawn(shell, start, []),
|
% Shell = spawn(shell, start, []),
|
||||||
ok = log(info, "Your shell is ~p, application is: ~p", [Shell, Pid]),
|
% ok = log(info, "Your shell is ~p, application is: ~p", [Shell, Pid]),
|
||||||
State = #s{realm = Realm,
|
% State = #s{realm = Realm,
|
||||||
name = Name,
|
% name = Name,
|
||||||
version = Version,
|
% version = Version,
|
||||||
pid = Pid,
|
% pid = Pid,
|
||||||
mon = Mon},
|
% mon = Mon},
|
||||||
exec_wait(State);
|
% exec_wait(State);
|
||||||
lib ->
|
% lib ->
|
||||||
Message = "Lib ~ts is available on the system, but is not a standalone app.",
|
% Message = "Lib ~ts is available on the system, but is not a standalone app.",
|
||||||
ok = log(info, Message, [package_string(PackageID)]),
|
% ok = log(info, Message, [package_string(PackageID)]),
|
||||||
halt(0)
|
% halt(0)
|
||||||
end.
|
% end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -335,16 +335,55 @@ latest_version({Realm, Name, Version}) ->
|
|||||||
%% locating or acquiring the package fail, then exit with an error.
|
%% locating or acquiring the package fail, then exit with an error.
|
||||||
|
|
||||||
ensure_installed(State = #s{realm = Realm, name = Name, version = Version}) ->
|
ensure_installed(State = #s{realm = Realm, name = Name, version = Version}) ->
|
||||||
% If the startup style is to always check first, match for the exact version,
|
case resolve_installed_version({Realm, Name, Version}) of
|
||||||
% If the startup style is to run a matching latest and then check
|
exact -> State;
|
||||||
PackageString = package_string(PackageID),
|
{ok, Installed} -> State#s{version = Installed};
|
||||||
PackageDir = filename:join("lib", PackageString),
|
not_found -> ensure_dep(State)
|
||||||
case filelib:is_dir(PackageDir) of
|
|
||||||
true -> ok;
|
|
||||||
false -> ensure_dep(PackageID)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
-spec resolve_installed_version(PackageID) -> Result
|
||||||
|
when PackageID :: package_id(),
|
||||||
|
Result :: not_found
|
||||||
|
| exact
|
||||||
|
| {ok, Installed :: version()}.
|
||||||
|
%% @private
|
||||||
|
%% Resolve the provided PackageID to the latest matching installed package directory version
|
||||||
|
%% if one exists, returning a value that indicates whether an exact match was found (in the
|
||||||
|
%% case of a full version input), a version matching a partial version input was found, or no
|
||||||
|
%% match was found at all.
|
||||||
|
|
||||||
|
resolve_installed_version(PackageID) ->
|
||||||
|
PackageString = package_string(PackageID),
|
||||||
|
Pattern = PackageString ++ "*",
|
||||||
|
case filelib:wildcard(Pattern, "lib") of
|
||||||
|
[] ->
|
||||||
|
not_found;
|
||||||
|
[PackageString] ->
|
||||||
|
exact;
|
||||||
|
[Dir] ->
|
||||||
|
{_, _, Version} = package_id(Dir),
|
||||||
|
{ok, Versoin};
|
||||||
|
Dirs ->
|
||||||
|
Dir = lists:last(lists:sort(Dirs)),
|
||||||
|
{_, _, Version} = package_id(Dir),
|
||||||
|
{ok, Version}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
ensure_deps(State = #s{realm = Realm, deps = Deps, socket = MaybeSocket}) ->
|
||||||
|
case scrub(Deps) of
|
||||||
|
[] ->
|
||||||
|
State;
|
||||||
|
Needed ->
|
||||||
|
Sorted = lists:sort(Needed),
|
||||||
|
Partition =
|
||||||
|
fun(D = {R, _, _}, M) ->
|
||||||
|
maps:update_with(R, fun(Ds) -> [D | Ds] end, [D], M)
|
||||||
|
end,
|
||||||
|
Partitioned = lists:foldl(Partition, #{}, Needed),
|
||||||
|
|
||||||
|
|
||||||
-spec ensure_dep(package_id()) -> ok | no_return().
|
-spec ensure_dep(package_id()) -> ok | no_return().
|
||||||
%% @private
|
%% @private
|
||||||
%% Given an PackageID as an argument, check whether its package file exists in the
|
%% Given an PackageID as an argument, check whether its package file exists in the
|
||||||
@ -581,13 +620,13 @@ execute(State = #s{type = lib}) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Needed = scrub(Deps),
|
% Needed = scrub(Deps),
|
||||||
Host = {"localhost", 11411},
|
% Host = {"localhost", 11411},
|
||||||
Socket = connect(Host, user),
|
% Socket = connect(Host, user),
|
||||||
ok = fetch(Socket, Needed),
|
% ok = fetch(Socket, Needed),
|
||||||
ok = lists:foreach(fun install/1, Needed),
|
% ok = lists:foreach(fun install/1, Needed),
|
||||||
ok = lists:foreach(fun build/1, Deps),
|
% ok = lists:foreach(fun build/1, Deps),
|
||||||
ok = file:set_cwd(ProjectRoot),
|
% ok = file:set_cwd(ProjectRoot),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -751,7 +790,7 @@ submit(PackageFile) ->
|
|||||||
{package_id, {Realm, Package, Version}} = lists:keyfind(package_id, 1, Meta),
|
{package_id, {Realm, Package, Version}} = lists:keyfind(package_id, 1, Meta),
|
||||||
{sig, {KeyID = {Realm, KeyName}, _}} = lists:keyfind(sig, 1, Meta),
|
{sig, {KeyID = {Realm, KeyName}, _}} = lists:keyfind(sig, 1, Meta),
|
||||||
true = ensure_keypair(KeyID),
|
true = ensure_keypair(KeyID),
|
||||||
{ok, Socket = connect_auth(Realm, KeyName),
|
{ok, Socket} = connect_auth(Realm, KeyName),
|
||||||
ok = send(Socket, {submit, {Realm, Package, Version}}),
|
ok = send(Socket, {submit, {Realm, Package, Version}}),
|
||||||
ok =
|
ok =
|
||||||
receive
|
receive
|
||||||
@ -772,7 +811,7 @@ submit(PackageFile) ->
|
|||||||
ok =
|
ok =
|
||||||
receive
|
receive
|
||||||
{tcp, Socket, Response2} ->
|
{tcp, Socket, Response2} ->
|
||||||
log(info, "Response: ~tp", [Response2]);
|
log(info, "Response: ~tp", [Response2])
|
||||||
after 5000 ->
|
after 5000 ->
|
||||||
log(warning, "Server timed out!")
|
log(warning, "Server timed out!")
|
||||||
end,
|
end,
|
||||||
@ -1554,11 +1593,18 @@ build() ->
|
|||||||
scrub([]) ->
|
scrub([]) ->
|
||||||
[];
|
[];
|
||||||
scrub(Deps) ->
|
scrub(Deps) ->
|
||||||
{ok, Names} = file:list_dir("lib"),
|
lists:filter(fun(PackageID) -> not installed(PackageID) end, Deps).
|
||||||
Existing = lists:map(fun package_id/1, Names),
|
|
||||||
Need = ordsets:from_list(Deps),
|
|
||||||
Have = ordsets:from_list(Existing),
|
-spec installed(package_id()) -> boolean().
|
||||||
ordsets:to_list(ordsets:subtract(Need, Have)).
|
%% @private
|
||||||
|
%% True to its name, returns `true' if the package is installed (its directory found),
|
||||||
|
%% `false' otherwise.
|
||||||
|
|
||||||
|
installed(PackageID) ->
|
||||||
|
PackageString = package_string(PackageID),
|
||||||
|
PackageDir = filename:join("lib", PackageString),
|
||||||
|
filelib:is_dir(PackageDir).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user