EU-Utility/pyproject.toml

329 lines
7.8 KiB
TOML

# EU-Utility - Modern Python Packaging Configuration
# https://github.com/ImpulsiveFPS/EU-Utility
[build-system]
requires = [
"setuptools>=65.0",
"wheel>=0.41.0",
"setuptools-scm>=7.0",
]
build-backend = "setuptools.build_meta"
[project]
name = "eu-utility"
version = "2.1.0"
description = "A versatile Entropia Universe utility suite with a modular plugin system"
readme = "README.md"
license = {text = "MIT"}
authors = [
{name = "ImpulsiveFPS", email = "dev@impulsivefps.com"},
]
maintainers = [
{name = "ImpulsiveFPS", email = "dev@impulsivefps.com"},
]
keywords = [
"entropia universe",
"game utility",
"overlay",
"plugin system",
"ocr",
"tracker",
"calculator",
"gaming",
"mmorpg",
]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Games/Entertainment",
"Topic :: Utilities",
"Topic :: Desktop Environment",
"Environment :: X11 Applications :: Qt",
"Environment :: Win32 (MS Windows)",
"Natural Language :: English",
]
requires-python = ">=3.11"
dependencies = [
"PyQt6>=6.4.0,<7.0.0",
"keyboard>=0.13.5,<1.0.0",
"psutil>=5.9.0,<6.0.0",
"pyperclip>=1.8.2,<2.0.0",
"easyocr>=1.7.0,<2.0.0",
"pytesseract>=0.3.10,<1.0.0",
"pyautogui>=0.9.54,<1.0.0",
"pillow>=10.0.0,<11.0.0",
"requests>=2.28.0,<3.0.0",
"urllib3>=1.26.0,<3.0.0",
"numpy>=1.21.0,<2.0.0",
'portalocker>=2.7.0; platform_system=="Windows"',
'pywin32>=306; platform_system=="Windows"',
]
[project.optional-dependencies]
spotify = [
"spotipy>=2.23.0,<3.0.0",
'pycaw>=20230407; platform_system=="Windows"',
]
discord = [
"pypresence>=4.3.0,<5.0.0",
]
all = [
"spotipy>=2.23.0,<3.0.0",
'pycaw>=20230407; platform_system=="Windows"',
"pypresence>=4.3.0,<5.0.0",
]
dev = [
"pytest>=7.4.0,<8.0.0",
"pytest-cov>=4.1.0,<5.0.0",
"pytest-mock>=3.11.0,<4.0.0",
"pytest-benchmark>=4.0.0,<5.0.0",
"pytest-qt>=4.2.0,<5.0.0",
"pytest-xvfb>=2.0.0,<3.0.0",
"black>=23.0.0,<24.0.0",
"flake8>=6.0.0,<7.0.0",
"mypy>=1.5.0,<2.0.0",
"isort>=5.12.0,<6.0.0",
"pydocstyle>=6.3.0,<7.0.0",
"bandit>=1.7.5,<2.0.0",
"safety>=2.3.0,<3.0.0",
"sphinx>=7.0.0,<8.0.0",
"sphinx-rtd-theme>=1.3.0,<2.0.0",
"myst-parser>=2.0.0,<3.0.0",
"build>=0.10.0,<1.0.0",
"twine>=4.0.0,<5.0.0",
"wheel>=0.41.0,<1.0.0",
"pre-commit>=3.4.0,<4.0.0",
]
[project.scripts]
eu-utility = "core.main:main"
eu-utility-secure = "core.main_optimized:main"
[project.gui-scripts]
eu-utility-gui = "core.main:main"
[project.urls]
Homepage = "https://github.com/ImpulsiveFPS/EU-Utility"
Documentation = "https://github.com/ImpulsiveFPS/EU-Utility/tree/main/docs"
Repository = "https://github.com/ImpulsiveFPS/EU-Utility.git"
"Bug Tracker" = "https://github.com/ImpulsiveFPS/EU-Utility/issues"
Changelog = "https://github.com/ImpulsiveFPS/EU-Utility/blob/main/CHANGELOG.md"
# =============================================================================
# TOOL CONFIGURATIONS
# =============================================================================
# Black - Code Formatter
[tool.black]
line-length = 100
target-version = ["py311", "py312"]
include = '\.pyi?$'
extend-exclude = '''
/(
\.git
| \.venv
| venv
| env
| build
| dist
| __pycache__
| \.pytest_cache
| htmlcov
| \.tox
| migrations
)/
'''
skip-string-normalization = false
preview = false
# isort - Import Sorting
[tool.isort]
profile = "black"
line_length = 100
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
skip = [".git", "__pycache__", "venv", ".venv", "build", "dist"]
known_first_party = ["core", "plugins"]
known_third_party = ["PyQt6", "pytest"]
# flake8 - Linting
[tool.flake8]
max-line-length = 100
extend-ignore = [
"E203", # Whitespace before ':' (conflicts with black)
"E501", # Line too long (handled by black)
"W503", # Line break before binary operator (black style)
]
exclude = [
".git",
"__pycache__",
".venv",
"venv",
"build",
"dist",
".pytest_cache",
"htmlcov",
".tox",
"migrations",
]
per-file-ignores = [
"__init__.py:F401,F403",
"test_*.py:S101",
]
max-complexity = 10
# mypy - Type Checking
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = false
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
show_error_codes = true
show_column_numbers = true
show_error_context = true
pretty = true
# Module-specific settings
[[tool.mypy.overrides]]
module = [
"pytesseract.*",
"pyautogui.*",
"easyocr.*",
"keyboard.*",
"psutil.*",
"PIL.*",
"win32con.*",
"win32gui.*",
"win32api.*",
"portalocker.*",
]
ignore_missing_imports = true
# pytest - Testing
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-v",
"--tb=short",
"--strict-markers",
"--cov=core",
"--cov=plugins",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml",
"--cov-fail-under=80",
]
markers = [
"unit: Unit tests for individual components",
"integration: Integration tests for plugin interactions",
"ui: UI automation tests",
"performance: Performance benchmarks",
"slow: Slow tests that may be skipped in CI",
"requires_qt: Tests requiring PyQt6",
"requires_network: Tests requiring network access",
]
filterwarnings = [
"ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
]
# Coverage - Code Coverage
[tool.coverage.run]
source = ["core", "plugins"]
branch = true
omit = [
"*/tests/*",
"*/test_*",
"*/venv/*",
"*/.venv/*",
"setup.py",
"run_tests.py",
"code_review_report.py",
"*/benchmarks/*",
"*_vulnerable.py",
]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if settings.DEBUG",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if __name__ == .__main__.:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
"pass",
]
fail_under = 80
show_missing = true
skip_covered = false
[tool.coverage.html]
directory = "htmlcov"
# Bandit - Security Linter
[tool.bandit]
exclude_dirs = [
"tests",
"test",
".venv",
"venv",
"build",
"dist",
]
skips = [
"B101", # assert_used (common in Python code)
"B311", # random (acceptable for non-cryptographic use)
]
# Pydocstyle - Docstring Conventions
[tool.pydocstyle]
convention = "google"
match = "(?!test_).*\\.py"
match_dir = "^(?!tests|\\.venv|venv|build|dist).*"
add_ignore = [
"D100", # Missing docstring in public module
"D104", # Missing docstring in public package
"D107", # Missing docstring in __init__
]
# setuptools - Package Discovery
[tool.setuptools]
packages = ["core", "core.*", "plugins", "plugins.*"]
include-package-data = true
zip-safe = false
[tool.setuptools.package-data]
core = ["*.json", "*.yaml", "*.yml", "*.css", "*.qss"]
plugins = ["*/assets/*", "*/templates/*"]
[tool.setuptools.exclude-package-data]
core = ["tests/*", "*_test.py", "test_*.py"]
plugins = ["tests/*", "*_test.py", "test_*.py"]