Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package protontricks for openSUSE:Factory checked in at 2024-08-15 09:58:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/protontricks (Old) and /work/SRC/openSUSE:Factory/.protontricks.new.7232 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "protontricks" Thu Aug 15 09:58:13 2024 rev:3 rq:1193888 version:1.11.1 Changes: -------- --- /work/SRC/openSUSE:Factory/protontricks/protontricks.changes 2024-01-06 17:29:28.368267979 +0100 +++ /work/SRC/openSUSE:Factory/.protontricks.new.7232/protontricks.changes 2024-08-15 09:58:38.747769717 +0200 @@ -1,0 +2,11 @@ +Wed Aug 14 14:20:55 UTC 2024 - Ralf Habacker <ralf.habac...@freenet.de> + +- Update to version 1.11.1: + * Fix Protontricks crash when custom Proton has an invalid or + empty compatibilitytool.vdf manifest + * Fix Protontricks GUI crash when Proton installation is + incomplete + * Check if Steam Runtime launcher service launched correctly + instead of always assuming successful launch + +------------------------------------------------------------------- Old: ---- protontricks-1.11.0.tar.xz New: ---- protontricks-1.11.1.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ protontricks.spec ++++++ --- /var/tmp/diff_new_pack.hoHvil/_old 2024-08-15 09:58:39.195788311 +0200 +++ /var/tmp/diff_new_pack.hoHvil/_new 2024-08-15 09:58:39.195788311 +0200 @@ -19,7 +19,7 @@ %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} Name: protontricks -Version: 1.11.0 +Version: 1.11.1 Release: 0 Summary: Winetricks for Proton-enabled Games License: GPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.hoHvil/_old 2024-08-15 09:58:39.227789639 +0200 +++ /var/tmp/diff_new_pack.hoHvil/_new 2024-08-15 09:58:39.231789805 +0200 @@ -2,7 +2,7 @@ <service name="tar_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/Matoking/protontricks.git</param> - <param name="revision">1.11.0</param> + <param name="revision">1.11.1</param> <param name="versionformat">@PARENT_TAG@</param> <param name="package-meta">yes</param> </service> ++++++ protontricks-1.11.0.tar.xz -> protontricks-1.11.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/HEAD new/protontricks-1.11.1/.git/HEAD --- old/protontricks-1.11.0/.git/HEAD 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/HEAD 2024-02-20 17:37:34.000000000 +0100 @@ -1 +1 @@ -3bb249616cf528bdb83e3a2f511e1c8fb1edb681 +aa6b0c3b9a06a5493da8ae1f1c67c959737e9971 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/ORIG_HEAD new/protontricks-1.11.1/.git/ORIG_HEAD --- old/protontricks-1.11.0/.git/ORIG_HEAD 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/ORIG_HEAD 2024-02-20 17:37:34.000000000 +0100 @@ -1 +1 @@ -3bb249616cf528bdb83e3a2f511e1c8fb1edb681 +aa6b0c3b9a06a5493da8ae1f1c67c959737e9971 Binary files old/protontricks-1.11.0/.git/index and new/protontricks-1.11.1/.git/index differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/logs/HEAD new/protontricks-1.11.1/.git/logs/HEAD --- old/protontricks-1.11.0/.git/logs/HEAD 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/logs/HEAD 2024-02-20 17:37:34.000000000 +0100 @@ -1,2 +1,2 @@ -0000000000000000000000000000000000000000 de708dca61eaf7c79db100b6703516bb2f89801b Ralf Habacker <ralf.habac...@freenet.de> 1704495096 +0100 clone: from https://github.com/Matoking/protontricks.git -de708dca61eaf7c79db100b6703516bb2f89801b 3bb249616cf528bdb83e3a2f511e1c8fb1edb681 Ralf Habacker <ralf.habac...@freenet.de> 1704495096 +0100 checkout: moving from master to 1.11.0 +0000000000000000000000000000000000000000 3d019caa387ed7aaca01242550c4b9be8c15c7b2 Ralf Habacker <ralf.habac...@freenet.de> 1723645239 +0200 clone: from https://github.com/Matoking/protontricks.git +3d019caa387ed7aaca01242550c4b9be8c15c7b2 aa6b0c3b9a06a5493da8ae1f1c67c959737e9971 Ralf Habacker <ralf.habac...@freenet.de> 1723645239 +0200 checkout: moving from master to 1.11.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/logs/refs/heads/master new/protontricks-1.11.1/.git/logs/refs/heads/master --- old/protontricks-1.11.0/.git/logs/refs/heads/master 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/logs/refs/heads/master 2024-02-20 17:37:34.000000000 +0100 @@ -1 +1 @@ -0000000000000000000000000000000000000000 de708dca61eaf7c79db100b6703516bb2f89801b Ralf Habacker <ralf.habac...@freenet.de> 1704495096 +0100 clone: from https://github.com/Matoking/protontricks.git +0000000000000000000000000000000000000000 3d019caa387ed7aaca01242550c4b9be8c15c7b2 Ralf Habacker <ralf.habac...@freenet.de> 1723645239 +0200 clone: from https://github.com/Matoking/protontricks.git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/logs/refs/remotes/origin/HEAD new/protontricks-1.11.1/.git/logs/refs/remotes/origin/HEAD --- old/protontricks-1.11.0/.git/logs/refs/remotes/origin/HEAD 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/logs/refs/remotes/origin/HEAD 2024-02-20 17:37:34.000000000 +0100 @@ -1 +1 @@ -0000000000000000000000000000000000000000 de708dca61eaf7c79db100b6703516bb2f89801b Ralf Habacker <ralf.habac...@freenet.de> 1704495096 +0100 clone: from https://github.com/Matoking/protontricks.git +0000000000000000000000000000000000000000 3d019caa387ed7aaca01242550c4b9be8c15c7b2 Ralf Habacker <ralf.habac...@freenet.de> 1723645239 +0200 clone: from https://github.com/Matoking/protontricks.git Binary files old/protontricks-1.11.0/.git/objects/pack/pack-2b55d5325ea91c6b8981a2d2b3f6b654533f2e0d.idx and new/protontricks-1.11.1/.git/objects/pack/pack-2b55d5325ea91c6b8981a2d2b3f6b654533f2e0d.idx differ Binary files old/protontricks-1.11.0/.git/objects/pack/pack-2b55d5325ea91c6b8981a2d2b3f6b654533f2e0d.pack and new/protontricks-1.11.1/.git/objects/pack/pack-2b55d5325ea91c6b8981a2d2b3f6b654533f2e0d.pack differ Binary files old/protontricks-1.11.0/.git/objects/pack/pack-65fddce3fbc102a27d07d12079d399eef77c9fa3.idx and new/protontricks-1.11.1/.git/objects/pack/pack-65fddce3fbc102a27d07d12079d399eef77c9fa3.idx differ Binary files old/protontricks-1.11.0/.git/objects/pack/pack-65fddce3fbc102a27d07d12079d399eef77c9fa3.pack and new/protontricks-1.11.1/.git/objects/pack/pack-65fddce3fbc102a27d07d12079d399eef77c9fa3.pack differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/packed-refs new/protontricks-1.11.1/.git/packed-refs --- old/protontricks-1.11.0/.git/packed-refs 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/packed-refs 2024-02-20 17:37:34.000000000 +0100 @@ -1,8 +1,13 @@ # pack-refs with: peeled fully-peeled sorted +b8099d2ed11706d5865d3883155992c630fea2f1 refs/remotes/origin/add_developer_name dea5c89fd6a856bee1e961ab946ba25945dc89cf refs/remotes/origin/add_sniper 19778ae5962f00f6983eb272f46b185660dd81ad refs/remotes/origin/app_type +f7b1fa33b0438dbd72f7222703f8442e40edc510 refs/remotes/origin/appinfo_v29 6bea9ae5fc90b7588d87a17acb2b83b6e15469f1 refs/remotes/origin/better_error_messages +28b8213781f1e146530279fd31b459c6fcef2833 refs/remotes/origin/check_launcher_start +b03877242769a389fb00d63b9866c8faa626be33 refs/remotes/origin/check_mount_noexec 9bb35cbdd6f29a16cf8364160f5d09cd64683087 refs/remotes/origin/clean_imports +61b147951eb343ae59ae3509e6199497fa089f37 refs/remotes/origin/config_vdf_parse_fix 03df9c3cba9c69411fdb34dc1252137ebb99c539 refs/remotes/origin/debug_logging db1876d40d592959eee62a3b57aff191c85587a5 refs/remotes/origin/detect_custom_icon fd93e458aacb7cb423a96947eae50f187c83d382 refs/remotes/origin/detect_xdg_perms @@ -10,9 +15,11 @@ db2796b04aada41e8940698ada152f43c9aa778f refs/remotes/origin/duplicate_fix 96f253d1e3d7684c97cec1e8fbeb1f3f78a3155e refs/remotes/origin/fix_app_mapping_detection a041b89af0a8f6f505f9676d80d8eb79d7aa68f8 refs/remotes/origin/fix_appinfo +e2a7871fca664305a284cef31a36a693b05d23b6 refs/remotes/origin/fix_appmanifest 425b954f4c3b25e295339f4f6df2c7e64de5705d refs/remotes/origin/fix_bg_wineserver_output 392a07cadaa2055551a9fa0509e85034a8019bb7 refs/remotes/origin/fix_bwrap_launcher 064f3a91dec219918ff9194d69f47d5190f0d59a refs/remotes/origin/fix_deprecated_socket +e7a54129bd47a8526bb45c60a12da2a2e6089c82 refs/remotes/origin/fix_gui_error f54e1fc5867807b4b5601ae785007d182f3396aa refs/remotes/origin/fix_help 7a2e3eb47ef3af0083babf0b80c952c29c99215b refs/remotes/origin/fix_icon_size 52e6e31b229ddca1f0683a6a0329297db4995421 refs/remotes/origin/fix_jpeg_convert @@ -24,28 +31,37 @@ 308fb280237445a5c1b4c50c9890adb361599b99 refs/remotes/origin/fix_xauthority_crash ab4d7f61231620f7339188ffeceaa376982a3a9d refs/remotes/origin/flatpak 11eb97e6c79c8b0827786a243d871c07ee18de46 refs/remotes/origin/flatpak_fix +4852aae049acee036768391b3c452c8ae8859ba5 refs/remotes/origin/grant-h-patch de708dca61eaf7c79db100b6703516bb2f89801b refs/remotes/origin/ignore_empty_compatibilitytool 6ad27720e8c475a0f3361e0dd506b0a1cc186da7 refs/remotes/origin/ignore_permission 12e427c570e39d0dc383edef7aa319460f46496c refs/remotes/origin/ignore_remaining_vdf 1d03f022f0db99896dfed23fa50ed0caac6f60aa refs/remotes/origin/interoperable_flatpak 9f35f4dbd72643756a4804da0f03039afaed2373 refs/remotes/origin/keep_wineserver_alive 68af8545189748b3342691302ee1718a75963b07 refs/remotes/origin/lenient_jpeg_parse +f2d605d1255ce87f4343aacb82d063d7cd954966 refs/remotes/origin/less_jargon 26952aeeb961ec09499a7923da7a51fc9695f852 refs/remotes/origin/log_compatibilitytool -de708dca61eaf7c79db100b6703516bb2f89801b refs/remotes/origin/master +3d019caa387ed7aaca01242550c4b9be8c15c7b2 refs/remotes/origin/master ace41890f10b6e075916a48e510b8f51335350b4 refs/remotes/origin/name_update 68f965f2876bb532cb68447ac4be248cd39b9c76 refs/remotes/origin/new_runtime_names 0b884635a48a2ec8cc4ffb2ae04aa3dd584e16ff refs/remotes/origin/no_wine_launcher_poll 65218290c7638ac4f9cf00e6d4a318d0272b32c0 refs/remotes/origin/pressure_vessel_launcher 490faf58d7ed54c25158bb46e0af489c795c10a5 refs/remotes/origin/prompt_steam_dir cdc8414e09fe2db34aecc2f90c180cf5b90df073 refs/remotes/origin/python311 +f75d57b3880d295bfe5a8637a6151db3763ba1f5 refs/remotes/origin/python312 55bd0ee04b64d9bbf2fc2e3e5e4fd436a5df4a7c refs/remotes/origin/python35_fix +3d019caa387ed7aaca01242550c4b9be8c15c7b2 refs/remotes/origin/readme_beta +fc78dc19f2f4286ccb3a06e4d689b44164596384 refs/remotes/origin/remove_install_wd 6572ba3b3bacf5e6b3e09cf88f4d9cb8f0873938 refs/remotes/origin/remove_old_appinfo c8dd5d41a4b677542ef91fed919f5e5c692f07ca refs/remotes/origin/return_status b78f098793c38308529bb9c641a1284ffffa1889 refs/remotes/origin/revert_dbus 4c9c8d4270f66961ffe53c532fa2fdeeb14ac19b refs/remotes/origin/secure_ci 3a57bc6bbfb039abd7fe623b25a29c277e064f9c refs/remotes/origin/standalone_flatpak 8c5a41f9d3e25bb031b753b0b2f07d37f2b85c70 refs/remotes/origin/steam_find_fix +4852aae049acee036768391b3c452c8ae8859ba5 refs/remotes/origin/test +d3d6dc9122a9b319d0ee4518114ec984d2c101a6 refs/remotes/origin/tolerate_compatibilitytool_issues +8076c02e5f0b75fbd98635ad13cac2a1f3b2375b refs/remotes/origin/update_issue_template d73477db34728b598f721c524032427b3571d566 refs/remotes/origin/update_template +1dabf82868f7a6a67f6aa87f74c4c067c641140a refs/remotes/origin/validate_appstream 3c482d13e6219bb4cb871ee05b0973118d02ba2c refs/tags/1.0 2b639ce66529cc3df18c955a3531139752401145 refs/tags/1.1 b3f6f7484d47341476a4556567ba782ae2eb7d40 refs/tags/1.1.1 @@ -63,6 +79,8 @@ ^77afe738935a56fc629a88593999bf52534723ea 94ef1e9d7e78182c1b6e82dc6e9b119e21bddd81 refs/tags/1.11.0 ^3bb249616cf528bdb83e3a2f511e1c8fb1edb681 +760f995b9dea354a3d548ec0f87271ded2dacfd7 refs/tags/1.11.1 +^aa6b0c3b9a06a5493da8ae1f1c67c959737e9971 be279a8a51a361b8177a2b806f233baa2b2fd584 refs/tags/1.2 f62eeab4f10e5a6a3370202556b8f171b41f20f4 refs/tags/1.2.1 7f90359eb6fbbc84b57b2e6ef374535c7a9ecf95 refs/tags/1.2.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.git/refs/heads/master new/protontricks-1.11.1/.git/refs/heads/master --- old/protontricks-1.11.0/.git/refs/heads/master 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.git/refs/heads/master 2024-02-20 17:37:34.000000000 +0100 @@ -1 +1 @@ -de708dca61eaf7c79db100b6703516bb2f89801b +3d019caa387ed7aaca01242550c4b9be8c15c7b2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/.github/ISSUE_TEMPLATE/bug_report.md new/protontricks-1.11.1/.github/ISSUE_TEMPLATE/bug_report.md --- old/protontricks-1.11.0/.github/ISSUE_TEMPLATE/bug_report.md 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/.github/ISSUE_TEMPLATE/bug_report.md 2024-02-20 17:37:34.000000000 +0100 @@ -26,6 +26,8 @@ **Additional context** -**If the error happens when trying to run a Protontricks command, run the command again using the `-v` flag and copy the output!** +**If the error happens when trying to run a Protontricks command, run the command again using the `-vv` flag and copy the output!** -For example, if the command that causes the error is `protontricks 42 faudio`, run `protontricks -v 42 faudio` instead and copy the output here. +For example, if the command that causes the error is `protontricks 42 faudio`, run `protontricks -vv 42 faudio` instead and copy the output here. + +If the output is very long, consider creating a gist using [gist.github.com](https://gist.github.com/). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/CHANGELOG.md new/protontricks-1.11.1/CHANGELOG.md --- old/protontricks-1.11.0/CHANGELOG.md 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/CHANGELOG.md 2024-02-20 17:37:34.000000000 +0100 @@ -4,6 +4,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [1.11.1] - 2024-02-20 +### Fixed + - Fix Protontricks crash when custom Proton has an invalid or empty `compatibilitytool.vdf` manifest + - Fix Protontricks GUI crash when Proton installation is incomplete + - Check if Steam Runtime launcher service launched correctly instead of always assuming successful launch + ## [1.11.0] - 2023-12-30 ### Added - Show app icons for custom shortcuts in the app selector @@ -278,7 +284,8 @@ ### Added - The last release of Protontricks maintained by [@Sirmentio](https://github.com/Sirmentio). -[Unreleased]: https://github.com/Matoking/protontricks/compare/1.11.0...HEAD +[Unreleased]: https://github.com/Matoking/protontricks/compare/1.11.1...HEAD +[1.11.1]: https://github.com/Matoking/protontricks/compare/1.11.0...1.11.1 [1.11.0]: https://github.com/Matoking/protontricks/compare/1.10.5...1.11.0 [1.10.5]: https://github.com/Matoking/protontricks/compare/1.10.4...1.10.5 [1.10.4]: https://github.com/Matoking/protontricks/compare/1.10.3...1.10.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/data/com.github.Matoking.protontricks.metainfo.xml new/protontricks-1.11.1/data/com.github.Matoking.protontricks.metainfo.xml --- old/protontricks-1.11.0/data/com.github.Matoking.protontricks.metainfo.xml 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/data/com.github.Matoking.protontricks.metainfo.xml 2024-02-20 17:37:34.000000000 +0100 @@ -36,6 +36,7 @@ <metadata_license>CC0-1.0</metadata_license> <update_contact>janne.pulkki...@protonmail.com</update_contact> <releases> + <release version="1.11.1" date="2024-02-20"/> <release version="1.11.0" date="2023-12-30"/> <release version="1.10.5" date="2023-09-05"/> <release version="1.10.4" date="2023-08-26"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/src/protontricks/cli/launch.py new/protontricks-1.11.1/src/protontricks/cli/launch.py --- old/protontricks-1.11.0/src/protontricks/cli/launch.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/src/protontricks/cli/launch.py 2024-02-20 17:37:34.000000000 +0100 @@ -176,7 +176,7 @@ cli_args += ["--no-term"] inner_args = " ".join( - ["wine", f"'{executable_path}'"] + ["wine", shlex.quote(str(executable_path))] + exec_args ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/src/protontricks/cli/main.py new/protontricks-1.11.1/src/protontricks/cli/main.py --- old/protontricks-1.11.0/src/protontricks/cli/main.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/src/protontricks/cli/main.py 2024-02-20 17:37:34.000000000 +0100 @@ -280,6 +280,13 @@ if not proton_app: exit_("Proton installation could not be found!") + if not proton_app.is_proton_ready: + exit_( + "Proton installation is incomplete. Have you launched a Steam " + "app using this Proton version at least once to finish the " + "installation?" + ) + run_command( winetricks_path=winetricks_path, proton_app=proton_app, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/src/protontricks/steam.py new/protontricks-1.11.1/src/protontricks/steam.py --- old/protontricks-1.11.0/src/protontricks/steam.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/src/protontricks/steam.py 2024-02-20 17:37:34.000000000 +0100 @@ -1007,24 +1007,40 @@ ) continue + if not vdf_data: + logger.warning( + "Compatibility tool declaration at %s is empty. You may need " + "to reinstall the application.", + vdf_path + ) + continue + # Traverse to 'compatibilitytools/compat_tools' in a case-insensitive # way. This is done because we can't turn all keys recursively to # lowercase from the get-go; the app name is stored as a key. - compat_tools = {k.lower(): v for k, v in vdf_data.items()} - compat_tools = compat_tools["compatibilitytools"] - compat_tools = { - k.lower(): v for k, v in compat_tools.items() - } - compat_tools = compat_tools["compat_tools"] - internal_name = list(compat_tools.keys())[0] - tool_info = compat_tools[internal_name] + try: + compat_tools = {k.lower(): v for k, v in vdf_data.items()} + compat_tools = compat_tools["compatibilitytools"] + compat_tools = { + k.lower(): v for k, v in compat_tools.items() + } + compat_tools = compat_tools["compat_tools"] + internal_name = list(compat_tools.keys())[0] + tool_info = compat_tools[internal_name] - # We can now convert the remainder into lowercase - tool_info = lower_dict(tool_info) + # We can now convert the remainder into lowercase + tool_info = lower_dict(tool_info) - install_path_name = tool_info["install_path"] - from_oslist = tool_info["from_oslist"] - to_oslist = tool_info["to_oslist"] + install_path_name = tool_info["install_path"] + from_oslist = tool_info["from_oslist"] + to_oslist = tool_info["to_oslist"] + except KeyError: + logger.warning( + "Compatibility tool declaration at %s is incomplete. You may " + "need to reinstall the application", + vdf_path + ) + continue if from_oslist != "windows" or to_oslist != "linux": continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/src/protontricks/util.py new/protontricks-1.11.1/src/protontricks/util.py --- old/protontricks-1.11.0/src/protontricks/util.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/src/protontricks/util.py 2024-02-20 17:37:34.000000000 +0100 @@ -6,7 +6,7 @@ import stat import tempfile from pathlib import Path -from subprocess import DEVNULL, PIPE, Popen, check_output, run +from subprocess import DEVNULL, PIPE, Popen, TimeoutExpired, check_output, run import pkg_resources @@ -504,11 +504,23 @@ # The Steam Runtime launcher service will write to the given # file descriptor and then close it to indicate the launcher is - # ready. + # ready or about to exit (i.e. due to wrong CLI parameters). os.close(launcher_write_fd) with open(launcher_read_fd, "rb") as reader: reader.read() - # Launcher has finished starting up once output is returned + + # Check if the launcher actually started up and is still running. + try: + launcher_process.wait(timeout=0.1) + # Launcher process crashed, bail out + raise RuntimeError( + f"bwrap launcher crashed, " + f"returncode: {launcher_process.returncode}" + ) + except TimeoutExpired: + # Launcher is running as expected + pass + logger.info("bwrap launcher started") if start_wineserver: @@ -535,14 +547,14 @@ finally: shutil.rmtree(str(temp_dir), ignore_errors=True) - if start_wineserver: + if keepalive_process: logger.info( "Terminating wineserver keepalive process %d", keepalive_process.pid ) keepalive_process.terminate() - if use_bwrap: + if launcher_process: logger.info( "Terminating launcher process %d", launcher_process.pid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/cli/test_desktop_install.py new/protontricks-1.11.1/tests/cli/test_desktop_install.py --- old/protontricks-1.11.0/tests/cli/test_desktop_install.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/cli/test_desktop_install.py 2024-02-20 17:37:34.000000000 +0100 @@ -1,11 +1,11 @@ -def test_run_desktop_install(home_dir, commands, desktop_install_cli): +def test_run_desktop_install(home_dir, command_mock, desktop_install_cli): """ Ensure that `desktop-file-install` is called properly """ # `protontricks-desktop-install` takes no arguments desktop_install_cli([]) - command = commands[0] + command = command_mock.commands[0] assert command.args[0:3] == [ "desktop-file-install", "--dir", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/cli/test_launch.py new/protontricks-1.11.1/tests/cli/test_launch.py --- old/protontricks-1.11.0/tests/cli/test_launch.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/cli/test_launch.py 2024-02-20 17:37:34.000000000 +0100 @@ -15,7 +15,7 @@ class TestCLIRun: def test_run_executable( self, steam_app_factory, default_proton, - commands, gui_provider, launch_cli): + command_mock, gui_provider, launch_cli): """ Run an EXE file by selecting using the GUI """ @@ -27,14 +27,14 @@ launch_cli(["test.exe"]) # 'test.exe' was executed - command = commands[-1] + command = command_mock.commands[-1] assert command.args.startswith("wine ") - assert command.args.endswith("/test.exe'") + assert command.args.endswith("/test.exe") assert command.env["WINEPREFIX"] == str(steam_app.prefix_path) def test_run_executable_appid( - self, default_proton, steam_app_factory, commands, launch_cli): + self, default_proton, steam_app_factory, command_mock, launch_cli): """ Run an EXE file directly for a chosen game """ @@ -43,9 +43,9 @@ launch_cli(["--appid", "10", "test.exe"]) # 'test.exe' was executed - command = commands[-1] + command = command_mock.commands[-1] assert command.args.startswith("wine ") - assert command.args.endswith("/test.exe'") + assert command.args.endswith("/test.exe") assert command.env["WINEPREFIX"] == str(steam_app.prefix_path) @@ -123,7 +123,7 @@ "--no-background-wineserver", "--no-term", "-c" ] assert cli_args[6].startswith("wine ") - assert cli_args[6].endswith("test.exe'") + assert cli_args[6].endswith("test.exe") assert cli_args[7] == "10" # Steam installation was provided to the main entrypoint @@ -192,7 +192,9 @@ assert b"Test appmanifest error" in message - @pytest.mark.usefixtures("flatpak_sandbox", "default_proton", "commands") + @pytest.mark.usefixtures( + "flatpak_sandbox", "default_proton", "command_mock" + ) def test_run_filesystem_permission_missing( self, launch_cli, steam_library_factory, steam_app_factory, caplog): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/cli/test_main.py new/protontricks-1.11.1/tests/cli/test_main.py --- old/protontricks-1.11.0/tests/cli/test_main.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/cli/test_main.py 2024-02-20 17:37:34.000000000 +0100 @@ -7,7 +7,7 @@ class TestCLIRun: def test_run_winetricks( - self, cli, steam_app_factory, default_proton, commands, + self, cli, steam_app_factory, default_proton, command_mock, home_dir): """ Perform a Protontricks command directly for a certain game @@ -19,7 +19,7 @@ cli(["10", "winecfg"], env={"STEAM_RUNTIME": "0"}) # winecfg was actually run - command = commands[-1] + command = command_mock.commands[-1] assert str(command.args[0]).endswith(".local/bin/winetricks") assert command.args[1] == "winecfg" @@ -38,7 +38,7 @@ ) def test_run_winetricks_shortcut( - self, cli, shortcut_factory, default_proton, commands, + self, cli, shortcut_factory, default_proton, command_mock, steam_dir): """ Perform a Protontricks command for a non-Steam shortcut @@ -49,14 +49,14 @@ cli(["4149337689", "winecfg"]) # Default Proton is used - command = commands[-1] + command = command_mock.commands[-1] assert command.env["PROTON_PATH"] == str(proton_install_path) assert command.env["WINEPREFIX"] == str( steam_dir / "steamapps" / "compatdata" / "4149337689" / "pfx") def test_run_winetricks_select_proton( self, cli, steam_app_factory, default_proton, - custom_proton_factory, commands, home_dir): + custom_proton_factory, command_mock, home_dir): """ Perform a Protontricks command while selecting a specific Proton version using PROTON_VERSION env var @@ -65,11 +65,11 @@ custom_proton = custom_proton_factory(name="Custom Proton") cli(["10", "winecfg"], env={"PROTON_VERSION": "Custom Proton"}) - assert commands[-1].env["PROTON_PATH"] \ + assert command_mock.commands[-1].env["PROTON_PATH"] \ == str(custom_proton.install_path) def test_run_winetricks_select_steam( - self, cli, steam_app_factory, default_proton, commands, + self, cli, steam_app_factory, default_proton, command_mock, home_dir): """ Perform a Protontricks command while selecting a specific @@ -90,7 +90,7 @@ env={"STEAM_DIR": str(home_dir / ".steam_new")} ) - command = commands[-1] + command = command_mock.commands[-1] assert command.env["WINE"] == str( home_dir / ".cache" / "protontricks" / "proton" / "Proton 4.20" / "bin" / "wine" @@ -102,7 +102,7 @@ def test_run_winetricks_steam_runtime_v1( self, cli, steam_app_factory, steam_runtime_dir, default_proton, - commands, home_dir): + command_mock, home_dir): """ Perform a Protontricks command using the older Steam Runtime bundled with Steam @@ -117,7 +117,7 @@ ) # winecfg was actually run - command = commands[-1] + command = command_mock.commands[-1] assert str(command.args[0]).endswith(".local/bin/winetricks") assert command.args[1] == "winecfg" assert command.env["PATH"].startswith(str(wine_bin_dir)) @@ -146,7 +146,7 @@ def test_run_winetricks_steam_runtime_v2( self, cli, home_dir, steam_app_factory, steam_runtime_dir, - steam_runtime_soldier, commands, proton_factory, caplog): + steam_runtime_soldier, command_mock, proton_factory, caplog): """ Perform a Protontricks command using a newer Steam Runtime that is installed as its own application @@ -166,10 +166,11 @@ # Launcher process was launched to handle launching processes # inside the sandbox - assert commands[0].args[0] == str(wine_bin_dir / "bwrap-launcher") + assert command_mock.commands[0].args[0] \ + == str(wine_bin_dir / "bwrap-launcher") # winecfg was run - command = commands[-1] + command = command_mock.commands[-1] assert str(command.args[0]).endswith(".local/bin/winetricks") assert command.args[1] == "winecfg" @@ -211,7 +212,7 @@ def test_run_winetricks_steam_runtime_v2_no_bwrap( self, cli, home_dir, steam_app_factory, steam_runtime_dir, - steam_runtime_soldier, commands, proton_factory, caplog): + steam_runtime_soldier, command_mock, proton_factory, caplog): """ Perform a Protontricks command using a newer Steam Runtime *without* bwrap that is installed as its own application @@ -229,7 +230,7 @@ / "bin" ) - command = commands[-1] + command = command_mock.commands[-1] # winecfg was run assert str(command.args[0]).endswith(".local/bin/winetricks") assert command.args[1] == "winecfg" @@ -302,7 +303,7 @@ ] ) def test_run_background_wineserver_toggle( - self, cli, steam_app_factory, default_new_proton, commands, + self, cli, steam_app_factory, default_new_proton, command_mock, args, wineserver_launched, home_dir): """ Try running a Protontricks command with different arguments @@ -314,7 +315,7 @@ cli(args) wineserver_found = any( - True for command in commands + True for command in command_mock.commands if isinstance(command.args, str) and command.args == str( home_dir / ".cache/protontricks/proton/Proton 7.0/bin" @@ -351,9 +352,9 @@ steam_app_factory(name="Fake game", appid=10) cli(["-c", "exit 5", "10"], expect_returncode=5) - def test_run_multiple_commands(self, cli): + def test_run_multiple_command_mock(self, cli): """ - Try performing multiple commands at once + Try performing multiple command_mock at once """ result = cli(["--gui", "-s", "game"]) @@ -616,12 +617,12 @@ assert record.levelname == "WARNING" assert str(path) in record.message - @pytest.mark.usefixtures("commands") + @pytest.mark.usefixtures("command_mock") def test_run_bwrap_default( self, cli, steam_app_factory, steam_runtime_soldier, - proton_factory, commands, caplog): + proton_factory, command_mock, caplog): """ - Perform commands for two Proton apps, one using a Proton version + Perform command_mock for two Proton apps, one using a Proton version using the legacy Steam Runtime and another app using newer Steam Runtime with bwrap. Ensure that the correct default for `use_bwrap` is used in both cases. @@ -718,7 +719,7 @@ class TestCLIGUI: def test_run_gui( self, cli, default_proton, steam_app_factory, gui_provider, - commands, home_dir): + command_mock, home_dir): """ Start the GUI and fake selecting a game """ @@ -730,7 +731,7 @@ cli(["--gui"]) - command = commands[-1] + command = command_mock.commands[-1] # 'winetricks --gui' was run for the game selected by user assert str(command.args[0]) == \ str(home_dir / ".local" / "bin" / "winetricks") @@ -760,11 +761,30 @@ assert "Found no games" in result + def test_run_gui_proton_incomplete( + self, cli, steam_app_factory, default_proton, gui_provider): + """ + Try running Protontricks GUI using a Proton installation that + is incomplete because it hasn't been launched yet. + """ + # Remove the 'dist' directory to make the Proton installation + # incomplete + shutil.rmtree(str(default_proton.install_path / "dist")) + + steam_app_factory(name="Fake game", appid=10) + + # Fake the user selecting the game + gui_provider.mock_stdout = "Fake game 1: 10" + + result = cli(["--gui"], expect_returncode=1) + + assert "Proton installation is incomplete" in result + class TestCLICommand: def test_run_command( self, cli, default_proton, steam_app_factory, gui_provider, - commands, home_dir): + command_mock, home_dir): """ Run a shell command for a given game """ @@ -773,7 +793,7 @@ cli(["-c", "bash", "10"]) - command = commands[-1] + command = command_mock.commands[-1] # The command is just 'bash' assert command.args == "bash" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/conftest.py new/protontricks-1.11.1/tests/conftest.py --- old/protontricks-1.11.0/tests/conftest.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/conftest.py 2024-02-20 17:37:34.000000000 +0100 @@ -5,7 +5,7 @@ import zlib from collections import defaultdict from pathlib import Path -from subprocess import run +from subprocess import run, TimeoutExpired import pytest import vdf @@ -45,6 +45,11 @@ logging.getLogger("protontricks").handlers.clear() +@pytest.fixture(scope="function", autouse=True) +def default_caplog(caplog): + caplog.set_level(logging.INFO) + + @pytest.fixture(scope="function") def info_logging(): """ @@ -776,8 +781,9 @@ class MockSubprocess: def __init__( - self, args=None, kwargs=None, mock_stdout=None, check=False, - cwd=None, shell=False, env=None, **_): + self, args=None, kwargs=None, mock_stdout=None, + launcher_alive=True, check=False, cwd=None, shell=False, env=None, + **_): self.args = args self.kwargs = kwargs self.check = check @@ -791,13 +797,26 @@ else: self.mock_stdout = mock_stdout + # The state of the mocked 'bwrap-launcher'. This will be set to False + # once 'terminate()' is called on the corresponding Popen object to + # mock the launcher stopping. + self.launcher_alive = launcher_alive + self.env = env - def wait(self): - pass + def wait(self, timeout=None): + name = self.args[0] + if name.endswith("bwrap-launcher"): + if self.launcher_alive: + raise TimeoutExpired(name, timeout=timeout) + else: + # Fake launcher crashing + self.returncode = 1 def terminate(self): - pass + name = self.args[0] + if name.endswith("bwrap-launcher"): + self.launcher_alive = False class MockResult: @@ -831,13 +850,19 @@ yield mock_gui_provider +class CommandMock: + def __init__(self): + self.commands = [] + self.launcher_working = True + + @pytest.fixture(scope="function") -def commands(monkeypatch): +def command_mock(monkeypatch): """ - Fixture containing all the commands called using subprocess during - the test run + Fixture to mock all subprocess calls. Returns instance containing + command history. """ - commands_ = [] + command_mock = CommandMock() def mock_subprocess_run(*args, **kwargs): try: @@ -853,17 +878,20 @@ mock_command = MockSubprocess( *args, - **kwargs + **{**kwargs, **{"launcher_alive": command_mock.launcher_working}} ) - commands_.append(mock_command) + command_mock.commands.append(mock_command) return MockResult(stdout=b"") def mock_Popen(*args, **kwargs): - mock_command = MockSubprocess(*args, **kwargs) + mock_command = MockSubprocess( + *args, + **{**kwargs, **{"launcher_alive": command_mock.launcher_working}} + ) - commands_.append(mock_command) + command_mock.commands.append(mock_command) return mock_command @@ -880,7 +908,7 @@ mock_subprocess_run ) - return commands_ + return command_mock @pytest.fixture(scope="function") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/test_gui.py new/protontricks-1.11.1/tests/test_gui.py --- old/protontricks-1.11.0/tests/test_gui.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/test_gui.py 2024-02-20 17:37:34.000000000 +0100 @@ -231,7 +231,7 @@ assert steam_app == steam_apps[1] assert ( "Your system locale is incapable of displaying all characters" - in caplog.records[0].message + in caplog.records[-1].message ) @pytest.mark.parametrize("gui_cmd", ["yad", "zenity"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/test_steam.py new/protontricks-1.11.1/tests/test_steam.py --- old/protontricks-1.11.0/tests/test_steam.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/test_steam.py 2024-02-20 17:37:34.000000000 +0100 @@ -741,16 +741,25 @@ "Tool manifest for Custom Proton is empty" ) + @pytest.mark.parametrize( + "content,error", + [ + (b"corrupted", " is corrupted. "), + (b"", " is empty. "), # Regression test for #241 + (b"\"incompatibilitytools\"\n{\n}", " is incomplete. ") + ] + ) def test_get_steam_apps_custom_proton_corrupted_compatibilitytool( - self, custom_proton_factory, steam_dir, steam_root, caplog): + self, custom_proton_factory, steam_dir, steam_root, caplog, + content, error): """ Create a custom Proton installation with a corrupted compatibilitytool.vdf and ensure a warning is printed and the app is ignored """ custom_proton = custom_proton_factory(name="Custom Proton") - (custom_proton.install_path / "compatibilitytool.vdf").write_text( - "corrupted" + (custom_proton.install_path / "compatibilitytool.vdf").write_bytes( + content ) steam_apps = get_steam_apps( @@ -774,9 +783,7 @@ if record.levelname == "WARNING" ) - assert record.getMessage().startswith( - "Compatibility tool declaration at" - ) + assert error in record.getMessage() def test_get_steam_apps_in_library_folder( self, default_proton, steam_library_factory, steam_app_factory, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/protontricks-1.11.0/tests/test_util.py new/protontricks-1.11.1/tests/test_util.py --- old/protontricks-1.11.0/tests/test_util.py 2023-12-30 17:52:23.000000000 +0100 +++ new/protontricks-1.11.1/tests/test_util.py 2024-02-20 17:37:34.000000000 +0100 @@ -55,7 +55,7 @@ class TestRunCommand: def test_user_environment_variables_used( self, default_proton, steam_runtime_dir, steam_app_factory, - home_dir, commands, monkeypatch): + home_dir, command_mock, monkeypatch): """ Test that user-provided environment variables are used even when Steam Runtime is enabled @@ -78,7 +78,7 @@ / "bin" ) - command = commands[-1] + command = command_mock.commands[-1] assert command.args == ["echo", "nothing"] assert command.env["WINE"] == str(wine_bin_dir / "wine") assert command.env["WINELOADER"] == str(wine_bin_dir / "wine") @@ -97,12 +97,13 @@ ) # User provided Wine paths are used even when Steam Runtime is enabled - command = commands[-1] + command = command_mock.commands[-1] assert command.args == ["echo", "nothing"] assert command.env["WINE"] == "/fake/wine" assert command.env["WINELOADER"] == "/fake/wine" assert command.env["WINESERVER"] == "/fake/wineserver" + @pytest.mark.usefixtures("command_mock") def test_unknown_steam_runtime_detected( self, home_dir, proton_factory, runtime_app_factory, steam_app_factory, caplog): @@ -143,7 +144,7 @@ @pytest.mark.usefixtures("steam_deck") def test_locale_fixed_on_steam_deck( self, proton_factory, default_proton, steam_app_factory, home_dir, - commands, caplog): + command_mock, caplog): """ Test that Protontricks will fix locale settings if nonexistent locale settings are detected and Steam Deck is used to run Protontricks @@ -194,7 +195,7 @@ ) # Ensure the incorrect locale settings were changed for the command - command = commands[-1] + command = command_mock.commands[-1] assert command.env["LANG"] == "en_US.UTF-8" # LC_CTYPE was not changed as 'en_US.UTF-8' and 'en_US.utf8' # are identical after normalization. @@ -202,6 +203,28 @@ assert command.env["LC_TIME"] == "en_US.UTF-8" assert command.env["LC_NUMERIC"] == "en_US.UTF-8" + def test_bwrap_launcher_crash_detected( + self, default_new_proton, steam_app_factory, command_mock): + """ + Test that Protontricks will raise an exception if `bwrap-launcher` + crashes unexpectedly + """ + steam_app = steam_app_factory(name="Fake game", appid=10) + + # Mock a crashing 'bwrap-launcher' + command_mock.launcher_working = False + + with pytest.raises(RuntimeError) as exc: + run_command( + winetricks_path=Path("/usr/bin/winetricks"), + proton_app=default_new_proton, + steam_app=steam_app, + command=["echo", "nothing"], + shell=True, + use_steam_runtime=True + ) + + assert str(exc.value) == "bwrap launcher crashed, returncode: 1" class TestLowerDict: