From 8c7b38b386a576895f1347206cd8334ad1605512 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 11 Dec 2024 10:18:48 -0500 Subject: [PATCH 1/7] chore: Add pre-commit --- .pre-commit-config.yaml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..b417b739d9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-xml + # - id: check-json + # - id: pretty-format-json + # args: ["--autofix", "--no-sort-keys", "--indent", "4"] + - id: check-added-large-files + +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.2 + hooks: + # - id: ruff + # args: [ "--fix" ] + - id: ruff-format + +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.13.0 + hooks: + - id: mypy + args: ["--pretty"] + additional_dependencies: ["pygobject-stubs", "types-PyYAML", "types-Markdown", "types-requests", "types-pycurl", "types-chardet", "pytest-stub", "types-orjson", "pathvalidate", "requirements-parser"] + +- repo: https://github.com/PyCQA/autoflake + rev: v2.3.1 + hooks: + - id: autoflake From aead62d798ecfac0f7e2514c53c79a83f2fc8a74 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 11 Dec 2024 11:32:54 -0500 Subject: [PATCH 2/7] chore: Fix type annotations --- bottles/frontend/views/library.py | 2 +- bottles/frontend/windows/main_window.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bottles/frontend/views/library.py b/bottles/frontend/views/library.py index 1013e8c969..bebea15a10 100644 --- a/bottles/frontend/views/library.py +++ b/bottles/frontend/views/library.py @@ -36,7 +36,7 @@ class LibraryView(Adw.Bin): style_provider = Gtk.CssProvider() # endregion - items_per_line = GObject.property(type=int, default=0) + items_per_line = GObject.property(type=int, default=0) # type: ignore def __init__(self, window, **kwargs): super().__init__(**kwargs) diff --git a/bottles/frontend/windows/main_window.py b/bottles/frontend/windows/main_window.py index 79bf0d722e..acbdc340b6 100644 --- a/bottles/frontend/windows/main_window.py +++ b/bottles/frontend/windows/main_window.py @@ -191,7 +191,7 @@ def g_show_uri_handler(self, res: Result): def update_library(self): GLib.idle_add(self.page_library.update) - def set_title(self, title, subtitle: str = ""): + def title(self, title, subtitle: str = ""): self.view_switcher_title.set_title(title) self.view_switcher_title.set_subtitle(subtitle) @@ -389,7 +389,7 @@ def show_toast( action_label=None, action_callback=None, dismissed_callback=None, - ) -> Adw.Toast: + ) -> None: toast = Adw.Toast.new(message) toast.props.timeout = timeout From ea201327e8549943bb09ee2a03e9a28aae93ee68 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 18 Dec 2024 19:13:33 -0500 Subject: [PATCH 3/7] pre-commit: Add pre-commit workflow --- .github/workflows/pre-commit.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/pre-commit.yml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000000..2b11178bf9 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,14 @@ +name: pre-commit + +on: + pull_request: + push: + branches: [main] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.1 From e8e9096910e47e653c6df1042414986885475ca6 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 18 Dec 2024 19:14:03 -0500 Subject: [PATCH 4/7] chore: Run pre-commit --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- .github/pull_request_template.md | 4 +- .vscode/launch.json | 2 +- .vscode/tasks.json | 2 +- CODE_OF_CONDUCT.md | 1 - CODING_GUIDE.md | 6 +- README.md | 4 +- bottles/backend/globals.py | 1 - bottles/backend/managers/component.py | 3 +- bottles/backend/managers/conf.py | 1 - bottles/backend/managers/dependency.py | 1 - bottles/backend/managers/epicgamesstore.py | 1 - bottles/backend/managers/importer.py | 1 - bottles/backend/managers/installer.py | 1 - bottles/backend/managers/origin.py | 1 - bottles/backend/managers/runtime.py | 1 - bottles/backend/managers/sandbox.py | 1 - bottles/backend/managers/steamgriddb.py | 1 - bottles/backend/managers/template.py | 1 - bottles/backend/managers/thumbnail.py | 1 - bottles/backend/managers/ubisoftconnect.py | 1 - bottles/backend/models/config.py | 1 - bottles/backend/utils/display.py | 1 - bottles/backend/utils/file.py | 3 +- bottles/backend/utils/json.py | 4 +- bottles/backend/utils/lnk.py | 3 +- bottles/backend/utils/proc.py | 1 - bottles/backend/utils/snake.py | 70 +-- bottles/backend/utils/steam.py | 6 +- bottles/backend/utils/vdf.py | 199 ++++---- bottles/backend/utils/wine.py | 1 - bottles/backend/wine/drives.py | 1 - bottles/backend/wine/executor.py | 8 +- bottles/backend/wine/register.py | 4 - bottles/backend/wine/regkeys.py | 1 - bottles/backend/wine/winecfg.py | 1 - bottles/backend/wine/winecommand.py | 5 +- bottles/frontend/cli/cli.py | 31 +- bottles/frontend/cli/meson.build | 2 +- bottles/frontend/main.py | 49 +- bottles/frontend/utils/gtk.py | 1 - bottles/frontend/views/bottle_preferences.py | 2 +- bottles/frontend/widgets/component.py | 1 - bottles/frontend/widgets/executable.py | 1 - bottles/frontend/windows/generic.py | 3 - bottles/frontend/windows/generic_cli.py | 3 - bottles/frontend/windows/launchoptions.py | 25 +- bottles/frontend/windows/main_window.py | 4 +- bottles/frontend/windows/vkbasalt.py | 1 - .../com.usebottles.bottles.metainfo.xml.in.in | 2 +- .../apps/com.usebottles.bottles-program.svg | 2 +- .../symbolic/actions/info-symbolic.svg | 2 +- .../preferences-desktop-apps-symbolic.svg | 2 +- .../system-software-install-symbolic.svg | 2 +- .../hicolor/symbolic/apps/bottle-symbolic.svg | 2 +- .../symbolic/apps/bottles-steam-symbolic.svg | 2 +- data/images/bottles-welcome-night.svg | 2 +- data/images/bottles-welcome.svg | 2 +- data/meson.build | 2 +- meson_options.txt | 2 +- po/README.md | 4 +- pyproject.toml | 2 +- utils/flatpak-pip-generator.py | 429 ++++++++++-------- utils/install.sh | 2 +- utils/pylint-parser.py | 11 +- 65 files changed, 501 insertions(+), 438 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 005d029786..9943483aaa 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -8,7 +8,7 @@ body: value: | ⚠️ Do not open issues for Windows executables not working in Bottles, if not installed through our installers. Bottles is a Wine prefix manager. If a Windows application doesn't work, it could be a Wine problem or a misconfiguration of the Wine prefix. Please visit [WineHQ](https://www.winehq.org) and [ProtonDB](https://www.protondb.com) for more information on the software you are trying to run. For additional support, use the [Programs](https://github.com/bottlesdevs/programs) repository. ⚠️ Do not open issues for bugs outside of [Bottles on Flathub](https://flathub.org/apps/details/com.usebottles.bottles), as we do not support packages from third-party repositories. If you can reproduce the bug(s) using Bottles on Flathub, then we will provide support, otherwise we will close the issue. - + - type: textarea id: what-happened attributes: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c95f11371d..c6217333bd 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,5 @@ # Description -Please include a summary of the change and which issue is fixed (if available). +Please include a summary of the change and which issue is fixed (if available). Please also include relevant motivation and context. Fixes #(issue) @@ -11,7 +11,7 @@ Fixes #(issue) - [ ] This change requires a documentation update # How Has This Been Tested? -Please describe the tests that you ran to verify your changes. +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. - [ ] Test A - [ ] Test B diff --git a/.vscode/launch.json b/.vscode/launch.json index c6d7ad0480..a52fc05de4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,4 +18,4 @@ "request": "attach" } ] -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f6302c79b7..b836d57c43 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -24,4 +24,4 @@ "type": "shell" } ] -} \ No newline at end of file +} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index faf6ec1e20..222b0a3789 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -123,4 +123,3 @@ Additional language was incorporated and modified from the following Codes of Co * [Mozilla Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) is licensed [Creative Commons Attribution-ShareAlike 3.0 Unported License](https://creativecommons.org/licenses/by-sa/3.0/). * [Python Mentors Code of Conduct](http://pythonmentors.com/) * [Speak Up! Community Code of Conduct](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html), licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/) - diff --git a/CODING_GUIDE.md b/CODING_GUIDE.md index f6d36e0df8..46889e5a61 100644 --- a/CODING_GUIDE.md +++ b/CODING_GUIDE.md @@ -40,7 +40,7 @@ python ./utils/flatpak-pip-generator.py --runtime org.gnome.Sdk -r requirements. ### `po/POTFILES` -List of source files containing translatable strings. +List of source files containing translatable strings. Regenerate this file when you added/moved/removed/renamed files that contains translatable strings. @@ -59,8 +59,8 @@ EOF ### `po/bottles.pot` and `po/*.po` -We have a main pot file, which is template for other `.po` files -And for each language listed in `po/LINGUAS` we have a corresponding `.po` file +We have a main pot file, which is template for other `.po` files +And for each language listed in `po/LINGUAS` we have a corresponding `.po` file Regenerate these files when any translatable string added/changed/removed ```bash diff --git a/README.md b/README.md index 6bec67e598..936dd872e7 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@
Documentation · - Forums · - Discord · + Forums · + Discord · Funding diff --git a/bottles/backend/globals.py b/bottles/backend/globals.py index 3ca5d33024..488acea315 100644 --- a/bottles/backend/globals.py +++ b/bottles/backend/globals.py @@ -17,7 +17,6 @@ import os import shutil -from functools import lru_cache from pathlib import Path from typing import Dict from bottles.backend.utils import yaml, json diff --git a/bottles/backend/managers/component.py b/bottles/backend/managers/component.py index 9412f2262d..b9ecacc41c 100644 --- a/bottles/backend/managers/component.py +++ b/bottles/backend/managers/component.py @@ -20,7 +20,7 @@ import shutil import tarfile from functools import lru_cache -from typing import Union, Optional +from typing import Optional import pycurl @@ -45,7 +45,6 @@ # noinspection PyTypeChecker class ComponentManager: - def __init__(self, manager, offline: bool = False): self.__manager = manager self.__repo = manager.repository_manager.get_repo("components", offline) diff --git a/bottles/backend/managers/conf.py b/bottles/backend/managers/conf.py index bb0fc471ce..736627d4c3 100644 --- a/bottles/backend/managers/conf.py +++ b/bottles/backend/managers/conf.py @@ -6,7 +6,6 @@ class ConfigManager(object): - def __init__( self, config_file: Optional[str] = None, diff --git a/bottles/backend/managers/dependency.py b/bottles/backend/managers/dependency.py index a63815e6cd..3f31749a3a 100644 --- a/bottles/backend/managers/dependency.py +++ b/bottles/backend/managers/dependency.py @@ -44,7 +44,6 @@ class DependencyManager: - def __init__(self, manager, offline: bool = False): self.__manager = manager self.__repo = manager.repository_manager.get_repo("dependencies", offline) diff --git a/bottles/backend/managers/epicgamesstore.py b/bottles/backend/managers/epicgamesstore.py index 8a2989592a..6f4cc09a23 100644 --- a/bottles/backend/managers/epicgamesstore.py +++ b/bottles/backend/managers/epicgamesstore.py @@ -25,7 +25,6 @@ class EpicGamesStoreManager: - @staticmethod def find_dat_path(config: BottleConfig) -> Union[str, None]: """ diff --git a/bottles/backend/managers/importer.py b/bottles/backend/managers/importer.py index 7500f911f2..8d3b14cf8e 100644 --- a/bottles/backend/managers/importer.py +++ b/bottles/backend/managers/importer.py @@ -30,7 +30,6 @@ class ImportManager: - def __init__(self, manager): self.manager = manager diff --git a/bottles/backend/managers/installer.py b/bottles/backend/managers/installer.py index a000f21d2b..8c0595e422 100644 --- a/bottles/backend/managers/installer.py +++ b/bottles/backend/managers/installer.py @@ -37,7 +37,6 @@ class InstallerManager: - def __init__(self, manager, offline: bool = False): self.__manager = manager self.__repo = manager.repository_manager.get_repo("installers", offline) diff --git a/bottles/backend/managers/origin.py b/bottles/backend/managers/origin.py index 80eaf93503..0d3f8fe49d 100644 --- a/bottles/backend/managers/origin.py +++ b/bottles/backend/managers/origin.py @@ -23,7 +23,6 @@ class OriginManager: - @staticmethod def find_manifests_path(config: BottleConfig) -> Union[str, None]: """ diff --git a/bottles/backend/managers/runtime.py b/bottles/backend/managers/runtime.py index d2640f1cf0..a56e31d992 100644 --- a/bottles/backend/managers/runtime.py +++ b/bottles/backend/managers/runtime.py @@ -22,7 +22,6 @@ class RuntimeManager: - @staticmethod @lru_cache def get_runtimes(_filter: str = "bottles"): diff --git a/bottles/backend/managers/sandbox.py b/bottles/backend/managers/sandbox.py index a17799f8a6..b6f8cb0da9 100644 --- a/bottles/backend/managers/sandbox.py +++ b/bottles/backend/managers/sandbox.py @@ -23,7 +23,6 @@ class SandboxManager: - def __init__( self, envs: Optional[dict] = None, diff --git a/bottles/backend/managers/steamgriddb.py b/bottles/backend/managers/steamgriddb.py index 925e9ceee7..7670f7b85e 100644 --- a/bottles/backend/managers/steamgriddb.py +++ b/bottles/backend/managers/steamgriddb.py @@ -27,7 +27,6 @@ class SteamGridDBManager: - @staticmethod def get_game_grid(name: str, config: BottleConfig): try: diff --git a/bottles/backend/managers/template.py b/bottles/backend/managers/template.py index 6e83224010..1ab83ebfbd 100644 --- a/bottles/backend/managers/template.py +++ b/bottles/backend/managers/template.py @@ -34,7 +34,6 @@ class TemplateManager: - @staticmethod def new(env: str, config: BottleConfig): env = env.lower() diff --git a/bottles/backend/managers/thumbnail.py b/bottles/backend/managers/thumbnail.py index 96bd981fd9..ea6183059a 100644 --- a/bottles/backend/managers/thumbnail.py +++ b/bottles/backend/managers/thumbnail.py @@ -25,7 +25,6 @@ class ThumbnailManager: - @staticmethod def get_path(config: BottleConfig, uri: str): if uri.startswith("grid:"): diff --git a/bottles/backend/managers/ubisoftconnect.py b/bottles/backend/managers/ubisoftconnect.py index 74484a87d4..259adb4390 100644 --- a/bottles/backend/managers/ubisoftconnect.py +++ b/bottles/backend/managers/ubisoftconnect.py @@ -24,7 +24,6 @@ class UbisoftConnectManager: - @staticmethod def find_conf_path(config: BottleConfig) -> Union[str, None]: """ diff --git a/bottles/backend/models/config.py b/bottles/backend/models/config.py index f3e7ed6cbf..77c0db1647 100644 --- a/bottles/backend/models/config.py +++ b/bottles/backend/models/config.py @@ -14,7 +14,6 @@ # noinspection PyDataclass class DictCompatMixIn: - @staticmethod def yaml_serialize_handler(dumper, data): dict_repr = data.to_dict() diff --git a/bottles/backend/utils/display.py b/bottles/backend/utils/display.py index a970e1aee9..5c9b02ea83 100644 --- a/bottles/backend/utils/display.py +++ b/bottles/backend/utils/display.py @@ -4,7 +4,6 @@ class DisplayUtils: - @staticmethod @lru_cache def get_x_display(): diff --git a/bottles/backend/utils/file.py b/bottles/backend/utils/file.py index 4efa6bb2db..64daf05aa0 100644 --- a/bottles/backend/utils/file.py +++ b/bottles/backend/utils/file.py @@ -24,6 +24,7 @@ from typing import Union from array import array + class FileUtils: """ This class provide some useful methods to work with files. @@ -124,7 +125,7 @@ def chattr_f(directory: str) -> bool: if os.path.isdir(directory) and len(os.listdir(directory)) == 0: fd = os.open(directory, os.O_RDONLY) try: - arg = array('L', [0]) + arg = array("L", [0]) fcntl.ioctl(fd, FS_IOC_GETFLAGS, arg, True) arg[0] |= FS_CASEFOLD_FL fcntl.ioctl(fd, FS_IOC_SETFLAGS, arg, True) diff --git a/bottles/backend/utils/json.py b/bottles/backend/utils/json.py index 6f38c97ac4..eb7a74dd07 100644 --- a/bottles/backend/utils/json.py +++ b/bottles/backend/utils/json.py @@ -31,7 +31,7 @@ def dump( fp: IO[str], *, indent: Optional[str | int] = None, - cls: Optional[Type[_json.JSONEncoder]] = None + cls: Optional[Type[_json.JSONEncoder]] = None, ) -> None: """ Serialize obj as a JSON formatted stream to fp (a .write()-supporting file-like object). @@ -50,7 +50,7 @@ def dumps( obj: Any, *, indent: Optional[str | int] = None, - cls: Optional[Type[_json.JSONEncoder]] = None + cls: Optional[Type[_json.JSONEncoder]] = None, ) -> str: """ Serialize obj to a JSON formatted str. diff --git a/bottles/backend/utils/lnk.py b/bottles/backend/utils/lnk.py index d6a660afcb..ba7cb920d0 100644 --- a/bottles/backend/utils/lnk.py +++ b/bottles/backend/utils/lnk.py @@ -21,7 +21,6 @@ class LnkUtils: - @staticmethod @lru_cache def get_data(path): @@ -53,7 +52,7 @@ def get_data(path): length = struct.unpack("I", content[last_pos:position])[0] """ - Skip 12 bytes (LinkInfoHeaderSize, LinkInfoFlags and + Skip 12 bytes (LinkInfoHeaderSize, LinkInfoFlags and VolumeIDOffset) """ position += 0x0C diff --git a/bottles/backend/utils/proc.py b/bottles/backend/utils/proc.py index dbebadc410..eff3e91e48 100644 --- a/bottles/backend/utils/proc.py +++ b/bottles/backend/utils/proc.py @@ -51,7 +51,6 @@ def kill(self): class ProcUtils: - @staticmethod def get_procs(): procs = [] diff --git a/bottles/backend/utils/snake.py b/bottles/backend/utils/snake.py index b116a5744e..cb1f0a9982 100644 --- a/bottles/backend/utils/snake.py +++ b/bottles/backend/utils/snake.py @@ -20,7 +20,7 @@ def __init__(self, stdscr: curses.window): self.food = [0, 0] self.score = 0 self.life = 3 - self.direction = 'RIGHT' + self.direction = "RIGHT" self.generate_food() @@ -28,36 +28,40 @@ def generate_food(self): self.food = [int(random.random() * 20), int(random.random() * 20)] while self.food in self.snake: bounds = self.stdscr.getmaxyx() - self.food = [int(random.random() * (bounds[0] - 2)) + 1, int(random.random() * (bounds[1] - 2)) + 1] + self.food = [ + int(random.random() * (bounds[0] - 2)) + 1, + int(random.random() * (bounds[1] - 2)) + 1, + ] def draw(self): self.stdscr.clear() self.stdscr.box() self.stdscr.addstr( - self.stdscr.getmaxyx()[0] - 1, self.stdscr.getmaxyx()[1] // 2 - len(str(self.score)) // 2, - f'Score: {self.score}', - curses.color_pair(3) + self.stdscr.getmaxyx()[0] - 1, + self.stdscr.getmaxyx()[1] // 2 - len(str(self.score)) // 2, + f"Score: {self.score}", + curses.color_pair(3), ) for i, j in self.snake: try: - self.stdscr.addstr(i, j, '◍', curses.color_pair(1)) + self.stdscr.addstr(i, j, "◍", curses.color_pair(1)) except: self.__is_running = False - self.stdscr.addstr(self.food[0], self.food[1], '🍎', curses.color_pair(2)) + self.stdscr.addstr(self.food[0], self.food[1], "🍎", curses.color_pair(2)) self.stdscr.refresh() def move(self): new_head = [self.snake[0][0], self.snake[0][1]] - if self.direction == 'UP': + if self.direction == "UP": new_head[0] -= 1 - elif self.direction == 'DOWN': + elif self.direction == "DOWN": new_head[0] += 1 - elif self.direction == 'LEFT': + elif self.direction == "LEFT": new_head[1] -= 1 - elif self.direction == 'RIGHT': + elif self.direction == "RIGHT": new_head[1] += 1 self.snake.insert(0, new_head) @@ -70,19 +74,19 @@ def move(self): def get_input(self): key = self.stdscr.getch() - if key == curses.KEY_UP and self.direction != 'DOWN': - self.direction = 'UP' - elif key == curses.KEY_DOWN and self.direction != 'UP': - self.direction = 'DOWN' - elif key == curses.KEY_LEFT and self.direction != 'RIGHT': - self.direction = 'LEFT' - elif key == curses.KEY_RIGHT and self.direction != 'LEFT': - self.direction = 'RIGHT' - elif key == ord('q'): + if key == curses.KEY_UP and self.direction != "DOWN": + self.direction = "UP" + elif key == curses.KEY_DOWN and self.direction != "UP": + self.direction = "DOWN" + elif key == curses.KEY_LEFT and self.direction != "RIGHT": + self.direction = "LEFT" + elif key == curses.KEY_RIGHT and self.direction != "LEFT": + self.direction = "RIGHT" + elif key == ord("q"): exit() def get_result(self): - return f'Your score is {self.score}' + return f"Your score is {self.score}" def run(self): self.__is_running = True @@ -103,36 +107,36 @@ def main(stdscr): result = snake.get_result() -if __name__ == '__main__': - os.system('clear') +if __name__ == "__main__": + os.system("clear") logo = """ .▄▄ · ▐ ▄ ▄▄▄· ▄ •▄ ▄▄▄ . ▐█ ▀. •█▌▐█▐█ ▀█ █▌▄▌▪▀▄.▀· ▄▀▀▀█▄▐█▐▐▌▄█▀▀█ ▐▀▀▄·▐▀▀▪▄ ▐█▄▪▐███▐█▌▐█ ▪▐▌▐█.█▌▐█▄▄▌ - ▀▀▀▀ ▀▀ █▪ ▀ ▀ ·▀ ▀ ▀▀▀ + ▀▀▀▀ ▀▀ █▪ ▀ ▀ ·▀ ▀ ▀▀▀ """ print(logo) - print('\u2550' * 27) + print("\u2550" * 27) print(""" 1. Play 2. Exit """) - print('\u2550' * 27) + print("\u2550" * 27) print("\nDo you want to play a game? (1/2)\n") choice = input() - if choice == '1': + if choice == "1": curses.wrapper(main) - os.system('tput reset') + os.system("tput reset") - print('\u2554' + '\u2550' * (len(result) + 2) + '\u2557') - print('\u2551' + " " + result + " " + '\u2551') - print('\u255a' + '\u2550' * (len(result) + 2) + '\u255d') + print("\u2554" + "\u2550" * (len(result) + 2) + "\u2557") + print("\u2551" + " " + result + " " + "\u2551") + print("\u255a" + "\u2550" * (len(result) + 2) + "\u255d") print("Start again? (y/n)") - if input() == 'y': + if input() == "y": os.execl(sys.executable, os.path.abspath(__file__), *sys.argv) else: exit() - elif choice == '2': + elif choice == "2": exit() diff --git a/bottles/backend/utils/steam.py b/bottles/backend/utils/steam.py index b6436c2bb5..c7a5fc9d1c 100644 --- a/bottles/backend/utils/steam.py +++ b/bottles/backend/utils/steam.py @@ -15,8 +15,9 @@ # along with this program. If not, see . # -import os, subprocess, shlex -from typing import Union, TextIO +import os +import shlex +from typing import TextIO from typing import TextIO from bottles.backend.logger import Logger @@ -27,7 +28,6 @@ class SteamUtils: - @staticmethod def parse_acf(data: str) -> VDFDict: """ diff --git a/bottles/backend/utils/vdf.py b/bottles/backend/utils/vdf.py index 462c0284ca..96c932b9ce 100644 --- a/bottles/backend/utils/vdf.py +++ b/bottles/backend/utils/vdf.py @@ -34,7 +34,7 @@ string_type = str int_type = int -BOMS = '\ufffe\ufeff' +BOMS = "\ufffe\ufeff" def strip_bom(line): @@ -52,8 +52,8 @@ def strip_bom(line): r"\a": "\a", r"\\": "\\", r"\?": "?", - r"\"": "\"", - r"\'": "\'", + r"\"": '"', + r"\'": "'", } _escape_char_map = {v: k for k, v in _unescape_char_map.items()} @@ -71,7 +71,9 @@ def _escape(text): def _unescape(text): - return re.sub(r"(\\n|\\t|\\v|\\b|\\r|\\f|\\a|\\\\|\\\?|\\\"|\\')", _re_unescape_match, text) + return re.sub( + r"(\\n|\\t|\\v|\\b|\\r|\\f|\\a|\\\\|\\\?|\\\"|\\')", _re_unescape_match, text + ) # parsing and dumping for KV1 @@ -88,19 +90,23 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): """ if not issubclass(mapper, Mapping): raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) - if not hasattr(fp, 'readline'): - raise TypeError("Expected fp to be a file-like object supporting line iteration") + if not hasattr(fp, "readline"): + raise TypeError( + "Expected fp to be a file-like object supporting line iteration" + ) stack = [mapper()] expect_bracket = False - re_keyvalue = re.compile(r'^("(?P(?:\\.|[^\\"])*)"|(?P#?[a-z0-9\-_\\?$%<>]+))' - r'([ \t]*(' - r'"(?P(?:\\.|[^\\"])*)(?P")?' - r'|(?P(?:(? ])+)' - r'|(?P{[ \t]*)(?P})?' - r'))?', - flags=re.I) + re_keyvalue = re.compile( + r'^("(?P(?:\\.|[^\\"])*)"|(?P#?[a-z0-9\-_\\?$%<>]+))' + r"([ \t]*(" + r'"(?P(?:\\.|[^\\"])*)(?P")?' + r"|(?P(?:(? ])+)" + r"|(?P{[ \t]*)(?P})?" + r"))?", + flags=re.I, + ) lineno = line = -1 for lineno, line in enumerate(fp, 1): @@ -110,7 +116,7 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): line = line.lstrip() # skip empty and comment lines - if line == "" or line[0] == '/': + if line == "" or line[0] == "/": continue # one level deeper @@ -119,8 +125,10 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): continue if expect_bracket: - raise SyntaxError("vdf.parse: expected openning bracket", - (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 1, line)) + raise SyntaxError( + "vdf.parse: expected openning bracket", + (getattr(fp, "name", "<%s>" % fp.__class__.__name__), lineno, 1, line), + ) # one level back if line[0] == "}": @@ -128,8 +136,10 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): stack.pop() continue - raise SyntaxError("vdf.parse: one too many closing parenthasis", - (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + raise SyntaxError( + "vdf.parse: one too many closing parenthasis", + (getattr(fp, "name", "<%s>" % fp.__class__.__name__), lineno, 0, line), + ) # parse keyvalue pairs while True: @@ -140,13 +150,24 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): line += next(fp) continue except StopIteration: - raise SyntaxError("vdf.parse: unexpected EOF (open key quote?)", - (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) - - key = match.group('key') if match.group('qkey') is None else match.group('qkey') - val = match.group('qval') + raise SyntaxError( + "vdf.parse: unexpected EOF (open key quote?)", + ( + getattr(fp, "name", "<%s>" % fp.__class__.__name__), + lineno, + 0, + line, + ), + ) + + key = ( + match.group("key") + if match.group("qkey") is None + else match.group("qkey") + ) + val = match.group("qval") if val is None: - val = match.group('val') + val = match.group("val") if val is not None: val = val.rstrip() if val == "": @@ -166,23 +187,30 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): _m = mapper() stack[-1][key] = _m - if match.group('eblock') is None: + if match.group("eblock") is None: # only expect a bracket if it's not already closed or on the same line stack.append(_m) - if match.group('sblock') is None: + if match.group("sblock") is None: expect_bracket = True # we've matched a simple keyvalue pair, map it to the last dict obj in the stack else: # if the value is line consume one more line and try to match again, # until we get the KeyValue pair - if match.group('vq_end') is None and match.group('qval') is not None: + if match.group("vq_end") is None and match.group("qval") is not None: try: line += next(fp) continue except StopIteration: - raise SyntaxError("vdf.parse: unexpected EOF (open quote for value?)", - (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + raise SyntaxError( + "vdf.parse: unexpected EOF (open quote for value?)", + ( + getattr(fp, "name", "<%s>" % fp.__class__.__name__), + lineno, + 0, + line, + ), + ) stack[-1][key] = _unescape(val) if escaped else val @@ -190,8 +218,10 @@ def parse(fp, mapper=dict, merge_duplicate_keys=True, escaped=True): break if len(stack) != 1: - raise SyntaxError("vdf.parse: unclosed parenthasis or quotes (EOF)", - (getattr(fp, 'name', '<%s>' % fp.__class__.__name__), lineno, 0, line)) + raise SyntaxError( + "vdf.parse: unclosed parenthasis or quotes (EOF)", + (getattr(fp, "name", "<%s>" % fp.__class__.__name__), lineno, 0, line), + ) return stack.pop() @@ -231,7 +261,7 @@ def dumps(obj, pretty=False, escaped=True): if not isinstance(escaped, bool): raise TypeError("Expected escaped to be of type bool") - return ''.join(_dump_gen(obj, pretty, escaped)) + return "".join(_dump_gen(obj, pretty, escaped)) def dump(obj, fp, pretty=False, escaped=True): @@ -241,7 +271,7 @@ def dump(obj, fp, pretty=False, escaped=True): """ if not isinstance(obj, Mapping): raise TypeError("Expected data to be an instance of``dict``") - if not hasattr(fp, 'write'): + if not hasattr(fp, "write"): raise TypeError("Expected fp to have write() method") if not isinstance(pretty, bool): raise TypeError("Expected pretty to be of type bool") @@ -297,20 +327,22 @@ class COLOR(BASE_INT): pass -BIN_NONE = b'\x00' -BIN_STRING = b'\x01' -BIN_INT32 = b'\x02' -BIN_FLOAT32 = b'\x03' -BIN_POINTER = b'\x04' -BIN_WIDESTRING = b'\x05' -BIN_COLOR = b'\x06' -BIN_UINT64 = b'\x07' -BIN_END = b'\x08' -BIN_INT64 = b'\x0A' -BIN_END_ALT = b'\x0B' +BIN_NONE = b"\x00" +BIN_STRING = b"\x01" +BIN_INT32 = b"\x02" +BIN_FLOAT32 = b"\x03" +BIN_POINTER = b"\x04" +BIN_WIDESTRING = b"\x05" +BIN_COLOR = b"\x06" +BIN_UINT64 = b"\x07" +BIN_END = b"\x08" +BIN_INT64 = b"\x0a" +BIN_END_ALT = b"\x0b" -def binary_loads(b, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=True): +def binary_loads( + b, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=True +): """ Deserialize ``b`` (``bytes`` containing a VDF in "binary form") to a Python object. @@ -324,10 +356,18 @@ def binary_loads(b, mapper=dict, merge_duplicate_keys=True, alt_format=False, ra if not isinstance(b, bytes): raise TypeError("Expected s to be bytes, got %s" % type(b)) - return binary_load(BytesIO(b), mapper, merge_duplicate_keys, alt_format, raise_on_remaining) + return binary_load( + BytesIO(b), mapper, merge_duplicate_keys, alt_format, raise_on_remaining + ) -def binary_load(fp, mapper=dict, merge_duplicate_keys=True, alt_format=False, raise_on_remaining=False): +def binary_load( + fp, + mapper=dict, + merge_duplicate_keys=True, + alt_format=False, + raise_on_remaining=False, +): """ Deserialize ``fp`` (a ``.read()``-supporting file-like object containing binary VDF) to a Python object. @@ -338,30 +378,32 @@ def binary_load(fp, mapper=dict, merge_duplicate_keys=True, alt_format=False, ra same key into one instead of overwriting. You can se this to ``False`` if you are using ``VDFDict`` and need to preserve the duplicates. """ - if not hasattr(fp, 'read') or not hasattr(fp, 'tell') or not hasattr(fp, 'seek'): - raise TypeError("Expected fp to be a file-like object with tell()/seek() and read() returning bytes") + if not hasattr(fp, "read") or not hasattr(fp, "tell") or not hasattr(fp, "seek"): + raise TypeError( + "Expected fp to be a file-like object with tell()/seek() and read() returning bytes" + ) if not issubclass(mapper, Mapping): raise TypeError("Expected mapper to be subclass of dict, got %s" % type(mapper)) # helpers - int32 = struct.Struct(' 1: stack.pop() @@ -423,13 +465,18 @@ def read_string(fp, wide=False): elif t == BIN_FLOAT32: stack[-1][key] = float32.unpack(fp.read(float32.size))[0] else: - raise SyntaxError("Unknown data type at offset %d: %s" % (fp.tell() - 1, repr(t))) + raise SyntaxError( + "Unknown data type at offset %d: %s" % (fp.tell() - 1, repr(t)) + ) if len(stack) != 1: raise SyntaxError("Reached EOF, but Binary VDF is incomplete") - if raise_on_remaining and fp.read(1) != b'': + if raise_on_remaining and fp.read(1) != b"": fp.seek(-1, 1) - raise SyntaxError("Binary VDF ended at offset %d, but there is more data remaining" % (fp.tell() - 1)) + raise SyntaxError( + "Binary VDF ended at offset %d, but there is more data remaining" + % (fp.tell() - 1) + ) return stack.pop() @@ -449,7 +496,7 @@ def binary_dump(obj, fp, alt_format=False): """ if not isinstance(obj, Mapping): raise TypeError("Expected obj to be type of Mapping") - if not hasattr(fp, 'write'): + if not hasattr(fp, "write"): raise TypeError("Expected fp to have write() method") for chunk in _binary_dump_gen(obj, alt_format=alt_format): @@ -460,14 +507,14 @@ def _binary_dump_gen(obj, level=0, alt_format=False): if level == 0 and len(obj) == 0: return - int32 = struct.Struct('/)") - ) + logging.error(_("Invalid URI (syntax: bottles:run//)")) return False - + uri = uri.replace("bottles:run/", "") bottle, program = uri.split("/") @@ -299,33 +296,37 @@ def __show_importer_view(self, widget=False, *args): def __show_about_dialog(self, *_args): developers = [ - "Mirko Brombin https://github.com/mirkobrombin", - "hthre7 https://github.com/hthre7", - "Kekun https://github.com/Kekun", - "Sonny Piers https://github.com/sonnyp", - "BrainBlasted https://github.com/BrainBlasted", - "Francesco Masala ", - "Hari Rana (TheEvilSkeleton) https://theevilskeleton.gitlab.io", - "axtlos https://axtloss.github.io", - "Oro https://github.com/orowith2os", - "gregorni https://gitlab.com/gregorni" + "Mirko Brombin https://github.com/mirkobrombin", + "hthre7 https://github.com/hthre7", + "Kekun https://github.com/Kekun", + "Sonny Piers https://github.com/sonnyp", + "BrainBlasted https://github.com/BrainBlasted", + "Francesco Masala ", + "Hari Rana (TheEvilSkeleton) https://theevilskeleton.gitlab.io", + "axtlos https://axtloss.github.io", + "Oro https://github.com/orowith2os", + "gregorni https://gitlab.com/gregorni", ] artists = [ - "Marco Montini https://github.com/marckniack", - "Noëlle https://github.com/jannuary", - "Alvar Lagerlöf https://github.com/alvarlagerlof", - "Ezekiel Smith https://github.com/ZekeSmith" + "Marco Montini https://github.com/marckniack", + "Noëlle https://github.com/jannuary", + "Alvar Lagerlöf https://github.com/alvarlagerlof", + "Ezekiel Smith https://github.com/ZekeSmith", ] - about_dialog = Adw.AboutDialog.new_from_appdata("/com/usebottles/bottles/appdata", f"{APP_MAJOR_VERSION}.0") + about_dialog = Adw.AboutDialog.new_from_appdata( + "/com/usebottles/bottles/appdata", f"{APP_MAJOR_VERSION}.0" + ) about_dialog.set_developers(developers) about_dialog.set_translator_credits(_("translator_credits")) about_dialog.set_artists(artists) about_dialog.set_debug_info(HealthChecker().get_results(plain=True)) about_dialog.add_link(_("Donate"), "https://usebottles.com/funding") about_dialog.set_copyright( - _("Copyright © 2017 {developer_name}").format(developer_name=about_dialog.get_developer_name()) + _("Copyright © 2017 {developer_name}").format( + developer_name=about_dialog.get_developer_name() + ) ) about_dialog.add_acknowledgement_section( _("Third-Party Libraries and Special Thanks"), diff --git a/bottles/frontend/utils/gtk.py b/bottles/frontend/utils/gtk.py index c70f57336f..cef386e2b5 100644 --- a/bottles/frontend/utils/gtk.py +++ b/bottles/frontend/utils/gtk.py @@ -23,7 +23,6 @@ class GtkUtils: - @staticmethod def validate_entry(entry, extend=None) -> bool: text = entry.get_text() diff --git a/bottles/frontend/views/bottle_preferences.py b/bottles/frontend/views/bottle_preferences.py index e09ff04629..d09e22b8c5 100644 --- a/bottles/frontend/views/bottle_preferences.py +++ b/bottles/frontend/views/bottle_preferences.py @@ -593,7 +593,7 @@ def __show_vkbasalt_settings(self, widget): def __show_fsr_settings(self, widget): new_window = FsrDialog(parent_window=self.window, config=self.config) new_window.present() - + def __show_mangohud_settings(self, widget): new_window = MangoHudDialog(parent_window=self.window, config=self.config) new_window.present() diff --git a/bottles/frontend/widgets/component.py b/bottles/frontend/widgets/component.py index 89fe89dd0d..aebceaf7df 100644 --- a/bottles/frontend/widgets/component.py +++ b/bottles/frontend/widgets/component.py @@ -179,7 +179,6 @@ def set_uninstalled(self): class ComponentExpander(Adw.ExpanderRow): - def __init__(self, title, subtitle=None, **kwargs): super().__init__(**kwargs) diff --git a/bottles/frontend/widgets/executable.py b/bottles/frontend/widgets/executable.py index a4e00413a0..1e5204ceff 100644 --- a/bottles/frontend/widgets/executable.py +++ b/bottles/frontend/widgets/executable.py @@ -22,7 +22,6 @@ class ExecButton(Gtk.Button): - def __init__(self, parent, data, config, **kwargs): super().__init__(**kwargs) self.parent = parent diff --git a/bottles/frontend/windows/generic.py b/bottles/frontend/windows/generic.py index 81e16355dc..5796f23431 100644 --- a/bottles/frontend/windows/generic.py +++ b/bottles/frontend/windows/generic.py @@ -20,7 +20,6 @@ class MessageDialog(Gtk.MessageDialog): - def __init__(self, window, message=_("An error has occurred."), log=False): Gtk.MessageDialog.__init__( self, @@ -46,7 +45,6 @@ def __init__(self, window, message=_("An error has occurred."), log=False): class SourceDialog(Adw.Window): - def __init__(self, parent, title, message, buttons=None, lang="yaml", **kwargs): super().__init__(**kwargs) if buttons is None: @@ -111,7 +109,6 @@ def __copy_text(self, widget): class TextDialog(Adw.Window): - def __init__(self, parent, title, message, **kwargs): super().__init__(**kwargs) self.set_default_size(700, 700) diff --git a/bottles/frontend/windows/generic_cli.py b/bottles/frontend/windows/generic_cli.py index 7cc76e9f1c..52e2cec382 100644 --- a/bottles/frontend/windows/generic_cli.py +++ b/bottles/frontend/windows/generic_cli.py @@ -2,7 +2,4 @@ class MessageDialog: def __init__( self, parent, title="Warning", message="An error has occurred.", log=False ): - parent = _ - title = _ - log = _ print(message) diff --git a/bottles/frontend/windows/launchoptions.py b/bottles/frontend/windows/launchoptions.py index 622de7230f..c711cdfa65 100644 --- a/bottles/frontend/windows/launchoptions.py +++ b/bottles/frontend/windows/launchoptions.py @@ -235,13 +235,11 @@ def __save(self, *_args): def __choose_pre_script(self, *_args): def set_path(dialog, result): - try: file = dialog.open_finish(result) if file is None: - self.action_pre_script.set_subtitle( - self.__default_pre_script_msg) + self.action_pre_script.set_subtitle(self.__default_pre_script_msg) return file_path = file.get_path() @@ -254,13 +252,16 @@ def set_path(dialog, result): # also thrown when dialog has been cancelled if error.code == 2: # error 2 seems to be 'dismiss' or 'cancel' - if self.program["pre_script"] is None or self.program["pre_script"] == "": + if ( + self.program["pre_script"] is None + or self.program["pre_script"] == "" + ): self.action_pre_script.set_subtitle( - self.__default_pre_script_msg) + self.__default_pre_script_msg + ) else: # something else happened... logging.warning("Error selecting pre-run script: %s" % error) - pass dialog = Gtk.FileDialog.new() dialog.set_title("Select Pre-run Script") @@ -269,13 +270,11 @@ def set_path(dialog, result): def __choose_post_script(self, *_args): def set_path(dialog, result): - try: file = dialog.open_finish(result) if file is None: - self.action_post_script.set_subtitle( - self.__default_post_script_msg) + self.action_post_script.set_subtitle(self.__default_post_script_msg) return file_path = file.get_path() @@ -286,9 +285,13 @@ def set_path(dialog, result): # also thrown when dialog has been cancelled if error.code == 2: # error 2 seems to be 'dismiss' or 'cancel' - if self.program["post_script"] is None or self.program["post_script"] == "": + if ( + self.program["post_script"] is None + or self.program["post_script"] == "" + ): self.action_pre_script.set_subtitle( - self.__default_pre_script_msg) + self.__default_pre_script_msg + ) else: # something else happened... logging.warning("Error selecting post-run script: %s" % error) diff --git a/bottles/frontend/windows/main_window.py b/bottles/frontend/windows/main_window.py index acbdc340b6..8f755972a7 100644 --- a/bottles/frontend/windows/main_window.py +++ b/bottles/frontend/windows/main_window.py @@ -34,7 +34,7 @@ from bottles.backend.utils.connection import ConnectionUtils from bottles.backend.utils.threading import RunAsync from bottles.frontend.operation import TaskSyncer -from bottles.frontend.params import * +from bottles.frontend.params import APP_ID, BASE_ID, PROFILE from bottles.frontend.utils.gtk import GtkUtils from bottles.frontend.views.details import DetailsView from bottles.frontend.views.importer import ImporterView @@ -74,7 +74,6 @@ class MainWindow(Adw.ApplicationWindow): argument_executed = False def __init__(self, arg_bottle, **kwargs): - width = self.settings.get_int("window-width") height = self.settings.get_int("window-height") @@ -390,7 +389,6 @@ def show_toast( action_callback=None, dismissed_callback=None, ) -> None: - toast = Adw.Toast.new(message) toast.props.timeout = timeout diff --git a/bottles/frontend/windows/vkbasalt.py b/bottles/frontend/windows/vkbasalt.py index c6d2407c1c..b1cecb802f 100644 --- a/bottles/frontend/windows/vkbasalt.py +++ b/bottles/frontend/windows/vkbasalt.py @@ -146,7 +146,6 @@ def __init__(self, parent_window, config, **kwargs): # Save file def __idle_save(self, *args): - conf = ManagerUtils.get_bottle_path(self.config) # Apply default settings and close the dialog if default setting is enabled diff --git a/data/com.usebottles.bottles.metainfo.xml.in.in b/data/com.usebottles.bottles.metainfo.xml.in.in index bdda5c6e2a..b2886ffc6d 100644 --- a/data/com.usebottles.bottles.metainfo.xml.in.in +++ b/data/com.usebottles.bottles.metainfo.xml.in.in @@ -251,4 +251,4 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/scalable/apps/com.usebottles.bottles-program.svg b/data/icons/hicolor/scalable/apps/com.usebottles.bottles-program.svg index 2e8afa1071..ee74801aa7 100644 --- a/data/icons/hicolor/scalable/apps/com.usebottles.bottles-program.svg +++ b/data/icons/hicolor/scalable/apps/com.usebottles.bottles-program.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/symbolic/actions/info-symbolic.svg b/data/icons/hicolor/symbolic/actions/info-symbolic.svg index 65d5d5d109..27560f7392 100644 --- a/data/icons/hicolor/symbolic/actions/info-symbolic.svg +++ b/data/icons/hicolor/symbolic/actions/info-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/symbolic/actions/preferences-desktop-apps-symbolic.svg b/data/icons/hicolor/symbolic/actions/preferences-desktop-apps-symbolic.svg index 7188428d8b..67cc74421b 100644 --- a/data/icons/hicolor/symbolic/actions/preferences-desktop-apps-symbolic.svg +++ b/data/icons/hicolor/symbolic/actions/preferences-desktop-apps-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/symbolic/actions/system-software-install-symbolic.svg b/data/icons/hicolor/symbolic/actions/system-software-install-symbolic.svg index c76e9fc81c..50aad35de8 100644 --- a/data/icons/hicolor/symbolic/actions/system-software-install-symbolic.svg +++ b/data/icons/hicolor/symbolic/actions/system-software-install-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/symbolic/apps/bottle-symbolic.svg b/data/icons/hicolor/symbolic/apps/bottle-symbolic.svg index 46ae058803..ccf0e00610 100644 --- a/data/icons/hicolor/symbolic/apps/bottle-symbolic.svg +++ b/data/icons/hicolor/symbolic/apps/bottle-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/icons/hicolor/symbolic/apps/bottles-steam-symbolic.svg b/data/icons/hicolor/symbolic/apps/bottles-steam-symbolic.svg index 42ecc23af1..453904e25e 100644 --- a/data/icons/hicolor/symbolic/apps/bottles-steam-symbolic.svg +++ b/data/icons/hicolor/symbolic/apps/bottles-steam-symbolic.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/images/bottles-welcome-night.svg b/data/images/bottles-welcome-night.svg index aca643c847..d2ae4564c2 100644 --- a/data/images/bottles-welcome-night.svg +++ b/data/images/bottles-welcome-night.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/images/bottles-welcome.svg b/data/images/bottles-welcome.svg index 431950478c..ce2d77d627 100644 --- a/data/images/bottles-welcome.svg +++ b/data/images/bottles-welcome.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/data/meson.build b/data/meson.build index 8012839e70..36fb6a7002 100644 --- a/data/meson.build +++ b/data/meson.build @@ -66,4 +66,4 @@ if compile_schemas.found() ) endif -subdir('icons') \ No newline at end of file +subdir('icons') diff --git a/meson_options.txt b/meson_options.txt index 6721b7a6b5..819c870ee9 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -6,4 +6,4 @@ option ( 'development' ], value: 'default' -) \ No newline at end of file +) diff --git a/po/README.md b/po/README.md index 47ea6f9e81..75e9d29065 100644 --- a/po/README.md +++ b/po/README.md @@ -2,10 +2,10 @@ Help Bottles get translated in your language! ## Improve a translation :raising_hand: -If you've found typos or just think you can improve a translation, contribute +If you've found typos or just think you can improve a translation, contribute using the [Weblate](https://hosted.weblate.org/engage/bottles/) platform. -Please, this is an open source, free, free project. Don't vandalize the +Please, this is an open source, free, free project. Don't vandalize the translations, it's not funny, it's idiotic. ## Thanks! :two_hearts: :tada: diff --git a/pyproject.toml b/pyproject.toml index 1a2798f589..a8e285e49a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,4 +1,4 @@ [tool.pytest.ini_options] log_cli = true log_cli_level = "INFO" -log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" \ No newline at end of file +log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" diff --git a/utils/flatpak-pip-generator.py b/utils/flatpak-pip-generator.py index 9317f130ab..e3ff138572 100644 --- a/utils/flatpak-pip-generator.py +++ b/utils/flatpak-pip-generator.py @@ -5,7 +5,7 @@ # - will use arch-dependent whl directly # - will still install packages if they already exist in org.freedesktop.Sdk -__license__ = 'MIT' +__license__ = "MIT" import argparse import hashlib @@ -24,38 +24,53 @@ exit('Requirements modules is not installed. Run "pip install requirements-parser"') parser = argparse.ArgumentParser() -parser.add_argument('packages', nargs='*') -parser.add_argument('--python2', action='store_true', - help='Look for a Python 2 package') -parser.add_argument('--cleanup', choices=['scripts', 'all'], - help='Select what to clean up after build') -parser.add_argument('--requirements-file', '-r', - help='Specify requirements.txt file') -parser.add_argument('--build-only', action='store_const', - dest='cleanup', const='all', - help='Clean up all files after build') -parser.add_argument('--build-isolation', action='store_true', - default=False, - help=( - 'Do not disable build isolation. ' - 'Mostly useful on pip that does\'t ' - 'support the feature.' - )) -parser.add_argument('--ignore-installed', - type=lambda s: s.split(','), - default='', - help='Comma-separated list of package names for which pip ' - 'should ignore already installed packages. Useful when ' - 'the package is installed in the SDK but not in the ' - 'runtime.') -parser.add_argument('--checker-data', action='store_true', - help='Include x-checker-data in output for the "Flatpak External Data Checker"') -parser.add_argument('--output', '-o', - help='Specify output file name') -parser.add_argument('--runtime', - help='Specify a flatpak to run pip inside of a sandbox, ensures python version compatibility') -parser.add_argument('--yaml', action='store_true', - help='Use YAML as output format instead of JSON') +parser.add_argument("packages", nargs="*") +parser.add_argument( + "--python2", action="store_true", help="Look for a Python 2 package" +) +parser.add_argument( + "--cleanup", choices=["scripts", "all"], help="Select what to clean up after build" +) +parser.add_argument("--requirements-file", "-r", help="Specify requirements.txt file") +parser.add_argument( + "--build-only", + action="store_const", + dest="cleanup", + const="all", + help="Clean up all files after build", +) +parser.add_argument( + "--build-isolation", + action="store_true", + default=False, + help=( + "Do not disable build isolation. " + "Mostly useful on pip that does't " + "support the feature." + ), +) +parser.add_argument( + "--ignore-installed", + type=lambda s: s.split(","), + default="", + help="Comma-separated list of package names for which pip " + "should ignore already installed packages. Useful when " + "the package is installed in the SDK but not in the " + "runtime.", +) +parser.add_argument( + "--checker-data", + action="store_true", + help='Include x-checker-data in output for the "Flatpak External Data Checker"', +) +parser.add_argument("--output", "-o", help="Specify output file name") +parser.add_argument( + "--runtime", + help="Specify a flatpak to run pip inside of a sandbox, ensures python version compatibility", +) +parser.add_argument( + "--yaml", action="store_true", help="Use YAML as output format instead of JSON" +) opts = parser.parse_args() if opts.yaml: @@ -66,64 +81,66 @@ def get_pypi_url(name: str, filename: str) -> str: - url = 'https://pypi.org/pypi/{}/json'.format(name) - print('Extracting download url for', name) + url = "https://pypi.org/pypi/{}/json".format(name) + print("Extracting download url for", name) with urllib.request.urlopen(url) as response: - body = json.loads(response.read().decode('utf-8')) - for release in body['releases'].values(): + body = json.loads(response.read().decode("utf-8")) + for release in body["releases"].values(): for source in release: - if source['filename'] == filename: - return source['url'] - raise Exception('Failed to extract url from {}'.format(url)) + if source["filename"] == filename: + return source["url"] + raise Exception("Failed to extract url from {}".format(url)) def get_tar_package_url_pypi(name: str, version: str) -> str: - url = 'https://pypi.org/pypi/{}/{}/json'.format(name, version) + url = "https://pypi.org/pypi/{}/{}/json".format(name, version) with urllib.request.urlopen(url) as response: - body = json.loads(response.read().decode('utf-8')) - for ext in ['bz2', 'gz', 'xz', 'zip']: - for source in body['urls']: - if source['url'].endswith(ext): - return source['url'] - err = 'Failed to get {}-{} source from {}'.format(name, version, url) + body = json.loads(response.read().decode("utf-8")) + for ext in ["bz2", "gz", "xz", "zip"]: + for source in body["urls"]: + if source["url"].endswith(ext): + return source["url"] + err = "Failed to get {}-{} source from {}".format(name, version, url) raise Exception(err) def get_package_name(filename: str) -> str: - if filename.endswith(('bz2', 'gz', 'xz', 'zip')): - segments = filename.split('-') + if filename.endswith(("bz2", "gz", "xz", "zip")): + segments = filename.split("-") if len(segments) == 2: return segments[0] - return '-'.join(segments[:len(segments) - 1]) - elif filename.endswith('whl'): - segments = filename.split('-') + return "-".join(segments[: len(segments) - 1]) + elif filename.endswith("whl"): + segments = filename.split("-") if len(segments) == 5: return segments[0] - candidate = segments[:len(segments) - 4] + candidate = segments[: len(segments) - 4] # Some packages list the version number twice # e.g. PyQt5-5.15.0-5.15.0-cp35.cp36.cp37.cp38-abi3-manylinux2014_x86_64.whl if candidate[-1] == segments[len(segments) - 4]: - return '-'.join(candidate[:-1]) - return '-'.join(candidate) + return "-".join(candidate[:-1]) + return "-".join(candidate) else: raise Exception( - 'Downloaded filename: {} does not end with bz2, gz, xz, zip, or whl'.format(filename) + "Downloaded filename: {} does not end with bz2, gz, xz, zip, or whl".format( + filename + ) ) def get_file_version(filename: str) -> str: name = get_package_name(filename) - segments = filename.split(name + '-') - version = segments[1].split('-')[0] - for ext in ['tar.gz', 'whl', 'tar.xz', 'tar.gz', 'tar.bz2', 'zip']: - version = version.replace('.' + ext, '') + segments = filename.split(name + "-") + version = segments[1].split("-")[0] + for ext in ["tar.gz", "whl", "tar.xz", "tar.gz", "tar.bz2", "zip"]: + version = version.replace("." + ext, "") return version def get_file_hash(filename: str) -> str: sha = hashlib.sha256() - print('Generating hash for', filename.split('/')[-1]) - with open(filename, 'rb') as f: + print("Generating hash for", filename.split("/")[-1]) + with open(filename, "rb") as f: while True: data = f.read(1024 * 1024 * 32) if not data: @@ -134,24 +151,26 @@ def get_file_hash(filename: str) -> str: def download_tar_pypi(url: str, tempdir: str) -> None: with urllib.request.urlopen(url) as response: - file_path = os.path.join(tempdir, url.split('/')[-1]) - with open(file_path, 'x+b') as tar_file: + file_path = os.path.join(tempdir, url.split("/")[-1]) + with open(file_path, "x+b") as tar_file: shutil.copyfileobj(response, tar_file) def parse_continuation_lines(fin): for line in fin: - line = line.rstrip('\n') - while line.endswith('\\'): + line = line.rstrip("\n") + while line.endswith("\\"): try: - line = line[:-1] + next(fin).rstrip('\n') + line = line[:-1] + next(fin).rstrip("\n") except StopIteration: - exit('Requirements have a wrong number of line continuation characters "\\"') + exit( + 'Requirements have a wrong number of line continuation characters "\\"' + ) yield line def fprint(string: str) -> None: - separator = '=' * 72 # Same as `flatpak-builder` + separator = "=" * 72 # Same as `flatpak-builder` print(separator) print(string) print(separator) @@ -161,52 +180,56 @@ def fprint(string: str) -> None: if opts.requirements_file: requirements_file = os.path.expanduser(opts.requirements_file) try: - with open(requirements_file, 'r') as req_file: + with open(requirements_file, "r") as req_file: reqs = parse_continuation_lines(req_file) - reqs_as_str = '\n'.join([r.split('--hash')[0] for r in reqs]) + reqs_as_str = "\n".join([r.split("--hash")[0] for r in reqs]) packages = list(requirements.parse(reqs_as_str)) except FileNotFoundError: pass elif opts.packages: - packages = list(requirements.parse('\n'.join(opts.packages))) - with tempfile.NamedTemporaryFile('w', delete=False, prefix='requirements.') as req_file: - req_file.write('\n'.join(opts.packages)) + packages = list(requirements.parse("\n".join(opts.packages))) + with tempfile.NamedTemporaryFile( + "w", delete=False, prefix="requirements." + ) as req_file: + req_file.write("\n".join(opts.packages)) requirements_file = req_file.name else: - exit('Please specifiy either packages or requirements file argument') + exit("Please specifiy either packages or requirements file argument") for i in packages: if i["name"].lower().startswith("pyqt"): print("PyQt packages are not supported by flapak-pip-generator") print("However, there is a BaseApp for PyQt available, that you should use") - print("Visit https://github.com/flathub/com.riverbankcomputing.PyQt.BaseApp for more information") + print( + "Visit https://github.com/flathub/com.riverbankcomputing.PyQt.BaseApp for more information" + ) sys.exit(0) -with open(requirements_file, 'r') as req_file: - use_hash = '--hash=' in req_file.read() +with open(requirements_file, "r") as req_file: + use_hash = "--hash=" in req_file.read() -python_version = '2' if opts.python2 else '3' +python_version = "2" if opts.python2 else "3" if opts.python2: - pip_executable = 'pip2' + pip_executable = "pip2" else: - pip_executable = 'pip3' + pip_executable = "pip3" if opts.runtime: flatpak_cmd = [ - 'flatpak', - '--devel', - '--share=network', - '--filesystem=/tmp', - '--command={}'.format(pip_executable), - 'run', - opts.runtime + "flatpak", + "--devel", + "--share=network", + "--filesystem=/tmp", + "--command={}".format(pip_executable), + "run", + opts.runtime, ] if opts.requirements_file: requirements_file = os.path.expanduser(opts.requirements_file) if os.path.exists(requirements_file): prefix = os.path.realpath(requirements_file) - flag = '--filesystem={}'.format(prefix) + flag = "--filesystem={}".format(prefix) flatpak_cmd.insert(1, flag) else: flatpak_cmd = [pip_executable] @@ -214,46 +237,47 @@ def fprint(string: str) -> None: if opts.output: output_package = opts.output elif opts.requirements_file: - output_package = 'python{}-{}'.format( + output_package = "python{}-{}".format( python_version, - os.path.basename(opts.requirements_file).replace('.txt', ''), + os.path.basename(opts.requirements_file).replace(".txt", ""), ) elif len(packages) == 1: - output_package = 'python{}-{}'.format( - python_version, packages[0].name, + output_package = "python{}-{}".format( + python_version, + packages[0].name, ) else: - output_package = 'python{}-modules'.format(python_version) + output_package = "python{}-modules".format(python_version) if opts.yaml: - output_filename = output_package + '.yaml' + output_filename = output_package + ".yaml" else: - output_filename = output_package + '.json' + output_filename = output_package + ".json" modules = [] vcs_modules = [] sources = {} -tempdir_prefix = 'pip-generator-{}'.format(os.path.basename(output_package)) +tempdir_prefix = "pip-generator-{}".format(os.path.basename(output_package)) with tempfile.TemporaryDirectory(prefix=tempdir_prefix) as tempdir: pip_download = flatpak_cmd + [ - 'download', - '--exists-action=i', - '--dest', + "download", + "--exists-action=i", + "--dest", tempdir, - '-r', - requirements_file + "-r", + requirements_file, ] if use_hash: - pip_download.append('--require-hashes') + pip_download.append("--require-hashes") - fprint('Downloading sources') - cmd = ' '.join(pip_download) + fprint("Downloading sources") + cmd = " ".join(pip_download) print('Running: "{}"'.format(cmd)) try: subprocess.run(pip_download, check=True) except subprocess.CalledProcessError: - print('Failed to download') - print('Please fix the module manually in the generated file') + print("Failed to download") + print("Please fix the module manually in the generated file") if not opts.requirements_file: try: @@ -261,18 +285,20 @@ def fprint(string: str) -> None: except FileNotFoundError: pass - fprint('Downloading arch independent packages') + fprint("Downloading arch independent packages") for filename in os.listdir(tempdir): - if not filename.endswith(('bz2', 'whl', 'gz', 'xz', 'zip')): # modified 'any.whl' to 'whl' + if not filename.endswith( + ("bz2", "whl", "gz", "xz", "zip") + ): # modified 'any.whl' to 'whl' version = get_file_version(filename) name = get_package_name(filename) url = get_tar_package_url_pypi(name, version) - print('Deleting', filename) + print("Deleting", filename) try: os.remove(os.path.join(tempdir, filename)) except FileNotFoundError: pass - print('Downloading {}'.format(url)) + print("Downloading {}".format(url)) download_tar_pypi(url, tempdir) files = {get_package_name(f): [] for f in os.listdir(tempdir)} @@ -286,102 +312,116 @@ def fprint(string: str) -> None: if len(files[name]) > 1: zip_source = False for f in files[name]: - if f.endswith('.zip'): + if f.endswith(".zip"): zip_source = True if zip_source: for f in files[name]: - if not f.endswith('.zip'): + if not f.endswith(".zip"): try: os.remove(os.path.join(tempdir, f)) except FileNotFoundError: pass vcs_packages = { - x.name: {'vcs': x.vcs, 'revision': x.revision, 'uri': x.uri} + x.name: {"vcs": x.vcs, "revision": x.revision, "uri": x.uri} for x in packages if x.vcs } - fprint('Obtaining hashes and urls') + fprint("Obtaining hashes and urls") for filename in os.listdir(tempdir): name = get_package_name(filename) sha256 = get_file_hash(os.path.join(tempdir, filename)) if name in vcs_packages: - uri = vcs_packages[name]['uri'] - revision = vcs_packages[name]['revision'] - vcs = vcs_packages[name]['vcs'] - url = 'https://' + uri.split('://', 1)[1] - s = 'commit' - if vcs == 'svn': - s = 'revision' - source = OrderedDict([ - ('type', vcs), - ('url', url), - (s, revision), - ]) + uri = vcs_packages[name]["uri"] + revision = vcs_packages[name]["revision"] + vcs = vcs_packages[name]["vcs"] + url = "https://" + uri.split("://", 1)[1] + s = "commit" + if vcs == "svn": + s = "revision" + source = OrderedDict( + [ + ("type", vcs), + ("url", url), + (s, revision), + ] + ) is_vcs = True else: url = get_pypi_url(name, filename) - source = OrderedDict([ - ('type', 'file'), - ('url', url), - ('sha256', sha256)]) + source = OrderedDict([("type", "file"), ("url", url), ("sha256", sha256)]) if opts.checker_data: - source['x-checker-data'] = { - 'type': 'pypi', - 'name': name} + source["x-checker-data"] = {"type": "pypi", "name": name} if url.endswith(".whl"): - source['x-checker-data']['packagetype'] = 'bdist_wheel' + source["x-checker-data"]["packagetype"] = "bdist_wheel" is_vcs = False - sources[name] = {'source': source, 'vcs': is_vcs} + sources[name] = {"source": source, "vcs": is_vcs} # Python3 packages that come as part of org.freedesktop.Sdk. -system_packages = ['cython', 'easy_install', 'mako', 'markdown', 'meson', 'pip', 'pygments', 'setuptools', 'six', - 'wheel'] - -fprint('Generating dependencies') +system_packages = [ + "cython", + "easy_install", + "mako", + "markdown", + "meson", + "pip", + "pygments", + "setuptools", + "six", + "wheel", +] + +fprint("Generating dependencies") for package in packages: - if package.name is None: print( - 'Warning: skipping invalid requirement specification {} because it is missing a name'.format(package.line), - file=sys.stderr) - print('Append #egg= to the end of the requirement line to fix', file=sys.stderr) + "Warning: skipping invalid requirement specification {} because it is missing a name".format( + package.line + ), + file=sys.stderr, + ) + print( + "Append #egg= to the end of the requirement line to fix", + file=sys.stderr, + ) continue elif package.name.casefold() in system_packages: # modified print(f"{package.name} is in system_packages. Proceed anyway.") if len(package.extras) > 0: - extras = '[' + ','.join(extra for extra in package.extras) + ']' + extras = "[" + ",".join(extra for extra in package.extras) + "]" else: - extras = '' + extras = "" version_list = [x[0] + x[1] for x in package.specs] - version = ','.join(version_list) + version = ",".join(version_list) if package.vcs: - revision = '' + revision = "" if package.revision: - revision = '@' + package.revision - pkg = package.uri + revision + '#egg=' + package.name + revision = "@" + package.revision + pkg = package.uri + revision + "#egg=" + package.name else: pkg = package.name + extras + version dependencies = [] # Downloads the package again to list dependencies - tempdir_prefix = 'pip-generator-{}'.format(package.name) - with tempfile.TemporaryDirectory(prefix='{}-{}'.format(tempdir_prefix, package.name)) as tempdir: + tempdir_prefix = "pip-generator-{}".format(package.name) + with tempfile.TemporaryDirectory( + prefix="{}-{}".format(tempdir_prefix, package.name) + ) as tempdir: pip_download = flatpak_cmd + [ - 'download', - '--exists-action=i', - '--dest', + "download", + "--exists-action=i", + "--dest", tempdir, ] try: - print('Generating dependencies for {}'.format(package.name)) + print("Generating dependencies for {}".format(package.name)) subprocess.run(pip_download + [pkg], check=True, stdout=subprocess.DEVNULL) for filename in sorted(os.listdir(tempdir)): dep_name = get_package_name(filename) @@ -390,58 +430,60 @@ def fprint(string: str) -> None: dependencies.append(dep_name) except subprocess.CalledProcessError: - print('Failed to download {}'.format(package.name)) + print("Failed to download {}".format(package.name)) is_vcs = True if package.vcs else False package_sources = [] for dependency in dependencies: if dependency in sources: source = sources[dependency] - elif dependency.replace('_', '-') in sources: - source = sources[dependency.replace('_', '-')] + elif dependency.replace("_", "-") in sources: + source = sources[dependency.replace("_", "-")] else: continue - if not (not source['vcs'] or is_vcs): + if not (not source["vcs"] or is_vcs): continue - package_sources.append(source['source']) + package_sources.append(source["source"]) if package.vcs: - name_for_pip = '.' + name_for_pip = "." else: name_for_pip = pkg - module_name = 'python{}-{}'.format(python_version, package.name) + module_name = "python{}-{}".format(python_version, package.name) pip_command = [ pip_executable, - 'install', - '--verbose', - '--exists-action=i', - '--no-index', + "install", + "--verbose", + "--exists-action=i", + "--no-index", '--find-links="file://${PWD}"', - '--prefix=${FLATPAK_DEST}', - '"{}"'.format(name_for_pip) + "--prefix=${FLATPAK_DEST}", + '"{}"'.format(name_for_pip), ] if package.name in opts.ignore_installed: - pip_command.append('--ignore-installed') + pip_command.append("--ignore-installed") if package.name.casefold() in system_packages: # modified - print(f'{package.name} is in system_packages, adding --ignore-installed') - pip_command.append('--ignore-installed') + print(f"{package.name} is in system_packages, adding --ignore-installed") + pip_command.append("--ignore-installed") if not opts.build_isolation: - pip_command.append('--no-build-isolation') - - module = OrderedDict([ - ('name', module_name), - ('buildsystem', 'simple'), - ('build-commands', [' '.join(pip_command)]), - ('sources', package_sources), - ]) - if opts.cleanup == 'all': - module['cleanup'] = ['*'] - elif opts.cleanup == 'scripts': - module['cleanup'] = ['/bin', '/share/man/man1'] + pip_command.append("--no-build-isolation") + + module = OrderedDict( + [ + ("name", module_name), + ("buildsystem", "simple"), + ("build-commands", [" ".join(pip_command)]), + ("sources", package_sources), + ] + ) + if opts.cleanup == "all": + module["cleanup"] = ["*"] + elif opts.cleanup == "scripts": + module["cleanup"] = ["/bin", "/share/man/man1"] if package.vcs: vcs_modules.append(module) @@ -453,28 +495,29 @@ def fprint(string: str) -> None: pypi_module = modules[0] else: pypi_module = { - 'name': output_package, - 'buildsystem': 'simple', - 'build-commands': [], - 'modules': modules, + "name": output_package, + "buildsystem": "simple", + "build-commands": [], + "modules": modules, } print() -with open(output_filename, 'w') as output: +with open(output_filename, "w") as output: if opts.yaml: + class OrderedDumper(yaml.Dumper): def increase_indent(self, flow=False, indentless=False): return super(OrderedDumper, self).increase_indent(flow, False) - def dict_representer(dumper, data): return dumper.represent_dict(data.items()) - OrderedDumper.add_representer(OrderedDict, dict_representer) - output.write("# Generated with flatpak-pip-generator " + " ".join(sys.argv[1:]) + "\n") + output.write( + "# Generated with flatpak-pip-generator " + " ".join(sys.argv[1:]) + "\n" + ) yaml.dump(pypi_module, output, Dumper=OrderedDumper) else: output.write(json.dumps(pypi_module, indent=4)) - print('Output saved to {}'.format(output_filename)) + print("Output saved to {}".format(output_filename)) diff --git a/utils/install.sh b/utils/install.sh index 94bcfb2fce..2aba03c6b7 100755 --- a/utils/install.sh +++ b/utils/install.sh @@ -5,4 +5,4 @@ if [ -d "$BUILD_DIR" ]; then fi mkdir build meson --prefix=$PWD/build build -ninja -j$(nproc) -C build install \ No newline at end of file +ninja -j$(nproc) -C build install diff --git a/utils/pylint-parser.py b/utils/pylint-parser.py index 90b07f46b2..f5572b30ec 100644 --- a/utils/pylint-parser.py +++ b/utils/pylint-parser.py @@ -1,14 +1,21 @@ import sys import subprocess -git_diff_raw = subprocess.run("git diff --name-only origin/main | grep \"\.py$\"", capture_output=True, shell=True, check=False) +git_diff_raw = subprocess.run( + 'git diff --name-only origin/main | grep "\.py$"', + capture_output=True, + shell=True, + check=False, +) git_diff = git_diff_raw.stdout.decode("ascii").splitlines() if len(git_diff) == 0: sys.exit(0) -pylint_result = subprocess.run("pylint bottles", capture_output=True, shell=True, check=False) +pylint_result = subprocess.run( + "pylint bottles", capture_output=True, shell=True, check=False +) should_print = False for l in pylint_result.stdout.decode("ascii").splitlines(): From 9bd8b1e72a92810bb59dc03f329ef0b2676ee842 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 18 Dec 2024 19:25:15 -0500 Subject: [PATCH 5/7] ci: Remove pytest.yml --- .github/workflows/pytest.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/pytest.yml diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml deleted file mode 100644 index 043f0b57b5..0000000000 --- a/.github/workflows/pytest.yml +++ /dev/null @@ -1,28 +0,0 @@ -on: - push: - branches: [main] - pull_request: -name: Pytest -jobs: - pytest-testing: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Install Ubuntu dependencies - run: | - sudo apt update - sudo apt install -y libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 - sudo apt install -y libcurl4-openssl-dev libssl-dev - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements.dev.txt - - name: Test with pytest - run: | - python -m pytest --version - python -m pytest bottles From 5bee57de99c64144833d47c2ddefbf7550dc9117 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 18 Dec 2024 19:25:36 -0500 Subject: [PATCH 6/7] ci: Remove pylint-commenter.yml --- .github/workflows/pylint-commenter.yml | 54 -------------------------- 1 file changed, 54 deletions(-) delete mode 100644 .github/workflows/pylint-commenter.yml diff --git a/.github/workflows/pylint-commenter.yml b/.github/workflows/pylint-commenter.yml deleted file mode 100644 index ed012f3475..0000000000 --- a/.github/workflows/pylint-commenter.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Pylint - comment on the pull request - -# read-write repo token -# access to secrets -on: - workflow_run: - workflows: ["Pylint - checker"] - types: - - completed - -jobs: - pylint-comment: - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' - steps: - - name: 'Download artifact' - uses: actions/github-script@v7.0.1 - with: - script: | - var artifacts = await github.rest.actions.listWorkflowRunArtifacts ({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - var matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "pylint-result" - })[0]; - var download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - var fs = require('fs'); - fs.writeFileSync('${{github.workspace}}/pylint-result.zip', Buffer.from(download.data)); - - name: Fetch results - run: | - unzip pylint-result.zip - echo "PYLINT_RES<> $GITHUB_ENV - cat pylint-result >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - echo "PR_NUMBER=$(cat pr-number)" >> $GITHUB_ENV - - name: Comment PR - uses: thollander/actions-comment-pull-request@v2 - with: - comment_tag: pylint-result-comment - pr_number: ${{ env.PR_NUMBER }} - message: | -
Pylint result on modfied files: -
${{ env.PYLINT_RES }}
-
From 7271fcfb7e160f04a7546c17ce068fe64639f824 Mon Sep 17 00:00:00 2001 From: Hari Rana Date: Wed, 18 Dec 2024 19:25:51 -0500 Subject: [PATCH 7/7] ci: Remove pylint-checker.yml --- .github/workflows/pylint-checker.yml | 37 ---------------------------- 1 file changed, 37 deletions(-) delete mode 100644 .github/workflows/pylint-checker.yml diff --git a/.github/workflows/pylint-checker.yml b/.github/workflows/pylint-checker.yml deleted file mode 100644 index b76c5840fc..0000000000 --- a/.github/workflows/pylint-checker.yml +++ /dev/null @@ -1,37 +0,0 @@ -on: - pull_request: -name: Pylint - checker -jobs: - pylint-checker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python 3.10 - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - name: Install Ubuntu dependencies - run: | - sudo apt update - sudo apt install -y libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 - sudo apt install -y libcurl4-openssl-dev libssl-dev - - name: Install Python dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements.dev.txt - - name: Analysing the code with pylint - id: pylint-result - continue-on-error: true - run: | - pylint --version - mkdir -p output - python3 utils/pylint-parser.py > output/pylint-result - cat output/pylint-result - echo ${{ github.event.number }} > output/pr-number - - uses: actions/upload-artifact@v4 - with: - name: pylint-result - path: output/