dar-backup 1.0.2__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. {dar_backup-1.0.2 → dar_backup-1.1.0}/.gitignore +1 -0
  2. {dar_backup-1.0.2 → dar_backup-1.1.0}/Changelog.md +27 -0
  3. {dar_backup-1.0.2 → dar_backup-1.1.0}/PKG-INFO +243 -25
  4. {dar_backup-1.0.2 → dar_backup-1.1.0}/README.md +237 -22
  5. dar_backup-1.1.0/doc/test-report/coverage.xml +3913 -0
  6. dar_backup-1.1.0/doc/test-report/dar-backup-1.1.0__pytest-full__2026-02-05T15-05-00Z.json +1 -0
  7. dar_backup-1.1.0/doc/test-report/dar-backup-1.1.0__pytest-full__2026-02-05T15-05-00Z.txt +31 -0
  8. dar_backup-1.1.0/doc/test-report/dar-backup-1.1.0__pytest-full__2026-02-05T15-05-00Z__collect.txt +565 -0
  9. {dar_backup-1.0.2 → dar_backup-1.1.0}/pyproject.toml +12 -20
  10. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/__about__.py +1 -1
  11. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/cleanup.py +4 -6
  12. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/command_runner.py +48 -2
  13. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/config_settings.py +0 -1
  14. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/dar_backup.py +92 -39
  15. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/dar_backup_systemd.py +1 -1
  16. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/demo.py +1 -2
  17. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/manager.py +793 -11
  18. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/util.py +9 -8
  19. dar_backup-1.1.0/venv/lib/python3.12/site-packages/dateparser-1.2.2.dist-info/licenses/LICENSE +12 -0
  20. dar_backup-1.1.0/venv/lib/python3.12/site-packages/librt-0.7.8.dist-info/licenses/LICENSE +263 -0
  21. dar_backup-1.1.0/venv/lib/python3.12/site-packages/mypy/typeshed/LICENSE +237 -0
  22. dar_backup-1.1.0/venv/lib/python3.12/site-packages/mypy-1.19.1.dist-info/licenses/LICENSE +264 -0
  23. dar_backup-1.1.0/venv/lib/python3.12/site-packages/pytest_json_report-1.5.0.dist-info/LICENSE +21 -0
  24. dar_backup-1.1.0/venv/lib/python3.12/site-packages/pytest_metadata-3.1.1.dist-info/licenses/LICENSE +3 -0
  25. dar_backup-1.1.0/venv/lib/python3.12/site-packages/pytest_mock-3.15.1.dist-info/licenses/LICENSE +21 -0
  26. dar_backup-1.1.0/venv/lib/python3.12/site-packages/pytokens-0.4.0.dist-info/licenses/LICENSE +21 -0
  27. dar_backup-1.1.0/venv/lib/python3.12/site-packages/ruff-0.14.14.dist-info/licenses/LICENSE +430 -0
  28. dar_backup-1.0.2/src/dar_backup/Changelog.md +0 -430
  29. dar_backup-1.0.2/src/dar_backup/README.md +0 -2105
  30. {dar_backup-1.0.2 → dar_backup-1.1.0}/LICENSE +0 -0
  31. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/Configfile.svg +0 -0
  32. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/Gemini3-assessment.md +0 -0
  33. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/clones-2025.png +0 -0
  34. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/dar-backup-overview-small.png +0 -0
  35. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/dar-backup-overview.png +0 -0
  36. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/dar-backup-overview.svg +0 -0
  37. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/dev.md +0 -0
  38. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/doc.md +0 -0
  39. {dar_backup-1.0.2 → dar_backup-1.1.0}/doc/portable-par2-layout.md +0 -0
  40. {dar_backup-1.0.2 → dar_backup-1.1.0}/packages/deb/README.md +0 -0
  41. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/.darrc +0 -0
  42. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/__init__.py +0 -0
  43. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/clean_log.py +0 -0
  44. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/dar-backup.conf +0 -0
  45. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/dar-backup.conf.j2 +0 -0
  46. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/demo_backup_def.j2 +0 -0
  47. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/exceptions.py +0 -0
  48. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/installer.py +0 -0
  49. {dar_backup-1.0.2 → dar_backup-1.1.0}/src/dar_backup/rich_progress.py +0 -0
  50. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/SecretStorage-3.3.3.dist-info/LICENSE +0 -0
  51. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/anyio-4.9.0.dist-info/LICENSE +0 -0
  52. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/black-25.1.0.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/black-26.1.0.dist-info}/licenses/LICENSE +0 -0
  53. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/blib2to3/LICENSE +0 -0
  54. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/build-1.2.2.post1.dist-info/LICENSE +0 -0
  55. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/certifi-2025.4.26.dist-info/licenses/LICENSE +0 -0
  56. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/cffi-1.17.1.dist-info/LICENSE +0 -0
  57. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/charset_normalizer-3.4.2.dist-info/licenses/LICENSE +0 -0
  58. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/contourpy-1.3.2.dist-info/LICENSE +0 -0
  59. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/cryptography-45.0.3.dist-info/licenses/LICENSE +0 -0
  60. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/cycler-0.12.1.dist-info/LICENSE +0 -0
  61. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/dar_backup-1.0.2.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/dar_backup-1.1.0.dist-info}/licenses/LICENSE +0 -0
  62. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/filelock-3.18.0.dist-info/licenses/LICENSE +0 -0
  63. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/fonttools-4.58.2.dist-info/licenses/LICENSE +0 -0
  64. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/hyperlink-21.0.0.dist-info/LICENSE +0 -0
  65. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/id-1.5.0.dist-info/LICENSE +0 -0
  66. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/iniconfig-2.1.0.dist-info/licenses/LICENSE +0 -0
  67. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/jaraco.classes-3.4.0.dist-info/LICENSE +0 -0
  68. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/jaraco.context-6.0.1.dist-info/LICENSE +0 -0
  69. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/jaraco.functools-4.1.0.dist-info/LICENSE +0 -0
  70. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/jeepney-0.9.0.dist-info/licenses/LICENSE +0 -0
  71. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/keyring-25.6.0.dist-info/LICENSE +0 -0
  72. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/kiwisolver-1.4.8.dist-info/LICENSE +0 -0
  73. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE +0 -0
  74. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/matplotlib-3.10.3.dist-info/LICENSE +0 -0
  75. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/mdurl-0.1.2.dist-info/LICENSE +0 -0
  76. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/more_itertools-10.7.0.dist-info/LICENSE +0 -0
  77. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/mypy_extensions-1.1.0.dist-info/licenses/LICENSE +0 -0
  78. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/nh3-0.2.21.dist-info/licenses/LICENSE +0 -0
  79. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/numpy/ma/LICENSE +0 -0
  80. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/packaging-25.0.dist-info/licenses/LICENSE +0 -0
  81. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pandas-2.3.0.dist-info/LICENSE +0 -0
  82. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pathspec-0.12.1.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pathspec-1.0.3.dist-info/licenses}/LICENSE +0 -0
  83. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pexpect-4.9.0.dist-info/LICENSE +0 -0
  84. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pillow-11.2.1.dist-info/licenses/LICENSE +0 -0
  85. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/certifi/LICENSE +0 -0
  86. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/distro/LICENSE +0 -0
  87. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/packaging/LICENSE +0 -0
  88. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/LICENSE +0 -0
  89. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/LICENSE +0 -0
  90. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/pygments/LICENSE +0 -0
  91. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/LICENSE +0 -0
  92. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/requests/LICENSE +0 -0
  93. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/LICENSE +0 -0
  94. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/rich/LICENSE +0 -0
  95. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/tomli/LICENSE +0 -0
  96. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/tomli_w/LICENSE +0 -0
  97. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pip/_vendor/truststore/LICENSE +0 -0
  98. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
  99. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
  100. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
  101. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
  102. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
  103. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
  104. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
  105. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
  106. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
  107. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
  108. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
  109. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
  110. {dar_backup-1.0.2/venv/lib/python3.12/site-packages/pip-25.3.dist-info → dar_backup-1.1.0/venv/lib/python3.12/site-packages/pip-26.0.1.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
  111. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/platformdirs-4.3.8.dist-info/licenses/LICENSE +0 -0
  112. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE +0 -0
  113. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/psutil-7.0.0.dist-info/LICENSE +0 -0
  114. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/ptyprocess-0.7.0.dist-info/LICENSE +0 -0
  115. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pycparser-2.22.dist-info/LICENSE +0 -0
  116. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE +0 -0
  117. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pyparsing-3.2.3.dist-info/LICENSE +0 -0
  118. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pyproject_hooks-1.2.0.dist-info/LICENSE +0 -0
  119. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pytest-8.4.0.dist-info/licenses/LICENSE +0 -0
  120. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pytest_cov-6.1.1.dist-info/licenses/LICENSE +0 -0
  121. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/pytest_timeout-2.4.0.dist-info/licenses/LICENSE +0 -0
  122. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE +0 -0
  123. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/readme_renderer-44.0.dist-info/LICENSE +0 -0
  124. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/requests-2.32.3.dist-info/LICENSE +0 -0
  125. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/requests_toolbelt-1.0.0.dist-info/LICENSE +0 -0
  126. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/rfc3986-2.0.0.dist-info/LICENSE +0 -0
  127. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/rich-14.0.0.dist-info/LICENSE +0 -0
  128. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/shellingham-1.5.4.dist-info/LICENSE +0 -0
  129. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/six-1.17.0.dist-info/LICENSE +0 -0
  130. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/sniffio-1.3.1.dist-info/LICENSE +0 -0
  131. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/tomli_w-1.2.0.dist-info/LICENSE +0 -0
  132. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/tomlkit-0.13.2.dist-info/LICENSE +0 -0
  133. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/trove_classifiers-2025.5.9.12.dist-info/licenses/LICENSE +0 -0
  134. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/twine-6.1.0.dist-info/LICENSE +0 -0
  135. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/typing_extensions-4.14.0.dist-info/licenses/LICENSE +0 -0
  136. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/tzdata-2025.2.dist-info/licenses/LICENSE +0 -0
  137. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/virtualenv-20.31.2.dist-info/licenses/LICENSE +0 -0
  138. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/wheel/vendored/packaging/LICENSE +0 -0
  139. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/zipp-3.22.0.dist-info/licenses/LICENSE +0 -0
  140. {dar_backup-1.0.2 → dar_backup-1.1.0}/venv/lib/python3.12/site-packages/zstandard-0.23.0.dist-info/LICENSE +0 -0
@@ -19,5 +19,6 @@ v2/.coverage
19
19
  v2/.coverage*
20
20
  v2/dar-backup.tar
21
21
  v2/coverage.xml
22
+ v2/doc/test-report/coverage.xml
22
23
  v2/packages/*
23
24
  v2/.coverage.*.*.*.*
@@ -1,6 +1,33 @@
1
1
  <!-- markdownlint-disable MD024 -->
2
2
  # dar-backup Changelog
3
3
 
4
+ ## v2-1.1.0 - not released
5
+
6
+ ### Added
7
+
8
+ - Point-in-Time Recovery (PITR): restore paths as of a specific time via `manager --restore-path --when --target`, with safety checks, logging, and fallback restore when catalogs can’t resolve a dated restore.
9
+ - PITR integration torture tests for rename/mtime traps and catalog rebuild after DB loss.
10
+ - PITR dry-run chain report (`manager --pitr-report`) to preview archive selection and detect missing archives.
11
+ - PITR fallback now reports missing archive slices and can notify via Discord when configured.
12
+ - CommandRunner debug diagnostics now include process PID and elapsed time for each executed command.
13
+ - Manager command to relocate archive paths inside catalog databases (`--relocate-archive-path`, with dry-run).
14
+ - PITR restore logging now includes the exact archive chain (FULL/DIFF/INCR + timestamps + basenames).
15
+ - Tests covering PITR direct-restore flow and relocate-archive-path CLI safeguards.
16
+ - PITR preflight flag `--pitr-report-first` to run a chain report before restore and fail fast on missing archives.
17
+
18
+ ### Changed
19
+
20
+ - The release.sh script is more strict and runs the full pytest suite and commits test reports to doc/test-report
21
+ - Github `pytest` workflow uploads test reports in .json and .txt formats
22
+ - [Snyk] An XML parsing function now strips DTD to avoid a class of XXE vulnerabilities
23
+ - PITR fallback now restores via the latest FULL → DIFF → INCR chain and fails fast when required archives are missing.
24
+ - PITR restore now requires `--target` and blocks unsafe restore targets by default.
25
+ - Filtered `.darrc` temp files are created in a writable location and cleaned up reliably after runs.
26
+ - PITR fallback now validates chain completeness instead of skipping missing archives.
27
+ - `COMMAND_TIMEOUT_SECS = -1` disables timeouts for long-running operations.
28
+ - Catalog rebuild (`manager --add-dir`) now adds archives in FULL → DIFF → INCR order for the same date to avoid dar_manager prompts.
29
+ - PITR restores now always use direct `dar` chain application (skipping `dar_manager -w` restores) to avoid interactive prompts on non-monotonic mtimes.
30
+
4
31
  ## v2-1.0.2 - 2026-01-25
5
32
 
6
33
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dar-backup
3
- Version: 1.0.2
3
+ Version: 1.1.0
4
4
  Summary: A script to do full, differential and incremental backups using dar. Some files are restored from the backups during verification, after which par2 redundancy files are created. The script also has a cleanup feature to remove old backups and par2 files.
5
5
  Project-URL: GPG Public Key, https://keys.openpgp.org/search?q=dar-backup@pm.me
6
6
  Project-URL: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
@@ -690,23 +690,26 @@ Classifier: Programming Language :: Python :: 3.11
690
690
  Classifier: Topic :: System :: Archiving :: Backup
691
691
  Requires-Python: >=3.11
692
692
  Requires-Dist: argcomplete>=3.6.2
693
+ Requires-Dist: dateparser>=1.2.0
693
694
  Requires-Dist: inputimeout>=1.0.4
694
695
  Requires-Dist: jinja2>=3.1.6
695
696
  Requires-Dist: rich>=13.0.0
696
697
  Provides-Extra: dev
697
698
  Requires-Dist: anyio>=4.4.0; extra == 'dev'
698
- Requires-Dist: black>=25.1.0; extra == 'dev'
699
699
  Requires-Dist: coverage>=7.8.2; extra == 'dev'
700
700
  Requires-Dist: h11>=0.16.0; extra == 'dev'
701
701
  Requires-Dist: httpcore>=0.17.3; extra == 'dev'
702
702
  Requires-Dist: matplotlib>=3.10.3; extra == 'dev'
703
+ Requires-Dist: mypy; extra == 'dev'
703
704
  Requires-Dist: pandas>=2.3.0; extra == 'dev'
704
705
  Requires-Dist: psutil>=7.0.0; extra == 'dev'
705
- Requires-Dist: pytest; extra == 'dev'
706
706
  Requires-Dist: pytest-cov>=6.1.1; extra == 'dev'
707
+ Requires-Dist: pytest-json-report; extra == 'dev'
708
+ Requires-Dist: pytest-mock; extra == 'dev'
707
709
  Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
708
710
  Requires-Dist: pytest>=8.4.0; extra == 'dev'
709
711
  Requires-Dist: requests>=2.32.2; extra == 'dev'
712
+ Requires-Dist: ruff; extra == 'dev'
710
713
  Requires-Dist: wheel>=0.45.1; extra == 'dev'
711
714
  Requires-Dist: zipp>=3.19.1; extra == 'dev'
712
715
  Provides-Extra: packaging
@@ -742,6 +745,18 @@ You can see the [v2 Changelog](v2/Changelog.md) for details on features and prog
742
745
 
743
746
  Version **1.0.0** was reached on October 9, 2025.
744
747
 
748
+ **High-level flow**
749
+
750
+ [![dar-backup overview](v2/doc/dar-backup-overview-small.png)](#dar-backup-principles)
751
+
752
+ **Quick links**
753
+
754
+ - [Quick Guide](#quick-guide)
755
+ - [Redundancy to fix bitrot](#par2)
756
+ - [Point In Time Recovery](#point-in-time-recovery-pitr)
757
+ - [550+ unit tests & integration tests](#test-coverage)
758
+ - par2 bitrot repair proof, full/diff/incr with restore, PITR verifications, ...
759
+
745
760
  ## Table of Contents
746
761
 
747
762
  - [`dar-backup`](#dar-backup)
@@ -785,6 +800,7 @@ Version **1.0.0** was reached on October 9, 2025.
785
800
  - [select a directory](#select-a-directory)
786
801
  - [select files with "Z50" in the file name and exclude .xmp files](#select-files-with-z50-in-the-file-name-and-exclude-xmp-files)
787
802
  - [Restoring](#restoring)
803
+ - [Point-in-Time Recovery (PITR)](#point-in-time-recovery-pitr)
788
804
  - [default location for restores](#default-location-for-restores)
789
805
  - [--restore-dir option](#--restore-dir-option)
790
806
  - [a single file](#a-single-file)
@@ -826,7 +842,10 @@ Version **1.0.0** was reached on October 9, 2025.
826
842
  - [Projects these scripts benefit from](#projects-these-scripts-benefit-from)
827
843
  - [Reference](#reference)
828
844
  - [CLI Tools Overview](#cli-tools-overview)
829
- - [test coverage](#test-coverage)
845
+ - [Test coverage](#test-coverage)
846
+ - [Test selection with markers](#test-selection-with-markers)
847
+ - [Common runs](#common-runs)
848
+ - [Run all tests](#run-all-tests)
830
849
  - [Dar-backup options](#dar-backup-options)
831
850
  - [Dar-backup exit codes](#dar-backup-exit-codes)
832
851
  - [Dar-backup env vars](#dar-backup-env-vars)
@@ -844,6 +863,7 @@ Version **1.0.0** was reached on October 9, 2025.
844
863
  - [1.0.2](#102)
845
864
  - [Trace Logging](#trace-logging)
846
865
  - [Command output Capture](#command-output-capture)
866
+ - [1.1.0](#110)
847
867
 
848
868
  ## My use case
849
869
 
@@ -1490,6 +1510,7 @@ NO_FILES_VERIFICATION = 5
1490
1510
  # timeout in seconds for backup, test, restore and par2 operations
1491
1511
  # The author has such `dar` tasks running for 10-15 hours on the yearly backups, so a value of 24 hours is used.
1492
1512
  # If a timeout is not specified when using the util.run_command(), a default timeout of 30 secs is used.
1513
+ # Use -1 to disable timeouts.
1493
1514
  COMMAND_TIMEOUT_SECS = 86400
1494
1515
 
1495
1516
  [DIRECTORIES]
@@ -1930,6 +1951,97 @@ gives something like
1930
1951
 
1931
1952
  ## Restoring
1932
1953
 
1954
+ ### Point-in-Time Recovery (PITR)
1955
+
1956
+ Use the `manager` CLI to restore files as they existed at a specific time:
1957
+
1958
+ ```bash
1959
+ . <the virtual env>/bin/activate
1960
+ manager --config-file <dar-backup.conf> \
1961
+ --backup-def <definition> \
1962
+ --restore-path tmp/path/to/file.txt \
1963
+ --when "2026-01-29 15:00:39" \
1964
+ --target /tmp/restore_pitr \
1965
+ --log-stdout --verbose
1966
+ deactivate
1967
+ ```
1968
+
1969
+ Restore a directory (same idea, but the path is a directory):
1970
+
1971
+ ```bash
1972
+ . <the virtual env>/bin/activate
1973
+ manager --config-file <dar-backup.conf> \
1974
+ --backup-def <definition> \
1975
+ --restore-path tmp/path/to/directory/ \
1976
+ --when "2026-01-29 15:00:39" \
1977
+ --target /tmp/restore_pitr \
1978
+ --log-stdout --verbose
1979
+ deactivate
1980
+ ```
1981
+
1982
+ Dry-run the archive chain selection before restoring:
1983
+
1984
+ ```bash
1985
+ . <the virtual env>/bin/activate
1986
+ manager --config-file <dar-backup.conf> \
1987
+ --backup-def <definition> \
1988
+ --restore-path tmp/path/to/directory \
1989
+ --when "2026-01-29 15:00:39" \
1990
+ --pitr-report \
1991
+ --log-stdout --verbose
1992
+ deactivate
1993
+ ```
1994
+
1995
+ **Notes**:
1996
+ - `--restore-path` must be a relative path as stored in the catalog (no leading slash).
1997
+ - If a restore path is a **directory** and its name has no file extension, add a trailing `/` to make the intent explicit (e.g., `photos/2026/01/`). This avoids ambiguity with file paths that also lack extensions.
1998
+ - Example (directory name has no extension):
1999
+ - `manager --backup-def <definition> --restore-path "Automatic Upload/Per - iPhone/2026/01/" --when "now" --target /tmp/restore_pitr`
2000
+ - `--target` is required to avoid accidental restores into the current working directory.
2001
+ - Protected targets are blocked (e.g., `/etc`, `/usr`, `/bin`, `/var`, `/root`, `/boot`, `/lib`, `/proc`, `/sys`, `/dev`).
2002
+ - `--pitr-report` does a **dry-run** chain selection; if it reports missing archives, a restore will fail until the catalog is rebuilt or missing archives are restored.
2003
+ - `--pitr-report-first` runs the same chain report before a restore and aborts if any archive is missing (useful as a safety preflight).
2004
+ - `--when` accepts natural-language date expressions via `dateparser`. Examples:
2005
+ - `"now"`
2006
+ - `"2 weeks ago"`
2007
+ - `"2025-10-05 14:30"`
2008
+ - `yesterday 23:00`
2009
+ - PITR restores use the catalog to select the correct archive chain (FULL → DIFF → INCR) and then restore **directly with `dar`** in that order.
2010
+ - This avoids interactive `dar_manager` prompts (e.g., non‑monotonic mtimes often seen on pCloud/FUSE).
2011
+ - Directories can get a **new mtime** when files inside them are added/removed; the chain restore ensures the correct tree is rebuilt even if mtimes look “too new”.
2012
+ - Missing archives:
2013
+ - PITR uses the latest FULL, the latest DIFF after that FULL, and the latest INCR after that DIFF.
2014
+ - If any archive slice in that chain is missing on disk, PITR restore **fails** and logs which archive slices are missing.
2015
+ - A short Discord notice is sent (if configured) so missing archives are visible immediately.
2016
+ - Relocating archive paths in the catalog:
2017
+ - The catalog stores **absolute archive paths**. If archives move (or a mountpoint changes), the catalog will still point to the old path.
2018
+ - This can happen when manager DBs are moved to another disk and the archives are re-added from a different mountpoint.
2019
+ - Use the built-in relocate command to rewrite a path prefix in-place:
2020
+ - Dry run:
2021
+ - `manager --relocate-archive-path /old/path /new/path --relocate-archive-path-dry-run --backup-def <definition>`
2022
+ - Apply:
2023
+ - `manager --relocate-archive-path /old/path /new/path --backup-def <definition>`
2024
+ - Example (move `/home/pj/mnt/dar` to `/mnt/dar`):
2025
+ - `manager --relocate-archive-path /home/pj/mnt/dar /mnt/dar --backup-def pCloudDrive`
2026
+ - Alternative quick fix: create a symlink from the old path to the new path.
2027
+ - Rebuilding a catalog after archive loss:
2028
+ - If PITR fails due to missing archives, the catalog may no longer match what is actually on disk.
2029
+ - You can rebuild the catalog from the remaining archives and then retry PITR (with the understanding that older restore points may no longer be possible).
2030
+ - Example:
2031
+ - `manager --create-db --config-file <dar-backup.conf>`
2032
+ - `manager --add-dir <backup_dir> --backup-def <definition> --config-file <dar-backup.conf>`
2033
+ - Or add individual archives:
2034
+ - `manager --add-specific-archive <path/to/archive> --config-file <dar-backup.conf>`
2035
+
2036
+ Example of the issue:
2037
+ 1) FULL backup at 10:00 with `/data/photos/`
2038
+ 2) You add files at 11:00 (directory mtime updates)
2039
+ 3) DIFF backup at 11:05
2040
+ 4) You request PITR restore of `/data/photos/` at 10:30
2041
+
2042
+ `dar_manager -w` may say “directory did not exist before that time” because the directory mtime is now 11:00+.
2043
+ The fallback still restores the correct tree as of 10:30 by applying the archive chain.
2044
+
1933
2045
  ### default location for restores
1934
2046
 
1935
2047
  dar-backup will use the TEST_RESTORE_DIR location as the Root for restores, if the --restore-dir option has not been supplied.
@@ -2479,40 +2591,135 @@ One backup definition per file
2479
2591
  | [installer](#installer-options) | Set up directories and optionally create catalog databases according to a config file |
2480
2592
  | [demo](#demo-options) | Set up required directories and config files for a demo|
2481
2593
 
2482
- ### test coverage
2594
+ ### Test coverage
2595
+
2596
+ #### Test selection with markers
2597
+
2598
+ The test suite is annotated with these markers:
2599
+
2600
+ - `unit` (fast, pure logic)
2601
+ - `component` (subprocess boundary with mocks/lightweight commands)
2602
+ - `integration` (end-to-end workflows; external tools)
2603
+ - `slow` (long-running/heavier integration)
2604
+ - `live_discord` (sends real webhook messages; opt-in only)
2605
+
2606
+ #### Common runs
2483
2607
 
2484
- Running
2608
+ ```bash
2609
+ # Fast local loop (unit + component)
2610
+ pytest -m "unit or component"
2611
+
2612
+ # Integration (exclude slow + live webhook)
2613
+ pytest -m "integration and not slow and not live_discord"
2614
+
2615
+ # Slow-only
2616
+ pytest -m slow
2617
+
2618
+ # Full suite (default pytest.ini already excludes live_discord)
2619
+ pytest -m "not live_discord"
2620
+
2621
+ # Live webhook (requires DAR_BACKUP_DISCORD_WEBHOOK_URL)
2622
+ pytest -m live_discord
2623
+ ```
2624
+
2625
+ #### Run all tests
2485
2626
 
2486
2627
  ```bash
2487
- pytest --cov=dar_backup tests/
2628
+ pytest
2488
2629
  ```
2489
2630
 
2490
- Results for version 1.0.0 in this report:
2631
+ Results for version 1.1.0 (pre-release, Feb 1, 2026) in this report:
2491
2632
 
2492
2633
  ```text
2493
- ====================================== tests coverage ======================================
2494
- _____________________ coverage: platform linux, python 3.12.3-final-0 ______________________
2634
+ ===================================== test session starts =====================================
2635
+ platform linux -- Python 3.12.3, pytest-8.4.0, pluggy-1.6.0
2636
+ rootdir: /home/pj/git/dar-backup/v2
2637
+ configfile: pytest.ini
2638
+ testpaths: tests
2639
+ plugins: anyio-4.9.0, timeout-2.4.0, cov-6.1.1, mock-3.15.1
2640
+ timeout: 1800.0s
2641
+ timeout method: signal
2642
+ timeout func_only: False
2643
+ collected 559 items / 1 deselected / 558 selected
2644
+
2645
+ tests/test_add_old_archive_confirmation.py .... [ 0%]
2646
+ tests/test_alternate_reference_archive.py ... [ 1%]
2647
+ tests/test_autocompletion_install.py ... [ 1%]
2648
+ tests/test_binary_info.py ...... [ 2%]
2649
+ tests/test_bitrot.py .. [ 3%]
2650
+ tests/test_clean_log.py .................... [ 6%]
2651
+ tests/test_cleanup.py ............................... [ 12%]
2652
+ tests/test_command_runner.py ......................................... [ 19%]
2653
+ tests/test_config_comments.py . [ 19%]
2654
+ tests/test_config_settings.py .............. [ 22%]
2655
+ tests/test_create_backup_command.py ... [ 22%]
2656
+ tests/test_create_full_diff_incr_backup.py .......... [ 24%]
2657
+ tests/test_dar_backup.py ....................................................... [ 34%]
2658
+ tests/test_dar_backup_additional_coverage.py ....................... [ 38%]
2659
+ tests/test_dar_backup_startup.py .. [ 39%]
2660
+ tests/test_darrc.py .. [ 39%]
2661
+ tests/test_demo.py ............. [ 41%]
2662
+ tests/test_discord_webhook.py .. [ 42%]
2663
+ tests/test_filter_darrc_file.py . [ 42%]
2664
+ tests/test_generic_backup_command_execution.py . [ 42%]
2665
+ tests/test_get_config_file.py ....... [ 43%]
2666
+ tests/test_gpt_file_compression.py . [ 43%]
2667
+ tests/test_gpt_tests.py ....... [ 45%]
2668
+ tests/test_installer.py .................. [ 48%]
2669
+ tests/test_links.py . [ 48%]
2670
+ tests/test_list_definitions.py . [ 48%]
2671
+ tests/test_listing.py ... [ 49%]
2672
+ tests/test_logging_trace.py .. [ 49%]
2673
+ tests/test_manager.py ................................................................. [ 61%]
2674
+ [ 61%]
2675
+ tests/test_manager_coverage.py .................................. [ 67%]
2676
+ tests/test_par2.py . [ 67%]
2677
+ tests/test_par2_manifest.py . [ 67%]
2678
+ tests/test_par2_multi_definitions.py . [ 67%]
2679
+ tests/test_par2_overrides.py . [ 68%]
2680
+ tests/test_pitr.py .............................................. [ 76%]
2681
+ tests/test_pitr_integration.py ..... [ 77%]
2682
+ tests/test_postreq.py . [ 77%]
2683
+ tests/test_preflight.py ... [ 77%]
2684
+ tests/test_prereq.py . [ 78%]
2685
+ tests/test_readme_changelog.py .......... [ 79%]
2686
+ tests/test_restore.py .... [ 80%]
2687
+ tests/test_run_command.py ......s [ 81%]
2688
+ tests/test_sanity_checks.py ................. [ 84%]
2689
+ tests/test_space_definition.py . [ 85%]
2690
+ tests/test_startup_cleanup.py ....... [ 86%]
2691
+ tests/test_status_indicators.py ....... [ 87%]
2692
+ tests/test_stress.py . [ 87%]
2693
+ tests/test_systemd_unit_generation.py .......... [ 89%]
2694
+ tests/test_trace_logging.py .. [ 89%]
2695
+ tests/test_util.py .......................................... [ 97%]
2696
+ tests/test_util_completers.py .......... [ 99%]
2697
+ tests/test_verbose.py ... [ 99%]
2698
+ tests/test_verify_cleanup.py . [100%]
2699
+
2700
+ ======================================= tests coverage ========================================
2701
+ _______________________ coverage: platform linux, python 3.12.3-final-0 _______________________
2495
2702
 
2496
2703
  Name Stmts Miss Branch BrPart Cover
2497
2704
  ------------------------------------------------------------------------
2498
- src/dar_backup/__about__.py 2 0 0 0 100%
2705
+ src/dar_backup/__about__.py 3 0 0 0 100%
2499
2706
  src/dar_backup/__init__.py 0 0 0 0 100%
2500
- src/dar_backup/clean_log.py 76 15 40 7 81%
2501
- src/dar_backup/cleanup.py 203 16 66 7 91%
2502
- src/dar_backup/command_runner.py 129 16 26 5 86%
2503
- src/dar_backup/config_settings.py 73 3 18 1 96%
2504
- src/dar_backup/dar_backup.py 551 28 180 21 93%
2505
- src/dar_backup/dar_backup_systemd.py 56 7 10 2 86%
2506
- src/dar_backup/demo.py 92 20 26 6 75%
2707
+ src/dar_backup/clean_log.py 114 10 46 2 91%
2708
+ src/dar_backup/cleanup.py 294 42 100 9 87%
2709
+ src/dar_backup/command_runner.py 231 20 82 10 90%
2710
+ src/dar_backup/config_settings.py 162 9 62 10 92%
2711
+ src/dar_backup/dar_backup.py 1027 55 420 49 92%
2712
+ src/dar_backup/dar_backup_systemd.py 56 1 10 1 97%
2713
+ src/dar_backup/demo.py 100 1 34 2 98%
2507
2714
  src/dar_backup/exceptions.py 2 0 0 0 100%
2508
- src/dar_backup/installer.py 107 14 46 9 82%
2509
- src/dar_backup/manager.py 427 42 152 15 90%
2510
- src/dar_backup/rich_progress.py 70 7 30 4 89%
2511
- src/dar_backup/util.py 339 41 88 21 85%
2715
+ src/dar_backup/installer.py 120 4 54 4 95%
2716
+ src/dar_backup/manager.py 1105 91 454 38 91%
2717
+ src/dar_backup/rich_progress.py 70 2 30 3 95%
2718
+ src/dar_backup/util.py 521 43 142 24 90%
2512
2719
  ------------------------------------------------------------------------
2513
- TOTAL 2127 209 682 98 89%
2514
- Coverage XML written to file coverage.xml
2515
- ======================== 257 passed, 1 skipped in 223.21s (0:03:43) ========================
2720
+ TOTAL 3805 278 1434 152 91%
2721
+ Coverage XML written to file /tmp/coverage.xml
2722
+ ================== 557 passed, 1 skipped, 1 deselected in 409.66s (0:06:49) ===================
2516
2723
  ```
2517
2724
 
2518
2725
  ### Dar-backup options
@@ -2584,6 +2791,13 @@ Available options:
2584
2791
  -l, --list-catalogs List catalogs in databases for all backup definitions.
2585
2792
  --list-archive-contents <archive> List the contents of an archive’s catalog by archive name.
2586
2793
  --find-file <file> Search catalogs for a specific file.
2794
+ --restore-path <path> [<path> ...] Restore specific path(s) (Point-in-Time Recovery).
2795
+ --when <timestamp> Date/time for restoration (used with --restore-path).
2796
+ --target <path> Target directory for restoration (default: current dir).
2797
+ --pitr-report Report PITR archive chain for --restore-path/--when without restoring.
2798
+ --pitr-report-first Run PITR chain report before restore and abort if missing archives.
2799
+ --relocate-archive-path <old> <new> Rewrite archive path prefix in the catalog DB (requires --backup-def).
2800
+ --relocate-archive-path-dry-run Show archive path changes without applying them (use with --relocate-archive-path).
2587
2801
  --verbose Enable verbose output.
2588
2802
  --log-level <level> Set log level (`debug` or `trace`, default is `info`).
2589
2803
 
@@ -2821,3 +3035,7 @@ Example:
2821
3035
  [MISC]
2822
3036
  COMMAND_CAPTURE_MAX_BYTES = 102400
2823
3037
  ```
3038
+
3039
+ #### 1.1.0
3040
+
3041
+ COMMAND_TIMEOUT_SECS=-1 now disables timeout for commands executed.