pyproject.toml
Rama main · réplica de lectura del repositorio original.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "trackstarr"
dynamic = ["version"]
description = "Keep media library audio and subtitle tracks tidy"
readme = "README.md"
license = { file = "LICENSE" }
# What the Alpine image ships and the only version CI tests.
requires-python = ">=3.14"
authors = [{ name = "MarcedForLife" }]
keywords = ["ffmpeg", "media", "radarr", "sonarr", "plex", "transcoding"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Topic :: Multimedia :: Video",
]
# One runtime dependency; the bar for a second is high. cryptography seals the
# credentials in settings.json, which needs an AEAD cipher the stdlib lacks.
# The floor is the first release with musllinux abi3 wheels for Alpine.
dependencies = ["cryptography>=45"]
[project.scripts]
trackstarr = "trackstarr.cli:main"
[project.urls]
Homepage = "https://github.com/MarcedForLife/trackstarr"
Issues = "https://github.com/MarcedForLife/trackstarr/issues"
# A group, so the tooling stays out of the published metadata and `uv sync`
# installs it. Loose bounds: uv.lock pins the versions CI installs.
[dependency-groups]
dev = ["mypy>=2", "pytest>=8", "pytest-cov>=5", "ruff>=0.14"]
[tool.hatch.version]
path = "src/trackstarr/__init__.py"
[tool.hatch.build.targets.wheel]
packages = ["src/trackstarr"]
[tool.pytest.ini_options]
testpaths = ["tests"]
filterwarnings = ["error"]
# strict-markers makes a mark typo an error; strict-config likewise for this
# table.
addopts = ["--strict-markers", "--strict-config"]
# --cov is not in addopts: it slows every run and the in-image suite has no
# pytest-cov. `pytest --cov` picks the settings up from here.
[tool.coverage.run]
source_pkgs = ["trackstarr"]
branch = true
# The `python -m trackstarr` shim: two imports and a call to cli.main.
omit = ["*/trackstarr/__main__.py"]
[tool.coverage.report]
show_missing = true
exclude_also = ["if __name__ == .__main__.:"]
# 100, so a line arriving without a test fails the build the day it lands.
# Untestable code takes an explicit `# pragma: no cover` with a reason; so far
# every one is a thread body or startup wiring. `grep -rn "pragma: no cover"
# src` is the list.
fail_under = 100
# src only; type-checking the tests buys little. Not --strict, which wants a
# type for every ffprobe dict, whose shape is the thing being interrogated.
# These are the strict flags that pass clean today.
[tool.mypy]
files = ["src"]
warn_unused_ignores = true
warn_redundant_casts = true
warn_unreachable = true
no_implicit_reexport = true
strict_equality = true
[tool.ruff]
line-length = 96
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", "W", # pycodestyle
"F", # pyflakes
"I", # isort
"B", # bugbear
"UP", # pyupgrade
"N", # pep8-naming
"SIM", # flake8-simplify
"S", # bandit
"A", # builtin shadowing
"C4", # comprehensions
"DTZ", # naive datetimes
"FURB", # refurb, modern idiom
"G", # logging call format
"ISC", # implicit string concatenation, i.e. the comma you forgot
"LOG", # logging misuse
"PERF", # obviously slow constructs
"PIE", # assorted lint
"RET", # return flow
"SLOT",
"TID", # tidy imports
"PLC", "PLE", # pylint's conventions and errors
"RUF",
]
# Unselected: TRY, PLW, PT, C90 and the PL refactor rules fire only on
# deliberate code here and would buy a row of noqa comments. ANN and D
# duplicate mypy and the docstrings. PTH would be a pathlib migration.
ignore = [
# Subprocess calls are the point of this tool; the argument lists are built
# from validated config, never through a shell.
"S603", "S607",
# 0.0.0.0 is the right default for a container's listener.
"S104",
# urllib only ever gets the configured Radarr/Sonarr base URL.
"S310",
]
[tool.ruff.lint.per-file-ignores]
# S101: asserts are what tests are. S108: the planner tests' /tmp paths are
# never opened. S105-S107: the "passwords" are fixture secrets. DTZ001: the
# cron tests are about naive wall-clock matching.
"tests/*" = ["S101", "S105", "S106", "S107", "S108", "DTZ001"]
[tool.ruff.lint.isort]
# conftest is a local test helper, not a third-party package.
known-first-party = ["trackstarr", "conftest"]