-module(chrobot@install). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([install_with_config/2, install/0, main/0]). -export_type([installation_error/0, version_item/0, download_item/0]). -type installation_error() :: installation_error. -type version_item() :: {version_item, binary(), binary(), list(download_item())}. -type download_item() :: {download_item, binary(), binary()}. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 300). -spec select_version(binary(), list(version_item())) -> {ok, version_item()} | {error, nil}. select_version(Target, Version_list) -> case Target of <<"latest"/utf8>> -> gleam@list:last(Version_list); _ -> case gleam_stdlib:contains_string(Target, <<"."/utf8>>) of true -> gleam@list:find( Version_list, fun(Item) -> erlang:element(2, Item) =:= Target end ); false -> _pipe = lists:reverse(Version_list), gleam@list:find( _pipe, fun(Item@1) -> case gleam@string:split( erlang:element(2, Item@1), <<"."/utf8>> ) of [Major | _] when Major =:= Target -> true; _ -> false end end ) end end. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 329). -spec select_download(version_item(), binary()) -> {ok, download_item()} | {error, nil}. select_download(Version, Platform) -> gleam@list:find( erlang:element(4, Version), fun(Item) -> erlang:element(2, Item) =:= Platform end ). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 333). -spec parse_version_list(gleam@dynamic:dynamic_()) -> {ok, list(version_item())} | {error, list(gleam@dynamic:decode_error())}. parse_version_list(Input) -> Download_item_decoder = gleam@dynamic:decode2( fun(Field@0, Field@1) -> {download_item, Field@0, Field@1} end, gleam@dynamic:field(<<"platform"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"url"/utf8>>, fun gleam@dynamic:string/1) ), Download_list_item_decoder = fun(List_item) -> (gleam@dynamic:field( <<"chrome"/utf8>>, gleam@dynamic:list(Download_item_decoder) ))(List_item) end, Version_item_decoder = gleam@dynamic:decode3( fun(Field@0, Field@1, Field@2) -> {version_item, Field@0, Field@1, Field@2} end, gleam@dynamic:field(<<"version"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"revision"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"downloads"/utf8>>, Download_list_item_decoder) ), (gleam@dynamic:field( <<"versions"/utf8>>, gleam@dynamic:list(Version_item_decoder) ))(Input). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 390). -spec assert_is_json( gleam@http@response:response(any()), binary(), fun(() -> {ok, ALTX} | {error, installation_error()}) ) -> {ok, ALTX} | {error, installation_error()}. assert_is_json(Res, Human_error, Fun) -> case gleam@http@response:get_header(Res, <<"content-type"/utf8>>) of {ok, <<"application/json"/utf8>>} -> Fun(); {ok, <<"application/json"/utf8, _/binary>>} -> Fun(); _ -> gleam_stdlib:println(<<""/utf8>>), chrobot@internal@utils:err(Human_error), {error, installation_error} end. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 406). -spec assert_ok( {ok, ALUB} | {error, any()}, binary(), fun((ALUB) -> {ok, ALUF} | {error, installation_error()}) ) -> {ok, ALUF} | {error, installation_error()}. assert_ok(Result, Human_error, Fun) -> case Result of {ok, X} -> Fun(X); {error, Err} -> gleam_stdlib:println(<<""/utf8>>), chrobot@internal@utils:err(Human_error), gleam@io:debug(Err), {error, installation_error} end. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 422). -spec assert_true( boolean(), binary(), fun(() -> {ok, ALUK} | {error, installation_error()}) ) -> {ok, ALUK} | {error, installation_error()}. assert_true(Condition, Human_error, Fun) -> case Condition of true -> Fun(); false -> gleam_stdlib:println(<<""/utf8>>), chrobot@internal@utils:err(Human_error), {error, installation_error} end. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 492). -spec new_download_request(binary()) -> {ok, gleam@http@request:request(bitstring())} | {error, nil}. new_download_request(Url) -> gleam@result:'try'( gleam@http@request:to(Url), fun(Base_req) -> {ok, gleam@http@request:set_body(Base_req, <<>>)} end ). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 354). -spec resolve_platform() -> {ok, binary()} | {error, binary()}. resolve_platform() -> case {gleam_erlang_ffi:os_family(), chrobot_ffi:get_arch()} of {darwin, <<"aarch64"/utf8, _/binary>>} -> {ok, <<"mac-arm64"/utf8>>}; {darwin, _} -> {ok, <<"mac-x64"/utf8>>}; {linux, <<"x86_64"/utf8, _/binary>>} -> gleam_stdlib:println(<<""/utf8>>), chrobot@internal@utils:warn( <<"You appear to be on linux, just to let you know, dependencies are not installed automatically by this script, you must install them yourself! Please check the docs of the install module for further information."/utf8>> ), {ok, <<"linux64"/utf8>>}; {windows_nt, <<"x86_64"/utf8, _/binary>>} -> {ok, <<"win64"/utf8>>}; {windows_nt, _} -> chrobot@internal@utils:warn( <<"The installer thinks you are on a 32-bit Windows system and is installing 32-bit Chrome, this is unusual, please verify this is correct"/utf8>> ), {ok, <<"win32"/utf8>>}; {_, Architecture} -> chrobot@internal@utils:err( <<<<"Could not resolve an appropriate platform for your system. Please note that the available platforms are limited by what Google Chrome for Testing supports, notably, ARM64 on Linux is unfortunately not supported at the moment. Your architecture is: "/utf8, Architecture/binary>>/binary, "."/utf8>> ), {error, <<"Unsupported system: "/utf8, Architecture/binary>>} end. -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 444). -spec unzip(binary(), binary()) -> {ok, nil} | {error, nil}. unzip(From, To) -> chrobot_ffi:run_command( <<<<<<"unzip -q "/utf8, From/binary>>/binary, " -d "/utf8>>/binary, To/binary>> ), gleam@result:'try'( begin _pipe = simplifile_erl:read_directory(To), gleam@result:replace_error(_pipe, nil) end, fun(Installation_dir_entries) -> Was_extracted = begin _pipe@1 = gleam@list:map( Installation_dir_entries, fun(I) -> simplifile_erl:is_directory(filepath:join(To, I)) end ), gleam@list:any(_pipe@1, fun(Check) -> case Check of {ok, true} -> true; _ -> false end end) end, case Was_extracted of true -> {ok, nil}; false -> chrobot@internal@utils:warn( <<"Failed to extract downloaded .zip archive using system unzip command, falling back to erlang unzip. You might run into permission issues when attempting to run the installed binary, this is not ideal!"/utf8>> ), gleam@result:'try'( chrobot_ffi:unzip(From, To), fun(_) -> gleam@result:'try'( begin _pipe@2 = simplifile:get_files(To), gleam@result:replace_error(_pipe@2, nil) end, fun(Installation_files) -> gleam@list:each( Installation_files, fun(I@1) -> case simplifile_erl:is_file(I@1) of {ok, true} -> _ = chrobot_ffi:set_executable( I@1 ), nil; _ -> nil end end ), {ok, nil} end ) end ) end end ). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 123). -spec install_with_config(binary(), binary()) -> {ok, binary()} | {error, installation_error()}. install_with_config(Target_path, Target_version) -> Chrome_dir_path = filepath:join(Target_path, <<"chrome"/utf8>>), Chrome_dir_path@1 = case Chrome_dir_path of <<"./chrome"/utf8>> -> <<"chrome"/utf8>>; Other -> Other end, gleam_stdlib:println( <<<<<<<<"\nPreparing to install Chrome for Testing ("/utf8, Target_version/binary>>/binary, ") into "/utf8>>/binary, Chrome_dir_path@1/binary>>/binary, ".\n"/utf8>> ), case chrobot@chrome:get_local_chrome_path_at(Chrome_dir_path@1) of {ok, Local_chrome_path} -> chrobot@internal@utils:warn( <<<<"You already have a local Chrome installation at this path:\n"/utf8, Local_chrome_path/binary>>/binary, " Chrobot does not support managing multiple browser installations, you are encouraged to remove old installations manually if you no longer need them."/utf8>> ); {error, _} -> nil end, assert_ok( resolve_platform(), <<"Platform unsupported"/utf8>>, fun(Platform) -> P = chrobot@internal@utils:start_progress( <<"Fetching available versions..."/utf8>> ), assert_ok( gleam@http@request:to( <<"https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"/utf8>> ), <<"Failed to build version request"/utf8>>, fun(Req) -> assert_ok( gleam@httpc:send(Req), <<"Version list request failed, ensure you have an active internet connection."/utf8>>, fun(Res) -> assert_true( erlang:element(2, Res) =:= 200, <<"Version list request returned a non-200 status code."/utf8>>, fun() -> assert_is_json( Res, <<"Version list request returned a response that is not JSON."/utf8>>, fun() -> assert_ok( gleam@json:decode( erlang:element(4, Res), fun gleam@dynamic:dynamic/1 ), <<"Failed to parse version list JSON"/utf8>>, fun(Payload) -> assert_ok( parse_version_list( Payload ), <<"Failed to decode version list JSON - Maybe the API has changed or is down?"/utf8>>, fun(Version_list) -> assert_ok( select_version( Target_version, Version_list ), <<<<"Failed to find version "/utf8, Target_version/binary>>/binary, " in version list"/utf8>>, fun(Version) -> assert_ok( select_download( Version, Platform ), <<<<<<"Failed to find download for platform "/utf8, Platform/binary>>/binary, " in version "/utf8>>/binary, (erlang:element( 2, Version ))/binary>>, fun( Download ) -> chrobot@internal@utils:stop_progress( P ), gleam_stdlib:println( <<<<<<<<"\nSelected version "/utf8, (erlang:element( 2, Version ))/binary>>/binary, " for platform "/utf8>>/binary, (erlang:element( 2, Download ))/binary>>/binary, "\n"/utf8>> ), P@1 = chrobot@internal@utils:start_progress( <<"Downloading Chrome for Testing..."/utf8>> ), assert_ok( new_download_request( erlang:element( 3, Download ) ), <<"Failed to build download request"/utf8>>, fun( Download_request ) -> assert_ok( gleam@httpc:send_bits( Download_request ), <<"Download request failed, ensure you have an active internet connection"/utf8>>, fun( Download_res ) -> assert_true( erlang:element( 2, Download_res ) =:= 200, <<"Download request returned a non-200 status code"/utf8>>, fun( ) -> chrobot@internal@utils:set_progress( P@1, <<"Writing download to disk..."/utf8>> ), Download_path = filepath:join( Chrome_dir_path@1, <<<<<<"chrome_download_"/utf8, (erlang:element( 2, Download ))/binary>>/binary, (erlang:element( 3, Version ))/binary>>/binary, ".zip"/utf8>> ), Installation_dir = filepath:join( Chrome_dir_path@1, <<<>/binary, (erlang:element( 2, Version ))/binary>> ), assert_ok( simplifile:create_directory_all( Installation_dir ), <<"Failed to create directory"/utf8>>, fun( _ ) -> assert_ok( simplifile_erl:write_bits( Download_path, erlang:element( 4, Download_res ) ), <<"Failed to write download to disk"/utf8>>, fun( _ ) -> chrobot@internal@utils:set_progress( P@1, <<"Extracting download..."/utf8>> ), assert_ok( unzip( Download_path, Installation_dir ), <<"Failed to extract downloaded .zip archive"/utf8>>, fun( _ ) -> assert_ok( simplifile_erl:delete( Download_path ), <<"Failed to remove downloaded .zip archive! The installation should otherwise have succeeded."/utf8>>, fun( _ ) -> assert_ok( simplifile:get_files( Installation_dir ), <<"Failed to scan installation directory for executable"/utf8>>, fun( Haystack ) -> assert_ok( gleam@list:find( Haystack, fun( File ) -> chrobot@chrome:is_local_chrome_path( File, gleam_erlang_ffi:os_family( ) ) end ), <<"Failed to find executable in installation directory"/utf8>>, fun( Executable ) -> chrobot@internal@utils:stop_progress( P@1 ), case gleam_erlang_ffi:os_family( ) of linux -> chrobot@internal@utils:hint( <<"You can run the following command to check wich depencies are missing on your system:"/utf8>> ), chrobot@internal@utils:show_cmd( <<<<"ldd \""/utf8, Executable/binary>>/binary, "\" | grep not"/utf8>> ); _ -> nil end, chrobot@internal@utils:info( <<<<<<<<<<"Chrome for Testing ("/utf8, (erlang:element( 2, Version ))/binary>>/binary, ") installed successfully! The executable is located at:\n"/utf8>>/binary, Executable/binary>>/binary, "\n"/utf8>>/binary, "When using the `launch` command, chrobot should automatically use this local installation."/utf8>> ), {ok, Executable} end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end ). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 113). -spec install() -> {ok, binary()} | {error, installation_error()}. install() -> Target_version = gleam@result:unwrap( envoy_ffi:get(<<"CHROBOT_TARGET_VERSION"/utf8>>), <<"latest"/utf8>> ), Target_path = gleam@result:unwrap( envoy_ffi:get(<<"CHROBOT_TARGET_PATH"/utf8>>), <<"."/utf8>> ), install_with_config(Target_path, Target_version). -file("/Users/jonas/Projects/chrobot/src/chrobot/install.gleam", 106). -spec main() -> {ok, binary()} | {error, installation_error()}. main() -> install().