Manage Atom feeds in a persistent git repository
1[build-system]
2requires = ["hatchling"]
3build-backend = "hatchling.build"
4
5[project]
6name = "thicket"
7dynamic = ["version"]
8description = "A CLI tool for persisting Atom/RSS feeds in Git repositories"
9readme = "README.md"
10license = "MIT"
11requires-python = ">=3.9"
12authors = [
13 {name = "thicket", email = "thicket@example.com"},
14]
15classifiers = [
16 "Development Status :: 3 - Alpha",
17 "Intended Audience :: Developers",
18 "License :: OSI Approved :: MIT License",
19 "Operating System :: OS Independent",
20 "Programming Language :: Python :: 3",
21 "Programming Language :: Python :: 3.9",
22 "Programming Language :: Python :: 3.10",
23 "Programming Language :: Python :: 3.11",
24 "Programming Language :: Python :: 3.12",
25 "Programming Language :: Python :: 3.13",
26 "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary",
27 "Topic :: Software Development :: Version Control :: Git",
28 "Topic :: Text Processing :: Markup :: XML",
29]
30dependencies = [
31 "typer>=0.15.0",
32 "rich>=13.0.0",
33 "GitPython>=3.1.40",
34 "feedparser>=6.0.11",
35 "pydantic>=2.11.0",
36 "pydantic-settings>=2.10.0",
37 "httpx>=0.28.0",
38 "pendulum>=3.0.0",
39 "bleach>=6.0.0",
40 "platformdirs>=4.0.0",
41 "pyyaml>=6.0.0",
42 "email_validator"
43]
44
45[project.optional-dependencies]
46dev = [
47 "pytest>=8.0.0",
48 "pytest-asyncio>=0.24.0",
49 "pytest-cov>=6.0.0",
50 "black>=24.0.0",
51 "ruff>=0.8.0",
52 "mypy>=1.13.0",
53 "types-PyYAML>=6.0.0",
54]
55
56[project.urls]
57Homepage = "https://github.com/example/thicket"
58Documentation = "https://github.com/example/thicket"
59Repository = "https://github.com/example/thicket"
60"Bug Tracker" = "https://github.com/example/thicket/issues"
61
62[project.scripts]
63thicket = "thicket.cli.main:app"
64
65[tool.hatch.version]
66path = "src/thicket/__init__.py"
67
68[tool.hatch.build.targets.wheel]
69packages = ["src/thicket"]
70
71[tool.black]
72line-length = 88
73target-version = ['py39']
74include = '\.pyi?$'
75extend-exclude = '''
76/(
77 # directories
78 \.eggs
79 | \.git
80 | \.hg
81 | \.mypy_cache
82 | \.tox
83 | \.venv
84 | build
85 | dist
86)/
87'''
88
89[tool.ruff]
90target-version = "py39"
91line-length = 88
92
93[tool.ruff.lint]
94select = [
95 "E", # pycodestyle errors
96 "W", # pycodestyle warnings
97 "F", # pyflakes
98 "I", # isort
99 "B", # flake8-bugbear
100 "C4", # flake8-comprehensions
101 "UP", # pyupgrade
102]
103ignore = [
104 "E501", # line too long, handled by black
105 "B008", # do not perform function calls in argument defaults
106 "C901", # too complex
107]
108
109[tool.ruff.lint.per-file-ignores]
110"__init__.py" = ["F401"]
111
112[tool.mypy]
113python_version = "3.9"
114check_untyped_defs = true
115disallow_any_generics = true
116disallow_incomplete_defs = true
117disallow_untyped_defs = true
118no_implicit_optional = true
119warn_redundant_casts = true
120warn_unused_ignores = true
121warn_return_any = true
122strict_optional = true
123
124[[tool.mypy.overrides]]
125module = [
126 "feedparser",
127 "git",
128 "bleach",
129]
130ignore_missing_imports = true
131
132[tool.pytest.ini_options]
133testpaths = ["tests"]
134python_files = ["test_*.py"]
135python_classes = ["Test*"]
136python_functions = ["test_*"]
137addopts = [
138 "-ra",
139 "--strict-markers",
140 "--strict-config",
141 "--cov=src/thicket",
142 "--cov-report=term-missing",
143 "--cov-report=html",
144 "--cov-report=xml",
145]
146filterwarnings = [
147 "error",
148 "ignore::UserWarning",
149 "ignore::DeprecationWarning",
150]
151markers = [
152 "slow: marks tests as slow (deselect with '-m \"not slow\"')",
153 "integration: marks tests as integration tests",
154]
155
156[tool.coverage.run]
157source = ["src"]
158branch = true
159
160[tool.coverage.report]
161exclude_lines = [
162 "pragma: no cover",
163 "def __repr__",
164 "if self.debug:",
165 "if settings.DEBUG",
166 "raise AssertionError",
167 "raise NotImplementedError",
168 "if 0:",
169 "if __name__ == .__main__.:",
170 "class .*\\bProtocol\\):",
171 "@(abc\\.)?abstractmethod",
172]