src/glipt@runner.erl
-module(glipt@runner).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glipt/runner.gleam").
-export([run/1]).
-export_type([run_error/0, run_options/0]).
-type run_error() :: {file_error, simplifile:file_error()} |
{build_error, binary()} |
{run_error, binary()}.
-type run_options() :: {run_options,
binary(),
glipt@target:target(),
binary(),
list(binary())}.
-file("src/glipt/runner.gleam", 60).
-spec setup_project(
binary(),
binary(),
binary(),
glipt@parser:script_meta(),
glipt@target:target(),
binary(),
binary()
) -> {ok, nil} | {error, run_error()}.
setup_project(Key, Script_path, Source, Meta, T, Function, Module_name) ->
Project_dir = glipt@internal@cache:cached_project_path(Key),
Src_dir = <<Project_dir/binary, "/src"/utf8>>,
gleam@result:'try'(
begin
_pipe = glipt@internal@cache:ensure_cache_dir(),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {file_error, Field@0} end
)
end,
fun(_) ->
gleam@result:'try'(
begin
_pipe@1 = simplifile:create_directory_all(Src_dir),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {file_error, Field@0} end
)
end,
fun(_) ->
Script_dir = glipt@internal@path:dirname(Script_path),
Toml_content = glipt@internal@toml:generate_runtime_toml(
Meta,
T,
Script_dir
),
gleam@result:'try'(
begin
_pipe@2 = simplifile:write(
<<Project_dir/binary, "/gleam.toml"/utf8>>,
Toml_content
),
gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {file_error, Field@0} end
)
end,
fun(_) ->
Dest = <<<<<<Src_dir/binary, "/"/utf8>>/binary,
Module_name/binary>>/binary,
".gleam"/utf8>>,
Clean_source = glipt@parser:strip_directives(Source),
gleam@result:'try'(
begin
_pipe@3 = simplifile:write(
Dest,
Clean_source
),
gleam@result:map_error(
_pipe@3,
fun(Field@0) -> {file_error, Field@0} end
)
end,
fun(_) -> gleam@result:'try'(case Function of
<<"main"/utf8>> ->
{ok, nil};
Func ->
Entry_source = <<<<<<<<<<<<"import "/utf8,
Module_name/binary>>/binary,
"\n\npub fn main() {\n "/utf8>>/binary,
Module_name/binary>>/binary,
"."/utf8>>/binary,
Func/binary>>/binary,
"()\n}\n"/utf8>>,
_pipe@4 = simplifile:write(
<<Src_dir/binary,
"/glipt_entry.gleam"/utf8>>,
Entry_source
),
gleam@result:map_error(
_pipe@4,
fun(Field@0) -> {file_error, Field@0} end
)
end, fun(_) ->
gleam@result:'try'(
begin
_pipe@5 = shellout:command(
<<"gleam"/utf8>>,
[<<"deps"/utf8>>,
<<"download"/utf8>>],
Project_dir,
[let_be_stderr]
),
gleam@result:map_error(
_pipe@5,
fun(E) ->
{build_error,
<<"deps download failed: "/utf8,
(erlang:element(
2,
E
))/binary>>}
end
)
end,
fun(_) ->
_pipe@6 = shellout:command(
<<"gleam"/utf8>>,
[<<"build"/utf8>>,
<<"--target"/utf8>>,
glipt@target:to_string(
T
)],
Project_dir,
[let_be_stderr]
),
_pipe@7 = gleam@result:map_error(
_pipe@6,
fun(E@1) ->
{build_error,
erlang:element(
2,
E@1
)}
end
),
gleam@result:map(
_pipe@7,
fun(_) -> nil end
)
end
)
end) end
)
end
)
end
)
end
).
-file("src/glipt/runner.gleam", 123).
-spec execute(binary(), binary(), glipt@target:target(), list(binary())) -> {ok,
binary()} |
{error, run_error()}.
execute(Key, Module_name, T, Script_args) ->
Project_dir = glipt@internal@cache:cached_project_path(Key),
Base_args = [<<"run"/utf8>>,
<<"--target"/utf8>>,
glipt@target:to_string(T),
<<"-m"/utf8>>,
Module_name],
Args = case Script_args of
[] ->
Base_args;
_ ->
lists:append(Base_args, [<<"--"/utf8>> | Script_args])
end,
_pipe = shellout:command(
<<"gleam"/utf8>>,
Args,
Project_dir,
[let_be_stderr]
),
gleam@result:map_error(
_pipe,
fun(E) -> {run_error, erlang:element(2, E)} end
).
-file("src/glipt/runner.gleam", 185).
-spec resolve_path_in_constraint(binary(), binary()) -> binary().
resolve_path_in_constraint(Constraint, Project_root) ->
case gleam@string:split_once(Constraint, <<"path"/utf8>>) of
{ok, {Before, After}} ->
case gleam@string:split_once(After, <<"\""/utf8>>) of
{ok, {Middle, Rest}} ->
case gleam@string:split_once(Rest, <<"\""/utf8>>) of
{ok, {Rel_path, End}} ->
Abs_path = case gleam_stdlib:string_starts_with(
Rel_path,
<<"/"/utf8>>
) of
true ->
Rel_path;
false ->
<<<<Project_root/binary, "/"/utf8>>/binary,
Rel_path/binary>>
end,
<<<<<<<<<<<<Before/binary, "path"/utf8>>/binary,
Middle/binary>>/binary,
"\""/utf8>>/binary,
Abs_path/binary>>/binary,
"\""/utf8>>/binary,
End/binary>>;
{error, nil} ->
Constraint
end;
{error, nil} ->
Constraint
end;
{error, nil} ->
Constraint
end.
-file("src/glipt/runner.gleam", 170).
-spec resolve_relative_paths(list(glipt@parser:dependency()), binary()) -> list(glipt@parser:dependency()).
resolve_relative_paths(Deps, Project_root) ->
gleam@list:map(
Deps,
fun(Dep) ->
case gleam_stdlib:contains_string(
erlang:element(3, Dep),
<<"path"/utf8>>
) of
true ->
Resolved = resolve_path_in_constraint(
erlang:element(3, Dep),
Project_root
),
{dependency, erlang:element(2, Dep), Resolved};
false ->
Dep
end
end
).
-file("src/glipt/runner.gleam", 139).
-spec maybe_inherit_host_deps(glipt@parser:script_meta(), binary()) -> glipt@parser:script_meta().
maybe_inherit_host_deps(Meta, Script_dir) ->
Has_directives = ((erlang:element(2, Meta) /= {error, nil}) orelse not gleam@list:is_empty(
erlang:element(4, Meta)
))
orelse not gleam@list:is_empty(erlang:element(3, Meta)),
case Has_directives of
true ->
Meta;
false ->
case glipt@internal@project:find_project_root(Script_dir) of
{error, nil} ->
Meta;
{ok, Root} ->
case simplifile:read(<<Root/binary, "/gleam.toml"/utf8>>) of
{error, _} ->
Meta;
{ok, Content} ->
Deps = glipt@internal@toml:parse_deps(Content),
Resolved_deps = resolve_relative_paths(Deps, Root),
Gleam_constraint = glipt@internal@toml:parse_gleam_version(
Content
),
{script_meta, Gleam_constraint, [], Resolved_deps}
end
end
end.
-file("src/glipt/runner.gleam", 28).
-spec run(run_options()) -> {ok, binary()} | {error, run_error()}.
run(Opts) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(erlang:element(2, Opts)),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {file_error, Field@0} end
)
end,
fun(Source) ->
Parsed = glipt@parser:parse(Source),
Script_dir = glipt@internal@path:dirname(erlang:element(2, Opts)),
Meta = maybe_inherit_host_deps(Parsed, Script_dir),
Key = glipt@internal@cache:cache_key(Source, Meta),
Module_name = glipt@internal@path:drop_extension(
glipt@internal@path:basename(erlang:element(2, Opts))
),
Entry_module = case erlang:element(4, Opts) of
<<"main"/utf8>> ->
Module_name;
_ ->
<<"glipt_entry"/utf8>>
end,
case glipt@internal@cache:is_cached(Key) of
true ->
execute(
Key,
Entry_module,
erlang:element(3, Opts),
erlang:element(5, Opts)
);
false ->
gleam@result:'try'(
setup_project(
Key,
erlang:element(2, Opts),
Source,
Meta,
erlang:element(3, Opts),
erlang:element(4, Opts),
Module_name
),
fun(_) ->
execute(
Key,
Entry_module,
erlang:element(3, Opts),
erlang:element(5, Opts)
)
end
)
end
end
).