Thinking about fetch
This commit is contained in:
parent
34656bef64
commit
3e3f72359a
164
zx
164
zx
@ -21,7 +21,7 @@
|
||||
{realm = "otpr" :: name(),
|
||||
name = none :: none | name(),
|
||||
version = {z, z, z} :: version(),
|
||||
type = app :: app | lib
|
||||
type = app :: app | lib,
|
||||
deps = [] :: [package_id()],
|
||||
dir = none :: none | file:filename(),
|
||||
socket = none :: none | gen_tcp:socket(),
|
||||
@ -139,49 +139,49 @@ start(_) ->
|
||||
%% procedure the runtime will halt with an error message.
|
||||
|
||||
run(Identifier, Args) ->
|
||||
PackageID = {Realm, Name, Version} = package_id(Identifier),
|
||||
{Realm, Name, Version} = package_id(Identifier),
|
||||
ok = file:set_cwd(zomp_dir()),
|
||||
PackageRoot = filename:join("lib", Identifier),
|
||||
State = #s{realm = Realm,
|
||||
name = Name,
|
||||
version = Version,
|
||||
dir = PackageRoot},
|
||||
NextState = ensure_installed(State),
|
||||
Meta = read_meta(PackageRoot),
|
||||
version = Version},
|
||||
NextState = #s{version = Installed} = ensure_installed(State),
|
||||
PackageID = {Realm, Name, Installed},
|
||||
Dir = filename:join("lib", package_string(PackageID)),
|
||||
Meta = read_meta(Dir),
|
||||
Deps = maps:get(deps, Meta),
|
||||
NewState = ensure_deps(NextState#s{deps = Deps}),
|
||||
execute(State).
|
||||
NewState = ensure_deps(NextState#s{dir = Dir, deps = Deps}),
|
||||
execute(NewState).
|
||||
|
||||
|
||||
Required = [PackageID | Deps],
|
||||
Needed = scrub(Required),
|
||||
Host = {"localhost", 11411},
|
||||
Socket = connect(Host, user),
|
||||
ok = fetch(Socket, Needed),
|
||||
ok = lists:foreach(fun install/1, Needed),
|
||||
ok = lists:foreach(fun build/1, Required),
|
||||
ok = file:set_cwd(PackageRoot),
|
||||
case maps:get(type, Meta) of
|
||||
app ->
|
||||
true = register(zx, self()),
|
||||
ok = inets:start(),
|
||||
ok = log(info, "Starting ~ts", [package_string(PackageID)]),
|
||||
PackageMod = list_to_atom(Name),
|
||||
{ok, Pid} = PackageMod:start(normal, Args),
|
||||
Mon = monitor(process, Pid),
|
||||
Shell = spawn(shell, start, []),
|
||||
ok = log(info, "Your shell is ~p, application is: ~p", [Shell, Pid]),
|
||||
State = #s{realm = Realm,
|
||||
name = Name,
|
||||
version = Version,
|
||||
pid = Pid,
|
||||
mon = Mon},
|
||||
exec_wait(State);
|
||||
lib ->
|
||||
Message = "Lib ~ts is available on the system, but is not a standalone app.",
|
||||
ok = log(info, Message, [package_string(PackageID)]),
|
||||
halt(0)
|
||||
end.
|
||||
% Required = [PackageID | Deps],
|
||||
% Needed = scrub(Required),
|
||||
% Host = {"localhost", 11411},
|
||||
% Socket = connect(Host, user),
|
||||
% ok = fetch(Socket, Needed),
|
||||
% ok = lists:foreach(fun install/1, Needed),
|
||||
% ok = lists:foreach(fun build/1, Required),
|
||||
% ok = file:set_cwd(PackageRoot),
|
||||
% case maps:get(type, Meta) of
|
||||
% app ->
|
||||
% true = register(zx, self()),
|
||||
% ok = inets:start(),
|
||||
% ok = log(info, "Starting ~ts", [package_string(PackageID)]),
|
||||
% PackageMod = list_to_atom(Name),
|
||||
% {ok, Pid} = PackageMod:start(normal, Args),
|
||||
% Mon = monitor(process, Pid),
|
||||
% Shell = spawn(shell, start, []),
|
||||
% ok = log(info, "Your shell is ~p, application is: ~p", [Shell, Pid]),
|
||||
% State = #s{realm = Realm,
|
||||
% name = Name,
|
||||
% version = Version,
|
||||
% pid = Pid,
|
||||
% mon = Mon},
|
||||
% exec_wait(State);
|
||||
% lib ->
|
||||
% Message = "Lib ~ts is available on the system, but is not a standalone app.",
|
||||
% ok = log(info, Message, [package_string(PackageID)]),
|
||||
% halt(0)
|
||||
% end.
|
||||
|
||||
|
||||
|
||||
@ -335,16 +335,55 @@ latest_version({Realm, Name, Version}) ->
|
||||
%% locating or acquiring the package fail, then exit with an error.
|
||||
|
||||
ensure_installed(State = #s{realm = Realm, name = Name, version = Version}) ->
|
||||
% If the startup style is to always check first, match for the exact version,
|
||||
% If the startup style is to run a matching latest and then check
|
||||
PackageString = package_string(PackageID),
|
||||
PackageDir = filename:join("lib", PackageString),
|
||||
case filelib:is_dir(PackageDir) of
|
||||
true -> ok;
|
||||
false -> ensure_dep(PackageID)
|
||||
case resolve_installed_version({Realm, Name, Version}) of
|
||||
exact -> State;
|
||||
{ok, Installed} -> State#s{version = Installed};
|
||||
not_found -> ensure_dep(State)
|
||||
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().
|
||||
%% @private
|
||||
%% 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),
|
||||
Host = {"localhost", 11411},
|
||||
Socket = connect(Host, user),
|
||||
ok = fetch(Socket, Needed),
|
||||
ok = lists:foreach(fun install/1, Needed),
|
||||
ok = lists:foreach(fun build/1, Deps),
|
||||
ok = file:set_cwd(ProjectRoot),
|
||||
% Needed = scrub(Deps),
|
||||
% Host = {"localhost", 11411},
|
||||
% Socket = connect(Host, user),
|
||||
% ok = fetch(Socket, Needed),
|
||||
% ok = lists:foreach(fun install/1, Needed),
|
||||
% ok = lists:foreach(fun build/1, Deps),
|
||||
% ok = file:set_cwd(ProjectRoot),
|
||||
|
||||
|
||||
|
||||
@ -751,7 +790,7 @@ submit(PackageFile) ->
|
||||
{package_id, {Realm, Package, Version}} = lists:keyfind(package_id, 1, Meta),
|
||||
{sig, {KeyID = {Realm, KeyName}, _}} = lists:keyfind(sig, 1, Meta),
|
||||
true = ensure_keypair(KeyID),
|
||||
{ok, Socket = connect_auth(Realm, KeyName),
|
||||
{ok, Socket} = connect_auth(Realm, KeyName),
|
||||
ok = send(Socket, {submit, {Realm, Package, Version}}),
|
||||
ok =
|
||||
receive
|
||||
@ -772,7 +811,7 @@ submit(PackageFile) ->
|
||||
ok =
|
||||
receive
|
||||
{tcp, Socket, Response2} ->
|
||||
log(info, "Response: ~tp", [Response2]);
|
||||
log(info, "Response: ~tp", [Response2])
|
||||
after 5000 ->
|
||||
log(warning, "Server timed out!")
|
||||
end,
|
||||
@ -1554,11 +1593,18 @@ build() ->
|
||||
scrub([]) ->
|
||||
[];
|
||||
scrub(Deps) ->
|
||||
{ok, Names} = file:list_dir("lib"),
|
||||
Existing = lists:map(fun package_id/1, Names),
|
||||
Need = ordsets:from_list(Deps),
|
||||
Have = ordsets:from_list(Existing),
|
||||
ordsets:to_list(ordsets:subtract(Need, Have)).
|
||||
lists:filter(fun(PackageID) -> not installed(PackageID) end, Deps).
|
||||
|
||||
|
||||
-spec installed(package_id()) -> boolean().
|
||||
%% @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