瀏覽代碼

Optionally error if a source directory does not exist.

feat: add optional check for existence of source directories
Dan Helfman 2 年之前
父節點
當前提交
31d04d9ee3
共有 3 個文件被更改,包括 46 次插入1 次删除
  1. 16 0
      borgmatic/borg/create.py
  2. 6 0
      borgmatic/config/schema.yaml
  3. 24 1
      tests/unit/borg/test_create.py

+ 16 - 0
borgmatic/borg/create.py

@@ -306,6 +306,20 @@ def collect_special_file_paths(
     )
 
 
+def check_all_source_directories_exist(source_directories):
+    '''
+    Given a sequence of source directories, check that they all exist. If any do not, raise an
+    exception.
+    '''
+    missing_directories = [
+        source_directory
+        for source_directory in source_directories
+        if not os.path.exists(source_directory)
+    ]
+    if missing_directories:
+        raise ValueError(f"Source directories do not exist: {', '.join(missing_directories)}")
+
+
 def create_archive(
     dry_run,
     repository,
@@ -331,6 +345,8 @@ def create_archive(
     borgmatic_source_directories = expand_directories(
         collect_borgmatic_source_directories(location_config.get('borgmatic_source_directory'))
     )
+    if location_config.get('source_directories_must_exist', False):
+        check_all_source_directories_exist(location_config.get('source_directories'))
     sources = deduplicate_directories(
         map_directories_to_devices(
             expand_directories(

+ 6 - 0
borgmatic/config/schema.yaml

@@ -202,6 +202,12 @@ properties:
                     path prevents "borgmatic restore" from finding any database
                     dumps created before the change. Defaults to ~/.borgmatic
                 example: /tmp/borgmatic
+            source_directories_must_exist:
+                type: boolean
+                description: |
+                    If true, then source directories must exist, otherwise an
+                    error is raised. Defaults to false.
+                example: true
     storage:
         type: object
         description: |

+ 24 - 1
tests/unit/borg/test_create.py

@@ -207,7 +207,6 @@ def test_make_exclude_flags_includes_exclude_patterns_filename_when_given():
 
 
 def test_make_exclude_flags_includes_exclude_from_filenames_when_in_config():
-
     exclude_flags = module.make_exclude_flags(
         location_config={'exclude_from': ['excludes', 'other']}
     )
@@ -2530,3 +2529,27 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes_and_read
         local_borg_version='1.2.3',
         stream_processes=processes,
     )
+
+
+def test_create_archive_with_non_existent_directory_and_source_directories_must_exist_raises_error():
+    """
+    If a source directory doesn't exist and source_directories_must_exist is True, raise an error.
+    """
+    flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
+    flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
+    flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([])
+    flexmock(module.os.path).should_receive('exists').and_return(False)
+
+    with pytest.raises(ValueError):
+        module.create_archive(
+            dry_run=False,
+            repository='repo',
+            location_config={
+                'source_directories': ['foo', 'bar'],
+                'repositories': ['repo'],
+                'exclude_patterns': None,
+                'source_directories_must_exist': True,
+            },
+            storage_config={},
+            local_borg_version='1.2.3',
+        )