Просмотр исходного кода

Fix the "source_directories_must_exist" option to work with relative "source_directories" paths when a "working_directory" is set (#905).

Dan Helfman 9 месяцев назад
Родитель
Сommit
e0298685a1
3 измененных файлов с 39 добавлено и 10 удалено
  1. 2 0
      NEWS
  2. 22 10
      borgmatic/borg/create.py
  3. 15 0
      tests/unit/borg/test_create.py

+ 2 - 0
NEWS

@@ -6,6 +6,8 @@
  * #900: Fix for a potential traceback (TypeError) during the handling of another error.
  * #900: Fix for a potential traceback (TypeError) during the handling of another error.
  * #904: Clarify the configuration reference about the "spot" check options:
  * #904: Clarify the configuration reference about the "spot" check options:
    https://torsion.org/borgmatic/docs/reference/configuration/
    https://torsion.org/borgmatic/docs/reference/configuration/
+ * #905: Fix the "source_directories_must_exist" option to work with relative "source_directories"
+   paths when a "working_directory" is set.
  * Fix a regression in which the "color" option had no effect.
  * Fix a regression in which the "color" option had no effect.
  * Add a recent contributors section to the documentation, because credit where credit's due! See:
  * Add a recent contributors section to the documentation, because credit where credit's due! See:
    https://torsion.org/borgmatic/#recent-contributors
    https://torsion.org/borgmatic/#recent-contributors

+ 22 - 10
borgmatic/borg/create.py

@@ -306,15 +306,25 @@ def collect_special_file_paths(
     )
     )
 
 
 
 
-def check_all_source_directories_exist(source_directories):
+def check_all_source_directories_exist(source_directories, working_directory=None):
     '''
     '''
-    Given a sequence of source directories, check that they all exist. If any do not, raise an
-    exception.
+    Given a sequence of source directories and an optional working directory to serve as a prefix
+    for each (if it's a relative directory), check that the source directories all exist. If any do
+    not, raise an exception.
     '''
     '''
     missing_directories = [
     missing_directories = [
         source_directory
         source_directory
         for source_directory in source_directories
         for source_directory in source_directories
-        if not all([os.path.exists(directory) for directory in expand_directory(source_directory)])
+        if not all(
+            [
+                os.path.exists(directory)
+                for directory in expand_directory(
+                    os.path.join(working_directory, source_directory)
+                    if working_directory
+                    else source_directory
+                )
+            ]
+        )
     ]
     ]
     if missing_directories:
     if missing_directories:
         raise ValueError(f"Source directories do not exist: {', '.join(missing_directories)}")
         raise ValueError(f"Source directories do not exist: {', '.join(missing_directories)}")
@@ -342,8 +352,15 @@ def make_base_create_command(
     (base Borg create command flags, Borg create command positional arguments, open pattern file
     (base Borg create command flags, Borg create command positional arguments, open pattern file
     handle, open exclude file handle).
     handle, open exclude file handle).
     '''
     '''
+    try:
+        working_directory = os.path.expanduser(config.get('working_directory'))
+    except TypeError:
+        working_directory = None
+
     if config.get('source_directories_must_exist', False):
     if config.get('source_directories_must_exist', False):
-        check_all_source_directories_exist(config.get('source_directories'))
+        check_all_source_directories_exist(
+            config.get('source_directories'), working_directory=working_directory
+        )
 
 
     sources = deduplicate_directories(
     sources = deduplicate_directories(
         map_directories_to_devices(
         map_directories_to_devices(
@@ -445,11 +462,6 @@ def make_base_create_command(
         logger.warning(
         logger.warning(
             f'{repository_path}: Ignoring configured "read_special" value of false, as true is needed for database hooks.'
             f'{repository_path}: Ignoring configured "read_special" value of false, as true is needed for database hooks.'
         )
         )
-        try:
-            working_directory = os.path.expanduser(config.get('working_directory'))
-        except TypeError:
-            working_directory = None
-
         borg_environment = environment.make_environment(config)
         borg_environment = environment.make_environment(config)
 
 
         logger.debug(f'{repository_path}: Collecting special file paths')
         logger.debug(f'{repository_path}: Collecting special file paths')

+ 15 - 0
tests/unit/borg/test_create.py

@@ -1891,3 +1891,18 @@ def test_check_all_source_directories_exist_with_non_existent_directory_raises()
 
 
     with pytest.raises(ValueError):
     with pytest.raises(ValueError):
         module.check_all_source_directories_exist(['foo'])
         module.check_all_source_directories_exist(['foo'])
+
+
+def test_check_all_source_directories_exist_with_working_directory_applies_to_relative_source_directories():
+    flexmock(module).should_receive('expand_directory').with_args('/tmp/foo*').and_return(
+        ('/tmp/foo', '/tmp/food')
+    )
+    flexmock(module).should_receive('expand_directory').with_args('/root/bar').and_return(
+        ('/root/bar',)
+    )
+    flexmock(module.os.path).should_receive('exists').and_return(False)
+    flexmock(module.os.path).should_receive('exists').with_args('/tmp/foo').and_return(True)
+    flexmock(module.os.path).should_receive('exists').with_args('/tmp/food').and_return(True)
+    flexmock(module.os.path).should_receive('exists').with_args('/root/bar').and_return(True)
+
+    module.check_all_source_directories_exist(['foo*', '/root/bar'], working_directory='/tmp')