pyproject.toml 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. [project]
  2. name = "borgbackup"
  3. dynamic = ["version", "readme"]
  4. authors = [{name="The Borg Collective (see AUTHORS file)"}]
  5. maintainers = [
  6. {name="Thomas Waldmann", email="tw@waldmann-edv.de"},
  7. ]
  8. description = "Deduplicated, encrypted, authenticated, and compressed backups"
  9. requires-python = ">=3.10"
  10. keywords = ["backup", "borgbackup"]
  11. classifiers = [
  12. "Development Status :: 4 - Beta",
  13. "Environment :: Console",
  14. "Intended Audience :: System Administrators",
  15. "Operating System :: POSIX :: BSD :: FreeBSD",
  16. "Operating System :: POSIX :: BSD :: OpenBSD",
  17. "Operating System :: POSIX :: BSD :: NetBSD",
  18. "Operating System :: MacOS :: MacOS X",
  19. "Operating System :: POSIX :: Linux",
  20. "Programming Language :: Python",
  21. "Programming Language :: Python :: 3",
  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. "Programming Language :: Python :: 3.14",
  27. "Topic :: Security :: Cryptography",
  28. "Topic :: System :: Archiving :: Backup",
  29. ]
  30. license = "BSD-3-Clause"
  31. license-files = ["LICENSE", "AUTHORS"]
  32. dependencies = [
  33. "borghash ~= 0.1.0",
  34. "borgstore ~= 0.3.0",
  35. "msgpack >=1.0.3, <=1.1.2",
  36. "packaging",
  37. "platformdirs >=3.0.0, <5.0.0; sys_platform == 'darwin'", # for macOS: breaking changes in 3.0.0.
  38. "platformdirs >=2.6.0, <5.0.0; sys_platform != 'darwin'", # for others: 2.6+ works consistently.
  39. "argon2-cffi",
  40. "shtab>=1.8.0",
  41. ]
  42. [project.optional-dependencies]
  43. llfuse = ["llfuse >= 1.3.8"] # fuse 2, low-level
  44. pyfuse3 = ["pyfuse3 >= 3.1.1"] # fuse 3, low-level, async
  45. mfusepy = ["mfusepy >= 3.1.0, <4.0.0"] # fuse 2+3, high-level
  46. # a pypi release of borgbackup can't contain a dependency on github!
  47. # mfusepym = ["mfusepy @ git+https://github.com/mxmlnkn/mfusepy.git@master"]
  48. nofuse = []
  49. s3 = ["borgstore[s3] ~= 0.3.0"]
  50. sftp = ["borgstore[sftp] ~= 0.3.0"]
  51. cockpit = ["textual>=6.8.0"] # might also work with older versions, untested
  52. [project.urls]
  53. "Homepage" = "https://borgbackup.org/"
  54. "Bug Tracker" = "https://github.com/borgbackup/borg/issues"
  55. "Documentation" = "https://borgbackup.readthedocs.io/"
  56. "Repository" = "https://github.com/borgbackup/borg"
  57. "Changelog" = "https://github.com/borgbackup/borg/blob/master/docs/changes.rst"
  58. [project.scripts]
  59. borg = "borg.archiver:main"
  60. borgfs = "borg.archiver:main"
  61. [tool.setuptools]
  62. # See also the MANIFEST.in file.
  63. # We want to install all the files in the package directories...
  64. include-package-data = true
  65. [tool.setuptools.packages.find]
  66. where = ["src"]
  67. [tool.setuptools.exclude-package-data]
  68. # ...except the source files which have been compiled (C extensions):
  69. "*" = ["*.c", "*.h", "*.pyx"]
  70. [build-system]
  71. requires = ["setuptools>=78.1.1", "wheel", "pkgconfig", "Cython>=3.0.3", "setuptools_scm[toml]>=6.2"]
  72. build-backend = "setuptools.build_meta"
  73. [tool.setuptools_scm]
  74. # Make sure we have the same versioning scheme with all setuptools_scm versions, to avoid different autogenerated files.
  75. # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015052
  76. # https://github.com/borgbackup/borg/issues/6875
  77. write_to = "src/borg/_version.py"
  78. write_to_template = "__version__ = version = {version!r}\n"
  79. [tool.black]
  80. line-length = 120
  81. skip-magic-trailing-comma = true
  82. [tool.ruff]
  83. line-length = 120
  84. target-version = "py310"
  85. # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
  86. select = ["E", "F"]
  87. # for reference ...
  88. # E402 module level import not at top
  89. # E501 line too long
  90. # F401 import unused
  91. # F405 undefined or defined from star imports
  92. # F811 redef of unused var
  93. # borg code style guidelines:
  94. # Ignoring E203 due to https://github.com/PyCQA/pycodestyle/issues/373.
  95. ignore = ["E203", "F405", "E402"]
  96. # Allow autofix for all enabled rules (when `--fix` is provided).
  97. fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
  98. unfixable = []
  99. # Exclude a variety of commonly ignored directories.
  100. exclude = [
  101. ".cache",
  102. ".eggs",
  103. ".git",
  104. ".git-rewrite",
  105. ".idea",
  106. ".mypy_cache",
  107. ".ruff_cache",
  108. ".tox",
  109. "build",
  110. "dist",
  111. ]
  112. # Allow unused variables when underscore-prefixed.
  113. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
  114. # Code style violation exceptions:
  115. # please note that the values are adjusted so that they do not cause failures
  116. # with existing code. if you want to change them, you should first fix all
  117. # ruff failures that appear with your change.
  118. [tool.ruff.per-file-ignores]
  119. "scripts/make.py" = ["E501"]
  120. "src/borg/archive.py" = ["E501"]
  121. "src/borg/archiver/help_cmd.py" = ["E501"]
  122. "src/borg/cache.py" = ["E501"]
  123. "src/borg/helpers/__init__.py" = ["F401"]
  124. "src/borg/platform/__init__.py" = ["F401"]
  125. "src/borg/testsuite/archiver/disk_full_test.py" = ["F811"]
  126. "src/borg/testsuite/archiver/return_codes_test.py" = ["F811"]
  127. "src/borg/testsuite/benchmark_test.py" = ["F811"]
  128. "src/borg/testsuite/platform_test.py" = ["F811"]
  129. [tool.pytest.ini_options]
  130. markers = []
  131. [tool.mypy]
  132. python_version = "3.10"
  133. strict_optional = false
  134. local_partial_types = true
  135. show_error_codes = true
  136. files = "src/borg/**/*.py"
  137. [[tool.mypy.overrides]]
  138. module = [
  139. "msgpack.*",
  140. "llfuse",
  141. "pyfuse3",
  142. "trio",
  143. "borg.crypto.low_level",
  144. "borg.platform.*",
  145. ]
  146. ignore_missing_imports = true
  147. [tool.tox]
  148. requires = ["tox>=4.19", "pkgconfig", "cython", "wheel", "setuptools_scm"]
  149. # Important: when adding/removing Python versions here,
  150. # also update the section "Test environments with different FUSE implementations" accordingly.
  151. env_list = ["py{310,311,312,313,314}-{none,llfuse,pyfuse3,mfusepy}", "docs", "ruff", "mypy", "bandit"]
  152. [tool.tox.env_run_base]
  153. package = "editable-legacy" # without this it does not find setup_docs when running under fakeroot
  154. deps = ["-rrequirements.d/development.txt"]
  155. commands = [["python", "-m", "pytest", "-v", "-n", "{env:XDISTN:auto}", "-rs", "--cov=borg", "--cov-config=pyproject.toml", "--benchmark-skip", "--pyargs", "{posargs:borg.testsuite}"]]
  156. pass_env = ["*"] # fakeroot -u needs some env vars
  157. [tool.tox.env_pkg_base]
  158. pass_env = ["*"] # needed by tox4, so env vars are visible for building borg
  159. # Test environments with different FUSE implementations
  160. [tool.tox.env.py310-none]
  161. [tool.tox.env.py310-llfuse]
  162. set_env = {BORG_FUSE_IMPL = "llfuse"}
  163. extras = ["llfuse", "sftp", "s3"]
  164. [tool.tox.env.py310-pyfuse3]
  165. set_env = {BORG_FUSE_IMPL = "pyfuse3"}
  166. extras = ["pyfuse3", "sftp", "s3"]
  167. [tool.tox.env.py310-mfusepy]
  168. set_env = {BORG_FUSE_IMPL = "mfusepy"}
  169. extras = ["mfusepy", "sftp", "s3"]
  170. [tool.tox.env.py311-none]
  171. [tool.tox.env.py311-llfuse]
  172. set_env = {BORG_FUSE_IMPL = "llfuse"}
  173. extras = ["llfuse", "sftp", "s3"]
  174. [tool.tox.env.py311-pyfuse3]
  175. set_env = {BORG_FUSE_IMPL = "pyfuse3"}
  176. extras = ["pyfuse3", "sftp", "s3"]
  177. [tool.tox.env.py311-mfusepy]
  178. set_env = {BORG_FUSE_IMPL = "mfusepy"}
  179. extras = ["mfusepy", "sftp", "s3"]
  180. [tool.tox.env.py312-none]
  181. [tool.tox.env.py312-llfuse]
  182. set_env = {BORG_FUSE_IMPL = "llfuse"}
  183. extras = ["llfuse", "sftp", "s3"]
  184. [tool.tox.env.py312-pyfuse3]
  185. set_env = {BORG_FUSE_IMPL = "pyfuse3"}
  186. extras = ["pyfuse3", "sftp", "s3"]
  187. [tool.tox.env.py312-mfusepy]
  188. set_env = {BORG_FUSE_IMPL = "mfusepy"}
  189. extras = ["mfusepy", "sftp", "s3"]
  190. [tool.tox.env.py313-none]
  191. [tool.tox.env.py313-llfuse]
  192. set_env = {BORG_FUSE_IMPL = "llfuse"}
  193. extras = ["llfuse", "sftp", "s3"]
  194. [tool.tox.env.py313-pyfuse3]
  195. set_env = {BORG_FUSE_IMPL = "pyfuse3"}
  196. extras = ["pyfuse3", "sftp", "s3"]
  197. [tool.tox.env.py313-mfusepy]
  198. set_env = {BORG_FUSE_IMPL = "mfusepy"}
  199. extras = ["mfusepy", "sftp", "s3"]
  200. [tool.tox.env.py314-none]
  201. [tool.tox.env.py314-llfuse]
  202. set_env = {BORG_FUSE_IMPL = "llfuse"}
  203. extras = ["llfuse", "sftp", "s3"]
  204. [tool.tox.env.py314-pyfuse3]
  205. set_env = {BORG_FUSE_IMPL = "pyfuse3"}
  206. extras = ["pyfuse3", "sftp", "s3"]
  207. [tool.tox.env.py314-mfusepy]
  208. set_env = {BORG_FUSE_IMPL = "mfusepy"}
  209. extras = ["mfusepy", "sftp", "s3"]
  210. [tool.tox.env.ruff]
  211. skip_install = true
  212. deps = ["ruff"]
  213. commands = [["ruff", "check", "."]]
  214. [tool.tox.env.mypy]
  215. deps = ["pytest", "mypy", "pkgconfig"]
  216. commands = [["mypy", "--ignore-missing-imports"]]
  217. [tool.tox.env.docs]
  218. change_dir = "docs"
  219. deps = ["sphinx", "sphinxcontrib-jquery", "guzzle_sphinx_theme"]
  220. commands = [["sphinx-build", "-n", "-v", "-W", "--keep-going", "-b", "html", "-d", "{envtmpdir}/doctrees", ".", "{envtmpdir}/html"]]
  221. [tool.bandit]
  222. exclude_dirs = [".cache", ".eggs", ".git", ".git-rewrite", ".idea", ".mypy_cache", ".ruff_cache", ".tox", "build", "dist", "src/borg/testsuite"]
  223. skips = [
  224. "B101", # skip assert warnings, we do not allow running borg with assertions disabled.
  225. "B404", # do not warn about just import subprocess
  226. ]
  227. [tool.tox.env.bandit]
  228. skip_install = true
  229. deps = ["bandit[toml]"]
  230. commands = [["bandit", "-r", "src/borg", "-c", "pyproject.toml"]]
  231. [tool.coverage.run]
  232. branch = true
  233. disable_warnings = ["module-not-measured", "no-ctracer"]
  234. source = ["src/borg"]
  235. omit = [
  236. "*/borg/__init__.py",
  237. "*/borg/__main__.py",
  238. "*/borg/_version.py",
  239. "*/borg/fuse.py",
  240. "*/borg/support/*",
  241. "*/borg/testsuite/*",
  242. "*/borg/hash_sizes.py",
  243. ]
  244. [tool.coverage.report]
  245. exclude_lines = [
  246. "pragma: no cover",
  247. "pragma: freebsd only",
  248. "pragma: unknown platform only",
  249. "def __repr__",
  250. "raise AssertionError",
  251. "raise NotImplementedError",
  252. "if 0:",
  253. "if __name__ == .__main__.:",
  254. ]
  255. ignore_errors = true