[build-system]
requires = ["hatchling", "hatch-openzim"]
build-backend = "hatchling.build"

[project]
name = "warc2zim"
requires-python = ">=3.13,<3.14"
description = "Convert WARC to ZIM"
readme = "README.md"
dependencies = [
  "warcio==1.7.5",
  "requests==2.32.3",
  "zimscraperlib==5.1.1",
  "jinja2==3.1.5",
  # to support possible brotli content in warcs, must be added separately
  "brotlipy==0.7.0",
  "tinycss2==1.4.0",
  "beautifulsoup4==4.13.3", # used to parse base href
  "lxml==5.3.1", # used by beautifulsoup4 for parsing html
  "python-dateutil==2.9.0.post0",
  "multipart==1.2.1",
]
dynamic = ["authors", "classifiers", "keywords", "license", "version", "urls"]

[tool.hatch.metadata.hooks.openzim-metadata]
kind = "scraper"
additional-keywords = ["warc"]

[[tool.hatch.metadata.hooks.openzim-metadata.additional-authors]]
name="Webrecorder Software"
email="info@webrecorder.net"

[project.optional-dependencies]
scripts = [
  "invoke==2.2.0",
]
lint = [
  "black==25.1.0",
  "ruff==0.9.6",
]
check = [
  "pyright==1.1.394",
]
test = [
  "pytest==8.3.4",
  "coverage==7.6.12",
]
dev = [
  "pre-commit==4.1.0",
  "debugpy==1.8.12",
  "warc2zim[scripts]",
  "warc2zim[lint]",
  "warc2zim[test]",
  "warc2zim[check]",
]

[project.scripts]
warc2zim = "warc2zim.main:main"

[tool.hatch.version]
path = "src/warc2zim/__about__.py"

[tool.hatch.build]
exclude = [
  "/.github",
]

[tool.hatch.build.targets.wheel]
packages = ["src/warc2zim"]

[tool.hatch.envs.default]
features = ["dev"]

[tool.hatch.envs.test]
features = ["scripts", "test"]

[tool.hatch.envs.test.scripts]
run = "inv test --args '{args}'"
run-cov = "inv test-cov --args '{args}'"
report-cov = "inv report-cov"
coverage = "inv coverage --args '{args}'"
html = "inv coverage --html --args '{args}'"

[tool.hatch.envs.lint]
template = "lint"
skip-install = false
features = ["scripts", "lint"]

[tool.hatch.envs.lint.scripts]
black = "inv lint-black --args '{args}'"
ruff = "inv lint-ruff --args '{args}'"
all = "inv lintall --args '{args}'"
fix-black = "inv fix-black --args '{args}'"
fix-ruff = "inv fix-ruff --args '{args}'"
fixall = "inv fixall --args '{args}'"

[tool.hatch.envs.check]
features = ["scripts", "check"]

[tool.hatch.envs.check.scripts]
pyright = "inv check-pyright --args '{args}'"
all = "inv checkall --args '{args}'"

[tool.black]
line-length = 88
target-version = ['py313']

[tool.ruff]
target-version = "py313"
line-length = 88
src = ["src"]

[tool.ruff.lint]
select = [
  "A",  # flake8-builtins
  # "ANN",  # flake8-annotations
  "ARG",  # flake8-unused-arguments
  # "ASYNC",  # flake8-async
  "B",  # flake8-bugbear
  # "BLE",  # flake8-blind-except
  "C4",  # flake8-comprehensions
  "C90",  # mccabe
  # "COM",  # flake8-commas
  # "D",  # pydocstyle
  # "DJ",  # flake8-django
  "DTZ",  # flake8-datetimez
  "E",  # pycodestyle (default)
  "EM",  # flake8-errmsg
  # "ERA",  # eradicate
  # "EXE",  # flake8-executable
  "F",  # Pyflakes (default)
  # "FA",  # flake8-future-annotations
  "FBT",  # flake8-boolean-trap
  # "FLY",  # flynt
  # "G",  # flake8-logging-format
  "I",  # isort
  "ICN",  # flake8-import-conventions
  # "INP",  # flake8-no-pep420
  # "INT",  # flake8-gettext
  "ISC",  # flake8-implicit-str-concat
  "N",  # pep8-naming
  # "NPY",  # NumPy-specific rules
  # "PD",  # pandas-vet
  # "PGH",  # pygrep-hooks
  # "PIE",  # flake8-pie
  # "PL",  # Pylint
  "PLC",  # Pylint: Convention
  "PLE",  # Pylint: Error
  "PLR",  # Pylint: Refactor
  "PLW",  # Pylint: Warning
  # "PT",  # flake8-pytest-style
  # "PTH",  # flake8-use-pathlib
  # "PYI",  # flake8-pyi
  "Q",  # flake8-quotes
  # "RET",  # flake8-return
  # "RSE",  # flake8-raise
  "RUF",  # Ruff-specific rules
  "S",  # flake8-bandit
  # "SIM",  # flake8-simplify
  # "SLF",  # flake8-self
  "T10",  # flake8-debugger
  "T20",  # flake8-print
  # "TCH",  # flake8-type-checking
  # "TD",  # flake8-todos
  "TID",  # flake8-tidy-imports
  # "TRY",  # tryceratops
  "UP",  # pyupgrade
  "W",  # pycodestyle
  "YTT",  # flake8-2020
]
ignore = [
  # Allow non-abstract empty methods in abstract base classes
  "B027",
  # Remove flake8-errmsg since we consider they bloat the code and provide limited value
  "EM",
  # Allow boolean positional values in function calls, like `dict.get(... True)`
  "FBT003",
  # Ignore checks for possible passwords
  "S105", "S106", "S107",
  # Ignore warnings on subprocess.run / popen
  "S603",
  # Ignore complexity
  "C901", "PLR0911", "PLR0912", "PLR0913", "PLR0915",
]
unfixable = [
  # Don't touch unused imports
  "F401",
]

[tool.ruff.lint.isort]
known-first-party = ["warc2zim"]

[tool.ruff.lint.flake8-bugbear]
# add exceptions to B008 for fastapi.
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]

[tool.ruff.lint.flake8-tidy-imports]
ban-relative-imports = "all"

[tool.ruff.lint.per-file-ignores]
# Tests can use magic values, assertions, and relative imports
"tests/**/*" = ["PLR2004", "S101", "TID252"]

[tool.pytest.ini_options]
minversion = "7.3"
testpaths = ["tests"]
pythonpath = [".", "src"]

[tool.coverage.paths]
warc2zim = ["src/warc2zim"]
tests = ["tests"]

[tool.coverage.run]
source_pkgs = ["warc2zim"]
branch = true
parallel = true
omit = [
  "src/warc2zim/__about__.py",
]

[tool.coverage.report]
exclude_lines = [
  "no cov",
  "if __name__ == .__main__.:",
  "if TYPE_CHECKING:",
]

[tool.pyright]
include = ["src", "tests", "tasks.py"]
exclude = [".env/**", ".venv/**"]
extraPaths = ["src"]
pythonVersion = "3.13"
typeCheckingMode = "basic"
disableBytesTypePromotions = true
