-module(go_over). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([main/0]). -export_type([flags/0]). -type flags() :: {flags, boolean(), boolean(), boolean()}. -spec spin_up() -> flags(). spin_up() -> _assert_subject = go_over@yaml:start(), {ok, _} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"go_over"/utf8>>, function => <<"spin_up"/utf8>>, line => 23}) end, Args = shellout_ffi:start_arguments(), Flags = {flags, gleam@list:any(Args, fun(Arg) -> Arg =:= <<"--skip"/utf8>> end), gleam@list:any(Args, fun(Arg@1) -> Arg@1 =:= <<"--force"/utf8>> end), gleam@list:any(Args, fun(Arg@2) -> Arg@2 =:= <<"--fake"/utf8>> end)}, go_over@util:iffnil( erlang:element(3, Flags) andalso erlang:element(2, Flags), fun() -> go_over@print:warning( <<"Cannot specify both `--skip` & `--force`"/utf8>> ), shellout_ffi:os_exit(1) end ), Flags. -spec get_vulnerable_packages( list(go_over@packages:package()), go_over@config:config(), flags() ) -> list(go_over@warning:warning()). get_vulnerable_packages(Pkgs, Conf, Flags) -> _pipe = go_over@advisories:check_for_advisories( Pkgs, not erlang:element(2, Flags) ), _pipe@1 = gleam@list:map( _pipe, fun(P) -> {Pkg, Adv} = P, {Pkg, go_over@config:filter_advisory_ids(Conf, Adv)} end ), _pipe@2 = gleam@list:filter(_pipe@1, fun(P@1) -> case P@1 of {_, []} -> false; _ -> true end end), gleam@list:map( _pipe@2, fun(P@2) -> {Pkg@1, Adv@1} = P@2, go_over@warning:adv_to_warning(Pkg@1, Adv@1) end ). -spec get_retired_packges(list(go_over@packages:package()), flags()) -> list(go_over@warning:warning()). get_retired_packges(Pkgs, Flags) -> _pipe = Pkgs, _pipe@1 = gleam@list:map( _pipe, fun(Pkg) -> case go_over@retired:check_retired( Pkg, not erlang:element(2, Flags) ) of {some, Ret} -> {some, {Pkg, Ret}}; none -> none end end ), _pipe@2 = gleam@option:values(_pipe@1), gleam@list:map( _pipe@2, fun(P) -> {Pkg@1, Ret@1} = P, go_over@warning:retired_to_warning(Pkg@1, Ret@1) end ). -spec print_warnings(list(go_over@warning:warning())) -> nil. print_warnings(Vulns) -> _pipe = (<<<<<<"⛔ "/utf8, (gleam@int:to_string(erlang:length(Vulns)))/binary>>/binary, " WARNING(s) FOUND!"/utf8>>/binary, (<<"\n-----------------------------------------------\n"/utf8>>)/binary>>), gleam@io:print(_pipe), _pipe@1 = Vulns, _pipe@2 = gleam@list:map(_pipe@1, fun go_over@warning:format_as_string/1), _pipe@3 = gleam@string:join( _pipe@2, <<"\n-----------------------------------------------\n"/utf8>> ), gleam@io:print(_pipe@3), shellout_ffi:os_exit(1). -spec main() -> nil. main() -> Flags = spin_up(), Conf = go_over@config:read_config(<<"./gleam.toml"/utf8>>), go_over@util:throwaway( erlang:element(3, Flags) orelse not erlang:element(2, Conf), fun() -> simplifile:delete(go_over@constants:go_over_path()) end ), Pkgs = begin _pipe = go_over@packages:read_manifest(<<"./manifest.toml"/utf8>>), go_over@config:filter_packages(Conf, _pipe) end, Vulnerable_packages = get_vulnerable_packages(Pkgs, Conf, Flags), Retired_packages = get_retired_packges(Pkgs, Flags), go_over@util:iffnil( erlang:element(4, Flags), fun() -> print_warnings( [{warning, <<"fake"/utf8>>, <<"x.y.z"/utf8>>, <<"Retired"/utf8>>, vulnerable, <<"Critical"/utf8>>, direct}, {warning, <<"another_fake"/utf8>>, <<"1.2.3"/utf8>>, <<"Vulnerabe"/utf8>>, vulnerable, <<"High"/utf8>>, direct}, {warning, <<"and_another"/utf8>>, <<"4.5.6"/utf8>>, <<"Vulnerabe"/utf8>>, vulnerable, <<"Moderate"/utf8>>, direct}, {warning, <<"one_more"/utf8>>, <<"7.8.9"/utf8>>, <<"Vulnerabe"/utf8>>, vulnerable, <<"LOW"/utf8>>, indirect}, {warning, <<"this_one_was_retired"/utf8>>, <<"10.11.12"/utf8>>, <<"Retired"/utf8>>, retired, <<"Package Retired"/utf8>>, indirect}] ) end ), Warnings = begin _pipe@1 = lists:append(Retired_packages, Vulnerable_packages), go_over@config:filter_severity(Conf, _pipe@1) end, case Warnings of [] -> go_over@print:success(<<"✅ All good! ✨"/utf8>>); Vulns -> print_warnings(Vulns) end.