Current section

Files

Jump to
ierl src ierl_cmd_install.erl
Raw

src/ierl_cmd_install.erl

-module(ierl_cmd_install).
-export([
exec/4,
opt_spec/0
]).
opt_spec() ->
{
"Install a Jupyter kernelspec for this backend",
[
{name, $n, "name", string, "Install the kernel under this name "
"(defaults to the backend name)"
},
{copy, $c, "copy", boolean, "Copy the escript to make a standalone "
"kernel"},
{node, undefined, "node", string, "Remote node to run against"},
{sname, undefined, "sname", string, "Short name for this node "
"(defaults to the backend name)"},
{cookie, undefined, "cookie", string, "Cookie"},
{directory, undefined, "output", string, "Instead of using "
"jupyter kernelspec to install, just write to the given directory"},
{replace, undefined, "replace", boolean, "Replace an existing kernel "
"spec with this name"},
{user, undefined, "user", boolean, "Install to the per-user kernel "
"registry"},
{prefix, undefined, "prefix", string, "Specify a prefix to install to, "
"e.g. an env. The kernelspec will be installed in "
"PREFIX/share/jupyter/kernels/"}
]
}.
exec({BName, Backend}, ParsedArgs, BackendArgs, BackendSpec) ->
application:ensure_all_started(jsx),
% TODO: Default to BName_Node
Copy = maps:get(copy, ParsedArgs, false),
BackendArgs1 = lists:foldl(
fun (OptSpec, Res) ->
Key = element(1, OptSpec),
Name = element(3, OptSpec),
case maps:get(Key, BackendArgs, undefined) of
undefined ->
Res;
Value ->
Res#{ Name => Value }
end
end,
#{},
BackendSpec
),
% TODO: Nicer generated name instead of BName
Name = case maps:get(name, ParsedArgs, undefined) of
undefined ->
case maps:get(node, ParsedArgs, undefined) of
undefined ->
BName;
NodeName ->
NodeName1 = string:to_lower(NodeName),
NodeName2 = re:replace(NodeName1, "[^a-z_0-9]",
"_"),
io_lib:format("~s_~s", [BName, NodeName2])
end;
NameInner ->
NameInner
end,
DisplayName =
case jup_util:call_if_exported(Backend, display_name, [BackendArgs1],
undefined) of
undefined ->
atom_to_list(BName);
DisplayNameInner ->
DisplayNameInner
end,
DisplayName1 =
case DisplayName of
undefined ->
Name;
_ ->
io_lib:format("~s (~s)", [DisplayName, Name])
end,
Args = #{
display_name => DisplayName1,
backend => Backend,
backend_name => BName,
copy => Copy,
args => BackendArgs1
},
Args1 = lists:foldl(
fun (PName, A) ->
forward_arg(PName, ParsedArgs, A)
end,
Args,
[node, sname]
),
Args2 = case maps:get(cookie, ParsedArgs, undefined) of
undefined ->
Args1;
Val ->
Args1#{
env => #{
'IERL_COOKIE' => jup_util:ensure_binary(Val)
}
}
end,
{Path, Install, Delete} =
case maps:get(directory, ParsedArgs, undefined) of
undefined ->
{mochitemp:mkdtemp(), true, true};
Dir ->
{jup_util:ensure_binary(Dir), false, false}
end,
FullPath = filename:join(Path, Name),
io:format("Writing kernel spec to ~s...~n", [FullPath]),
ierl_kernelspec:create(Args2#{ path => FullPath }),
case Install of
true ->
io:format("Installing kernelspec ~s...~n", [Name]),
JKArgs = [kernelspec, install, FullPath]
++
case maps:get(replace, ParsedArgs, undefined) of
true ->
["--replace"];
_ ->
[]
end
++
case maps:get(user, ParsedArgs, undefined) of
true ->
["--user"];
_ ->
[]
end
++
case maps:get(prefix, ParsedArgs, undefined) of
Prefix when is_list(Prefix) ->
["--prefix", Prefix];
_ ->
[]
end,
case ierl_exec:exec(jupyter, JKArgs) of
{ok, _} ->
io:format("Successfully installed kernelspec~n");
{error, _, Data} ->
io:format("Failed installing:~n~n~s~n", [Data])
end;
_ ->
ok
end,
case Delete of
true ->
io:format("Cleaning up temporary path...~n"),
mochitemp:rmtempdir(Path);
_ ->
ok
end.
forward_arg(Name, ParsedArgs, Args) ->
case maps:get(Name, ParsedArgs, undefined) of
undefined ->
Args;
Val ->
Args#{
args => maps:put(Name, Val, maps:get(args, Args, #{})),
Name => Val
}
end.