# SPDX-FileCopyrightText: 2025 icalendar-anonymizer contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# icalendar-anonymizer - Strip personal data from iCalendar files
# See https://packaging.python.org/en/latest/specifications/pyproject-toml/
#

[build-system]
requires = ["hatchling>=1.27.0", "hatch-vcs"]
build-backend = "hatchling.build"

[project]
name = "icalendar-anonymizer"
license = "AGPL-3.0-or-later"
keywords = [
    "icalendar",
    "calendar",
    "anonymizer",
    "privacy",
    "ics",
    "vcalendar",
]
authors = [
    { name = "Sashank Bhamidi", email = "hello@sashank.wiki" },
    { name = "Nicco Kunzmann", email = "niccokunzmann@rambler.ru" },
    { name = "Abe Hanoka", email = "abe@habet.dev" },
]
maintainers = [
    { name = "Sashank Bhamidi", email = "hello@sashank.wiki" },
    { name = "Nicco Kunzmann", email = "niccokunzmann@rambler.ru" },
    { name = "Abe Hanoka", email = "abe@habet.dev" },
]
dynamic = ["urls", "version"]
description = "Strip personal data from iCalendar files while preserving technical properties for bug reproduction"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"

# see https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: Implementation :: CPython",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Topic :: Office/Business :: Scheduling",
]

dependencies = [
    "icalendar>=7.0.0",
]

[project.optional-dependencies]
cli = ["click>=8.3.1"]

web = [
    "fastapi>=0.128.0",
    "uvicorn>=0.38.0",
    "python-multipart>=0.0.18",
    "httpx>=0.28.1",
]

dev = [
    "pytest>=9.0",
    "pytest-cov>=6.0",
    "pytest-asyncio>=1.3.0",
    "coverage>=7.11",
    "ruff>=0.14.0",
    "reuse>=6.2",
    "commitizen>=4.10",
    "pre-commit>=4.4",
    "build>=1.3",
    "twine>=6.2",
]

doc = [
    "sphinx>=8.2",
    "pydata-sphinx-theme>=0.16.0",
    "sphinx-copybutton>=0.5.2",
    "sphinx-design>=0.6.0",
]

test = [
    "pytest>=9.0",
    "pytest-cov>=6.0",
    "pytest-asyncio>=1.3.0",
    "coverage>=7.11",
    "hypothesis>=6.147",
    "click>=8.3.1",
    "pytest-httpx>=0.30.0",
]

all = ["icalendar-anonymizer[cli,web,dev,doc]"]

[project.scripts]
icalendar-anonymize = "icalendar_anonymizer.cli:main"
ican = "icalendar_anonymizer.cli:main"

[tool.hatch.build]
exclude = ["/.*", "/*.*", "/dist", "/build", "/htmlcov"]

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

[tool.hatch.version]
source = "vcs"

[tool.hatch.version.raw-options]
local_scheme = "no-local-version"

[tool.hatch.build.hooks.vcs]
version-file = "src/icalendar_anonymizer/_version.py"

[tool.hatch.metadata.hooks.vcs.urls]
Homepage = "https://docs.icalendar-anonymizer.com"
Documentation = "https://docs.icalendar-anonymizer.com"
Repository = "https://github.com/pycalendar/icalendar-anonymizer"
Changelog = "https://docs.icalendar-anonymizer.com/stable/changelog.html"
Issues = "https://github.com/pycalendar/icalendar-anonymizer/issues"
Discussions = "https://github.com/pycalendar/icalendar-anonymizer/discussions"
source_archive = "https://github.com/pycalendar/icalendar-anonymizer/archive/{commit_hash}.zip"

[tool.hatch.metadata]
allow-direct-references = true

[tool.ruff]
target-version = "py311"
line-length = 100
unsafe-fixes = true

[tool.ruff.lint]
select = ["ALL"]
ignore = [
    "ANN",     # flake8-annotations
    "C401",    # Unnecessary generator (rewrite as a set comprehension)
    "C901",    # {name} is too complex ({complexity} > {max_complexity})
    "COM812",  # Trailing comma missing
    "D1",      # Missing docstring
    "PLC0415", # Import should be at top-level (common pattern in pytest)
    "D2",      # docstrings stuffs
    "D4",      # docstrings stuffs
    "EM10",    # Exception string usage
    "ERA001",  # Found commented-out code
    "FBT002",  # Boolean default positional argument in function definition
    "FIX",     # TODO comments
    "ISC001",  # Implicitly concatenated string literals on one line (to avoid with formatter)
    "PLR091",  # Too many things (complexity, arguments, branches, etc...)
    "PLR2004", # Magic value used in comparison
    "S101",    # Use of assert detected
    "TD",      # TODO comments
    "TRY003",  # Avoid specifying long messages outside the exception class
]

extend-safe-fixes = [
    "PT006", # Wrong type passed to first argument of @pytest.mark.parametrize
]

[tool.ruff.lint.per-file-ignores]
"src/icalendar_anonymizer/tests/*" = [
    "B011",   # Do not assert False
    "DTZ001", # datetime.datetime() called without a tzinfo argument
    "E501",   # Line too long
    "N802",   # Function name should be lowercase
    "PT011",  # pytest.raises too broad
    "PT012",  # pytest.raises() block should contain a single simple statement
    "PT015",  # Assertion always fails
    "T201",   # print found
    "T203",   # pprint found
    "RUF001", # String contains ambiguous character
    "SIM300", # Yoda condition
    "SLF001", # Private member accessed
    "N999",   # module name
    "PT027",  # assertRaises
]
"docs/*" = [
    "INP001", # implicit namespace package
]
"src/icalendar_anonymizer/webapp/vendored/*" = [
    "ALL",  # Vendored code - skip all linting
]

[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["src/icalendar_anonymizer/tests"]
norecursedirs = ["build", "dist", ".eggs"]
filterwarnings = ["ignore::DeprecationWarning"]
asyncio_mode = "auto"

[tool.coverage.run]
source = ["src"]
branch = true
omit = [
    "src/icalendar_anonymizer/_version.py",
    "src/icalendar_anonymizer/webapp/vendored/*",
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise AssertionError",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
    "if TYPE_CHECKING:",
    "@abstractmethod",
]

[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.11", "3.12", "3.13"]
