Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
185 lines (163 loc) · 6.67 KB
/
Copy pathpyproject.toml
File metadata and controls
185 lines (163 loc) · 6.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
[project]
name = "steamcleaner"
version = "1.2.0"
description = "Cross-platform GUI tool (Windows, macOS, Linux) for reclaiming disk space from Steam, Epic Games, EA App, GOG Galaxy, and Ubisoft Connect"
readme = "README.md"
license = "MIT"
requires-python = ">=3.14" # also the Python that `flet build` bundles into the binary
authors = [
{ name = "Solganis", email = "solganis.dev@gmail.com" },
]
keywords = ["steam", "epic", "gog", "ubisoft", "ea", "disk-cleanup", "cache-cleaner"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: MacOS X",
"Environment :: Win32 (MS Windows)",
"Environment :: X11 Applications",
"Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: MIT License",
"Natural Language :: Chinese (Simplified)",
"Natural Language :: English",
"Natural Language :: Portuguese (Brazilian)",
"Natural Language :: Russian",
"Natural Language :: Spanish",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.14",
"Topic :: System :: Filesystems",
"Topic :: Utilities",
]
dependencies = [
"darkdetect>=0.8.0",
"flet>=1.0.3",
"send2trash>=2.1.0",
]
[project.urls]
Homepage = "https://github.com/Solganis/SteamCleaner"
Repository = "https://github.com/Solganis/SteamCleaner"
Issues = "https://github.com/Solganis/SteamCleaner/issues"
[project.scripts]
steamcleaner = "steamcleaner.app:main"
[tool.flet]
org = "dev.steamcleaner"
product = "SteamCleaner"
[tool.flet.app]
path = "src"
[tool.flet.windows.app]
hide_window_on_start = true # the app shows the window itself once Python is ready, so no empty frame flashes
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/steamcleaner"]
# Listed rather than filtered: hatchling reads only `.gitignore`, so anything kept out of git through
# `.git/info/exclude` would ship in an sdist built from a working tree.
[tool.hatch.build.targets.sdist]
include = [
"src",
"tests",
"scripts/drop_exempt_survivors.py",
"scripts/prune_bundle.py",
"README.md",
"LICENSE",
"CONTRIBUTING.md",
"SECURITY.md",
]
[dependency-groups]
dev = [
"assertpy2>=2.29.1",
"hypothesis>=6.168.3",
"pytest>=9.1.1",
"pytest-cov>=7.1.0",
"ruff>=0.16.10",
"ty>=0.0.84",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src", "tests"] # the package from src/ and shared test helpers from tests/
# --strict-markers: an unknown @pytest.mark.* is an error, not a silent typo
addopts = ["--import-mode=importlib", "--strict-markers"]
xfail_strict = true # an xfail that unexpectedly passes fails the run
# A deprecation or runtime warning fails the run instead of scrolling past. Add a targeted
# `"ignore::<Category>"` here only if a third-party warning forces it.
filterwarnings = ["error"]
[tool.coverage.run]
branch = true
source = ["steamcleaner"]
# Out of the 100% target by scope: ui/* is flet GUI paint, windows.py, recycle_bin.py and macos.py each run on one OS
# only, so no single run covers them all (their tests run on the matching CI job), __main__.py and app.py are
# entry-point wiring.
omit = [
"src/steamcleaner/ui/*",
"src/steamcleaner/platform/windows.py",
"src/steamcleaner/platform/recycle_bin.py",
"src/steamcleaner/platform/macos.py",
"src/steamcleaner/__main__.py",
"src/steamcleaner/app.py",
]
[tool.coverage.report]
# Only what never runs under test by construction. A line that can be tested is tested, and a single line
# that cannot is marked `# pragma: no cover` with its reason beside it.
exclude_lines = [
"if __name__ == .__main__.",
"if TYPE_CHECKING:",
"pragma: no cover",
]
[tool.ruff]
# 120 feeds both `ruff format` and the E501 lint: line length is a hard rule, not just a formatter hint.
line-length = 120
target-version = "py314"
# Under preview ruff prints rule names instead of codes. Keep the codes: they are what a `# noqa` needs.
output-prefer-rule-codes = true
[tool.ruff.lint]
# Preview rules only when named in `select` (E301), never the whole unstable set.
preview = true
explicit-preview-rules = true
# Curated set, not "ALL": each prefix is here on purpose.
select = [
"E", # pycodestyle errors
"E301", # pycodestyle, preview-gated: a blank line between methods (not in stable "E")
"F", # Pyflakes: unused imports and names, undefined names
"W", # pycodestyle warnings
"N", # pep8-naming
"I", # isort
"UP", # pyupgrade: modernize syntax to the py314 floor
"B", # flake8-bugbear: likely bugs and footguns
"A", # flake8-builtins: don't shadow builtins
"ANN", # flake8-annotations: type hints on everything
"ASYNC", # flake8-async: blocking calls inside the flet async handlers
"C4", # flake8-comprehensions: drop redundant list()/dict()/set() wrappers
"FURB", # refurb: idiom simplifications
"PIE", # flake8-pie: small idiom simplifications
"RSE", # flake8-raise: no empty parens on a bare `raise SomeError`
"PGH", # pygrep-hooks: a suppression must name its rule code
"PLE", # Pylint errors: the real-error subset, not style
"SIM", # flake8-simplify: collapse redundant constructs
"T10", # flake8-debugger: no committed breakpoint()/pdb calls
"RUF", # Ruff-specific rules
"ERA", # eradicate: no commented-out code
"PERF", # Perflint: performance anti-patterns
"TC", # flake8-type-checking: typing-only imports under TYPE_CHECKING
"C901", # mccabe: a ratchet rather than a bar, see the threshold below
]
# Intentionally empty: nothing is ignored globally. Relaxations go in per-file-ignores.
ignore = []
[tool.ruff.lint.mccabe]
# A ratchet, not a bar: the worst function sits at 22, so this stops a new worst without forcing a rewrite.
max-complexity = 22
[tool.ruff.lint.flake8-type-checking]
# Dataclass annotations are read at run time (hypothesis `st.builds`), so their imports must stay real.
runtime-evaluated-decorators = ["dataclasses.dataclass"]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["ANN"] # tests omit `-> None` and fixture-parameter annotations by convention
[tool.ty.environment]
python-version = "3.14"
# Every platform, not the runner's: each OS has its own PlatformAdapter and all of them must type-check.
python-platform = "all"
[tool.ty.analysis]
# Suppressions must be ty-native `# ty: ignore[rule]`, so a stray mypy `# type: ignore` cannot mask a ty error.
respect-type-ignore-comments = false