Add pre-commit hook (#179)

* Update dev dependencies.
* Add pre-commit hook.
This commit is contained in:
Mikaël Capelle
2025-04-25 08:23:10 +02:00
committed by GitHub
parent 9e30d7d104
commit f502fb468f
52 changed files with 666 additions and 580 deletions
+25
View File
@@ -0,0 +1,25 @@
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-toml
- id: check-merge-conflict
- id: mixed-line-ending
args: [--fix=lf]
- id: check-case-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.7 # must match pyproject.toml
hooks:
- id: ruff
args: [--extend-select, I, --fix]
- id: ruff-format
ci:
autofix_commit_msg: "[pre-commit.ci] Auto fixes from pre-commit.com hooks."
autofix_prs: true
autoupdate_commit_msg: "[pre-commit.ci] Pre-commit autoupdate."
autoupdate_schedule: quarterly
submodules: false
+1 -1
View File
@@ -4,4 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+2 -1
View File
@@ -1,6 +1,7 @@
import mobase
from PyQt6.QtCore import QDir
import mobase
class BasicLocalSavegames(mobase.LocalSavegames):
def __init__(self, game_save_dir: QDir):
+1 -1
View File
@@ -78,7 +78,7 @@ class GlobPatterns:
unfold: list[str] | None = None
valid: list[str] | None = None
delete: list[str] | None = None
move: dict[str, str] = field(default_factory=dict)
move: dict[str, str] = field(default_factory=dict[str, str])
def merge(
self, other: GlobPatterns, mode: Literal["merge", "replace"] = "replace"
+2 -1
View File
@@ -6,11 +6,12 @@ from datetime import datetime
from pathlib import Path
from typing import Any, Callable, Self, Sequence
import mobase
from PyQt6.QtCore import QDateTime, QLocale, Qt
from PyQt6.QtGui import QImage, QPixmap
from PyQt6.QtWidgets import QFormLayout, QLabel, QSizePolicy, QVBoxLayout, QWidget
import mobase
def format_date(date_time: QDateTime | datetime | str, format_str: str | None = None):
"""Default format for date and time in the `BasicGameSaveGameInfoWidget`.
+2 -1
View File
@@ -5,11 +5,12 @@ import sys
from pathlib import Path
from typing import Callable, Generic, TypeVar
import mobase
from PyQt6.QtCore import QDir, QFileInfo, QStandardPaths
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QMessageBox
import mobase
from .basic_features.basic_save_game_info import (
BasicGameSaveGame,
BasicGameSaveGameInfo,
+87 -86
View File
@@ -1,86 +1,87 @@
import mobase
from PyQt6.QtCore import QDir, QFileInfo
from ..basic_features import BasicLocalSavegames
from ..basic_game import BasicGame
from ..steam_utils import find_steam_path
# Lifted from https://github.com/ModOrganizer2/modorganizer-basic_games/blob/71dbb8c557d43cba9d290674a332e7ecd1650261/games/game_darkestdungeon.py
class ArkhamCityModDataChecker(mobase.ModDataChecker):
def __init__(self):
super().__init__()
self.validDirNames = [
"config",
"cookedpcconsole",
"localization",
"movies",
"moviesstereo",
"splash",
]
def dataLooksValid(
self, filetree: mobase.IFileTree
) -> mobase.ModDataChecker.CheckReturn:
for entry in filetree:
if not entry.isDir():
continue
if entry.name().casefold() in self.validDirNames:
return mobase.ModDataChecker.VALID
return mobase.ModDataChecker.INVALID
class ArkhamCityGame(BasicGame):
Name = "Batman: Arkham City Plugin"
Author = "Paynamia"
Version = "0.5.3"
GameName = "Batman: Arkham City"
GameShortName = "batmanarkhamcity"
GameNexusId = 372
GameSteamId = 200260
GameGogId = 1260066469
GameEpicId = "Egret"
GameBinary = "Binaries/Win32/BatmanAC.exe"
GameLauncher = "Binaries/Win32/BmLauncher.exe"
GameDataPath = "BmGame"
GameDocumentsDirectory = (
"%DOCUMENTS%/WB Games/Batman Arkham City GOTY/BmGame/Config"
)
GameIniFiles = ["UserEngine.ini", "UserGame.ini", "UserInput.ini"]
GameSaveExtension = "sgd"
# This will only detect saves from the earliest-created Steam profile on the user's PC.
def savesDirectory(self) -> QDir:
docSaves = QDir(self.documentsDirectory().cleanPath("../../SaveData"))
if self.is_steam():
if (steamDir := find_steam_path()) is None:
return docSaves
for child in steamDir.joinpath("userdata").iterdir():
if not child.is_dir() or child.name == "0":
continue
steamSaves = child.joinpath("200260", "remote")
if steamSaves.is_dir():
return QDir(str(steamSaves))
else:
return docSaves
else:
return docSaves
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._register_feature(ArkhamCityModDataChecker())
self._register_feature(BasicLocalSavegames(self.savesDirectory()))
return True
def executables(self):
return [
mobase.ExecutableInfo(
"Batman: Arkham City",
QFileInfo(self.gameDirectory(), "Binaries/Win32/BatmanAC.exe"),
),
mobase.ExecutableInfo(
"Arkham City Launcher",
QFileInfo(self.gameDirectory(), "Binaries/Win32/BmLauncher.exe"),
),
]
from PyQt6.QtCore import QDir, QFileInfo
import mobase
from ..basic_features import BasicLocalSavegames
from ..basic_game import BasicGame
from ..steam_utils import find_steam_path
# Lifted from https://github.com/ModOrganizer2/modorganizer-basic_games/blob/71dbb8c557d43cba9d290674a332e7ecd1650261/games/game_darkestdungeon.py
class ArkhamCityModDataChecker(mobase.ModDataChecker):
def __init__(self):
super().__init__()
self.validDirNames = [
"config",
"cookedpcconsole",
"localization",
"movies",
"moviesstereo",
"splash",
]
def dataLooksValid(
self, filetree: mobase.IFileTree
) -> mobase.ModDataChecker.CheckReturn:
for entry in filetree:
if not entry.isDir():
continue
if entry.name().casefold() in self.validDirNames:
return mobase.ModDataChecker.VALID
return mobase.ModDataChecker.INVALID
class ArkhamCityGame(BasicGame):
Name = "Batman: Arkham City Plugin"
Author = "Paynamia"
Version = "0.5.3"
GameName = "Batman: Arkham City"
GameShortName = "batmanarkhamcity"
GameNexusId = 372
GameSteamId = 200260
GameGogId = 1260066469
GameEpicId = "Egret"
GameBinary = "Binaries/Win32/BatmanAC.exe"
GameLauncher = "Binaries/Win32/BmLauncher.exe"
GameDataPath = "BmGame"
GameDocumentsDirectory = (
"%DOCUMENTS%/WB Games/Batman Arkham City GOTY/BmGame/Config"
)
GameIniFiles = ["UserEngine.ini", "UserGame.ini", "UserInput.ini"]
GameSaveExtension = "sgd"
# This will only detect saves from the earliest-created Steam profile on the user's PC.
def savesDirectory(self) -> QDir:
docSaves = QDir(self.documentsDirectory().cleanPath("../../SaveData"))
if self.is_steam():
if (steamDir := find_steam_path()) is None:
return docSaves
for child in steamDir.joinpath("userdata").iterdir():
if not child.is_dir() or child.name == "0":
continue
steamSaves = child.joinpath("200260", "remote")
if steamSaves.is_dir():
return QDir(str(steamSaves))
else:
return docSaves
else:
return docSaves
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._register_feature(ArkhamCityModDataChecker())
self._register_feature(BasicLocalSavegames(self.savesDirectory()))
return True
def executables(self):
return [
mobase.ExecutableInfo(
"Batman: Arkham City",
QFileInfo(self.gameDirectory(), "Binaries/Win32/BatmanAC.exe"),
),
mobase.ExecutableInfo(
"Arkham City Launcher",
QFileInfo(self.gameDirectory(), "Binaries/Win32/BmLauncher.exe"),
),
]
+2 -1
View File
@@ -6,9 +6,10 @@ from collections.abc import Mapping
from pathlib import Path
from typing import BinaryIO
import mobase
from PyQt6.QtCore import QDateTime, QDir, QFile, QFileInfo
import mobase
from ..basic_features import BasicLocalSavegames
from ..basic_features.basic_save_game_info import (
BasicGameSaveGame,
+2 -1
View File
@@ -2,9 +2,10 @@ import json
from collections.abc import Mapping
from pathlib import Path
import mobase
from PyQt6.QtCore import QDateTime, QDir
import mobase
from ..basic_features.basic_save_game_info import (
BasicGameSaveGame,
BasicGameSaveGameInfo,
+2 -1
View File
@@ -1,8 +1,9 @@
from __future__ import annotations
import mobase
from PyQt6.QtCore import QFileInfo
import mobase
from ..basic_game import BasicGame
+4 -3
View File
@@ -10,7 +10,6 @@ from dataclasses import dataclass
from pathlib import Path
from typing import Any, Literal, TypeVar
import mobase
from PyQt6.QtCore import QDateTime, QDir, Qt, qCritical, qInfo, qWarning
from PyQt6.QtWidgets import (
QCheckBox,
@@ -20,6 +19,8 @@ from PyQt6.QtWidgets import (
QWidget,
)
import mobase
from ..basic_features import BasicLocalSavegames, BasicModDataChecker, GlobPatterns
from ..basic_features.basic_save_game_info import (
BasicGameSaveGame,
@@ -74,7 +75,7 @@ def parse_cyberpunk_save_metadata(save_path: Path, save: mobase.ISaveGame):
"Street Cred": int(meta_data["streetCred"]),
"Life Path": meta_data["lifePath"],
"Difficulty": meta_data["difficulty"],
"Gender": f'{meta_data["bodyGender"]} / {meta_data["brainGender"]}',
"Gender": f"{meta_data['bodyGender']} / {meta_data['brainGender']}",
"Game version": meta_data["buildPatch"],
}
except (FileNotFoundError, json.JSONDecodeError):
@@ -487,7 +488,7 @@ class Cyberpunk2077Game(BasicGame):
_,
) = self._modlist_files.update_modlist("redmod")
modlist_param = f'-modlist="{modlist_path}"' if modlist else ""
args = f"{args[:m.start()]}{modlist_param}{args[m.end():]}"
args = f"{args[: m.start()]}{modlist_param}{args[m.end() :]}"
qInfo(f"Manual modlist deployment: replacing {m[0]}, new args = {args}")
self._check_redmod_result(
self._organizer.waitForApplication(
+56 -56
View File
@@ -1,56 +1,56 @@
import mobase
from ..basic_game import BasicGame
class DaggerfallUnityModDataChecker(mobase.ModDataChecker):
def __init__(self):
super().__init__()
self.validDirNames = [
"biogs",
"docs",
"factions",
"fonts",
"mods",
"questpacks",
"quests",
"sound",
"soundfonts",
"spellicons",
"tables",
"text",
"textures",
"worlddata",
"aa",
]
def dataLooksValid(
self, filetree: mobase.IFileTree
) -> mobase.ModDataChecker.CheckReturn:
for entry in filetree:
if not entry.isDir():
continue
if entry.name().casefold() in self.validDirNames:
return mobase.ModDataChecker.VALID
return mobase.ModDataChecker.INVALID
class DaggerfallUnityGame(BasicGame):
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._register_feature(DaggerfallUnityModDataChecker())
return True
Name = "Daggerfall Unity Support Plugin"
Author = "HomerSimpleton"
Version = "1.0.0"
GameName = "Daggerfall Unity"
GameShortName = "daggerfallunity"
GameBinary = "DaggerfallUnity.exe"
GameLauncher = "DaggerfallUnity.exe"
GameDataPath = "%GAME_PATH%/DaggerfallUnity_Data/StreamingAssets"
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
"Game:-Daggerfall-Unity"
)
import mobase
from ..basic_game import BasicGame
class DaggerfallUnityModDataChecker(mobase.ModDataChecker):
def __init__(self):
super().__init__()
self.validDirNames = [
"biogs",
"docs",
"factions",
"fonts",
"mods",
"questpacks",
"quests",
"sound",
"soundfonts",
"spellicons",
"tables",
"text",
"textures",
"worlddata",
"aa",
]
def dataLooksValid(
self, filetree: mobase.IFileTree
) -> mobase.ModDataChecker.CheckReturn:
for entry in filetree:
if not entry.isDir():
continue
if entry.name().casefold() in self.validDirNames:
return mobase.ModDataChecker.VALID
return mobase.ModDataChecker.INVALID
class DaggerfallUnityGame(BasicGame):
def init(self, organizer: mobase.IOrganizer) -> bool:
super().init(organizer)
self._register_feature(DaggerfallUnityModDataChecker())
return True
Name = "Daggerfall Unity Support Plugin"
Author = "HomerSimpleton"
Version = "1.0.0"
GameName = "Daggerfall Unity"
GameShortName = "daggerfallunity"
GameBinary = "DaggerfallUnity.exe"
GameLauncher = "DaggerfallUnity.exe"
GameDataPath = "%GAME_PATH%/DaggerfallUnity_Data/StreamingAssets"
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
"Game:-Daggerfall-Unity"
)
+31 -31
View File
@@ -1,31 +1,31 @@
import mobase
from ..basic_features import BasicGameSaveGameInfo
from ..basic_game import BasicGame
class DAOriginsGame(BasicGame):
Name = "Dragon Age Origins Support Plugin"
Author = "Patchier"
Version = "1.1.1"
GameName = "Dragon Age: Origins"
GameShortName = "dragonage"
GameBinary = r"bin_ship\DAOrigins.exe"
GameDataPath = r"%DOCUMENTS%\BioWare\Dragon Age\packages\core\override"
GameSavesDirectory = r"%DOCUMENTS%\BioWare\Dragon Age\Characters"
GameSaveExtension = "das"
GameSteamId = [17450, 47810]
GameGogId = 1949616134
GameEaDesktopId = [70377, 70843]
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
"Game:-Dragon-Age:-Origins"
)
def init(self, organizer: mobase.IOrganizer):
super().init(organizer)
self._register_feature(
BasicGameSaveGameInfo(lambda s: s.parent.joinpath("screen.dds"))
)
return True
import mobase
from ..basic_features import BasicGameSaveGameInfo
from ..basic_game import BasicGame
class DAOriginsGame(BasicGame):
Name = "Dragon Age Origins Support Plugin"
Author = "Patchier"
Version = "1.1.1"
GameName = "Dragon Age: Origins"
GameShortName = "dragonage"
GameBinary = r"bin_ship\DAOrigins.exe"
GameDataPath = r"%DOCUMENTS%\BioWare\Dragon Age\packages\core\override"
GameSavesDirectory = r"%DOCUMENTS%\BioWare\Dragon Age\Characters"
GameSaveExtension = "das"
GameSteamId = [17450, 47810]
GameGogId = 1949616134
GameEaDesktopId = [70377, 70843]
GameSupportURL = (
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
"Game:-Dragon-Age:-Origins"
)
def init(self, organizer: mobase.IOrganizer):
super().init(organizer)
self._register_feature(
BasicGameSaveGameInfo(lambda s: s.parent.joinpath("screen.dds"))
)
return True
+2 -1
View File
@@ -1,9 +1,10 @@
import json
from pathlib import Path
import mobase
from PyQt6.QtCore import QDir, QFileInfo, QStandardPaths
import mobase
from ..basic_game import BasicGame, BasicGameSaveGame
from ..steam_utils import find_steam_path
+2 -1
View File
@@ -1,9 +1,10 @@
import struct
from pathlib import Path
import mobase
from PyQt6.QtGui import QImage
import mobase
from ..basic_features import BasicGameSaveGameInfo
from ..basic_game import BasicGame
+1 -2
View File
@@ -69,8 +69,7 @@ class DivinityOriginalSinEnhancedEditionGame(BasicGame, mobase.IPluginFileMapper
GameDataPath = "Data"
GameSaveExtension = "lsv"
GameDocumentsDirectory = (
"%USERPROFILE%/Documents/Larian Studios/"
"Divinity Original Sin Enhanced Edition"
"%USERPROFILE%/Documents/Larian Studios/Divinity Original Sin Enhanced Edition"
)
GameSavesDirectory = (
"%USERPROFILE%/Documents/Larian Studios/"
+2 -1
View File
@@ -1,6 +1,7 @@
import mobase
from PyQt6.QtCore import QFileInfo
import mobase
from ..basic_game import BasicGame
+2 -1
View File
@@ -1,6 +1,7 @@
import mobase
from PyQt6.QtCore import QFileInfo
import mobase
from ..basic_game import BasicGame
+13 -13
View File
@@ -1,13 +1,13 @@
from ..basic_game import BasicGame
class F123Game(BasicGame):
Name = "F1 23 Support Plugin"
Author = "ju5tA1ex"
Version = "1.0.0"
GameName = "F1 23"
GameShortName = "F1 23"
GameSteamId = 2108330
GameBinary = "F1_23.exe"
GameDataPath = ""
from ..basic_game import BasicGame
class F123Game(BasicGame):
Name = "F1 23 Support Plugin"
Author = "ju5tA1ex"
Version = "1.0.0"
GameName = "F1 23"
GameShortName = "F1 23"
GameSteamId = 2108330
GameBinary = "F1_23.exe"
GameDataPath = ""
+2 -1
View File
@@ -1,9 +1,10 @@
import os
from pathlib import Path
import mobase
from PyQt6.QtCore import QDir, QFileInfo
import mobase
from ..basic_game import BasicGame

Some files were not shown because too many files have changed in this diff Show More