diff --git a/NEWS b/NEWS index 2d28fecb..aa6ca5f1 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ 2.1.6.dev0 + * #1300: Fix the "source_directories_must_exist" option to support source directories relative to a + "working_directory". * Add the NEWS changelog file to release tarball (#1298). * Enable reply by email on projects.torsion.org, so replies to notification emails get posted as comments on tickets. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 7d23e9d7..8e3e9820 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -180,7 +180,9 @@ def make_base_create_command( # noqa: PLR0912 open pattern file handle). ''' if config.get('source_directories_must_exist', True): - borgmatic.borg.pattern.check_all_root_patterns_exist(patterns) + borgmatic.borg.pattern.check_all_root_patterns_exist( + patterns, borgmatic.config.paths.get_working_directory(config) + ) patterns_file = borgmatic.borg.pattern.write_patterns_file( patterns, diff --git a/borgmatic/borg/pattern.py b/borgmatic/borg/pattern.py index aee6a780..261a1d63 100644 --- a/borgmatic/borg/pattern.py +++ b/borgmatic/borg/pattern.py @@ -88,16 +88,16 @@ def write_patterns_file(patterns, borgmatic_runtime_directory, patterns_file=Non return patterns_file -def check_all_root_patterns_exist(patterns): +def check_all_root_patterns_exist(patterns, working_directory): ''' - Given a sequence of Pattern instances, check that all root pattern paths exist. If any don't, - raise an exception. + Given a sequence of Pattern instances and the current working directory, check that all root + pattern paths exist. If any don't, raise an exception. ''' missing_paths = [ pattern.path for pattern in patterns if pattern.type == Pattern_type.ROOT - if not os.path.exists(pattern.path) + if not os.path.exists(os.path.join(working_directory or '', pattern.path)) ] if missing_paths: diff --git a/tests/unit/borg/test_pattern.py b/tests/unit/borg/test_pattern.py index 7ed5158c..fdd2939b 100644 --- a/tests/unit/borg/test_pattern.py +++ b/tests/unit/borg/test_pattern.py @@ -34,19 +34,36 @@ def test_write_patterns_file_appends_to_existing(): def test_check_all_root_patterns_exist_with_existent_pattern_path_does_not_raise(): - flexmock(module.os.path).should_receive('exists').and_return(True) + flexmock(module.os.path).should_receive('exists').with_args('foo').and_return(True) - module.check_all_root_patterns_exist([Pattern('foo')]) + module.check_all_root_patterns_exist([Pattern('foo')], working_directory=None) + + +def test_check_all_root_patterns_exist_with_existent_relative_pattern_path_and_working_directory_does_not_raise(): + flexmock(module.os.path).should_receive('exists').with_args('foo').never() + flexmock(module.os.path).should_receive('exists').with_args('/working/foo').and_return(True) + + module.check_all_root_patterns_exist([Pattern('foo')], working_directory='/working') def test_check_all_root_patterns_exist_with_non_root_pattern_skips_existence_check(): flexmock(module.os.path).should_receive('exists').never() - module.check_all_root_patterns_exist([Pattern('foo', Pattern_type.INCLUDE)]) + module.check_all_root_patterns_exist( + [Pattern('foo', Pattern_type.INCLUDE)], working_directory=None + ) def test_check_all_root_patterns_exist_with_non_existent_pattern_path_raises(): flexmock(module.os.path).should_receive('exists').and_return(False) with pytest.raises(ValueError): - module.check_all_root_patterns_exist([Pattern('foo')]) + module.check_all_root_patterns_exist([Pattern('foo')], working_directory=None) + + +def test_check_all_root_patterns_exist_with_non_existent_relative_pattern_path_and_working_directory_raises(): + flexmock(module.os.path).should_receive('exists').with_args('foo').never() + flexmock(module.os.path).should_receive('exists').with_args('/working/foo').and_return(False) + + with pytest.raises(ValueError): + module.check_all_root_patterns_exist([Pattern('foo')], working_directory='/working')