Fix for an error when a blank line occurs in the configured patterns or excludes (#970).

This commit is contained in:
Dan Helfman
2025-01-18 09:25:29 -08:00
parent e789de0851
commit e66df22a6e
4 changed files with 20 additions and 5 deletions
+3
View File
@@ -1,3 +1,6 @@
1.9.7
* #970: Fix for an error when a blank line occurs in the configured patterns or excludes.
1.9.6
* #959: Fix an error in the Btrfs hook when a subvolume mounted at "/" is configured in borgmatic's
source directories.
+4 -1
View File
@@ -23,7 +23,7 @@ def parse_pattern(pattern_line):
try:
(pattern_type, remainder) = pattern_line.split(' ', maxsplit=1)
except ValueError:
raise ValueError('Invalid pattern:', pattern_line)
raise ValueError(f'Invalid pattern: {pattern_line}')
try:
(pattern_style, path) = remainder.split(':', maxsplit=1)
@@ -57,6 +57,7 @@ def collect_patterns(config):
parse_pattern(pattern_line.strip())
for pattern_line in config.get('patterns', ())
if not pattern_line.lstrip().startswith('#')
if pattern_line.strip()
)
+ tuple(
borgmatic.borg.pattern.Pattern(
@@ -71,6 +72,7 @@ def collect_patterns(config):
for filename in config.get('patterns_from', ())
for pattern_line in open(filename).readlines()
if not pattern_line.lstrip().startswith('#')
if pattern_line.strip()
)
+ tuple(
borgmatic.borg.pattern.Pattern(
@@ -81,6 +83,7 @@ def collect_patterns(config):
for filename in config.get('excludes_from', ())
for exclude_line in open(filename).readlines()
if not exclude_line.lstrip().startswith('#')
if exclude_line.strip()
)
)
except (FileNotFoundError, OSError) as error:
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "borgmatic"
version = "1.9.6"
version = "1.9.7.dev0"
authors = [
{ name="Dan Helfman", email="witten@torsion.org" },
]
+12 -3
View File
@@ -36,9 +36,11 @@ def test_collect_patterns_converts_source_directories():
def test_collect_patterns_parses_config_patterns():
flexmock(module).should_receive('parse_pattern').with_args('R /foo').and_return(Pattern('/foo'))
flexmock(module).should_receive('parse_pattern').with_args('# comment').never()
flexmock(module).should_receive('parse_pattern').with_args('').never()
flexmock(module).should_receive('parse_pattern').with_args(' ').never()
flexmock(module).should_receive('parse_pattern').with_args('R /bar').and_return(Pattern('/bar'))
assert module.collect_patterns({'patterns': ['R /foo', '# comment', 'R /bar']}) == (
assert module.collect_patterns({'patterns': ['R /foo', '# comment', '', ' ', 'R /bar']}) == (
Pattern('/foo'),
Pattern('/bar'),
)
@@ -55,10 +57,12 @@ def test_collect_patterns_reads_config_patterns_from_file():
builtins = flexmock(sys.modules['builtins'])
builtins.should_receive('open').with_args('file1.txt').and_return(io.StringIO('R /foo'))
builtins.should_receive('open').with_args('file2.txt').and_return(
io.StringIO('R /bar\n# comment\nR /baz')
io.StringIO('R /bar\n# comment\n\n \nR /baz')
)
flexmock(module).should_receive('parse_pattern').with_args('R /foo').and_return(Pattern('/foo'))
flexmock(module).should_receive('parse_pattern').with_args('# comment').never()
flexmock(module).should_receive('parse_pattern').with_args('').never()
flexmock(module).should_receive('parse_pattern').with_args(' ').never()
flexmock(module).should_receive('parse_pattern').with_args('R /bar').and_return(Pattern('/bar'))
flexmock(module).should_receive('parse_pattern').with_args('R /baz').and_return(Pattern('/baz'))
@@ -82,8 +86,13 @@ def test_collect_patterns_reads_config_excludes_from_file():
builtins = flexmock(sys.modules['builtins'])
builtins.should_receive('open').with_args('file1.txt').and_return(io.StringIO('/foo'))
builtins.should_receive('open').with_args('file2.txt').and_return(
io.StringIO('/bar\n# comment\n/baz')
io.StringIO('/bar\n# comment\n\n \n/baz')
)
flexmock(module).should_receive('parse_pattern').with_args('/bar').and_return(Pattern('/bar'))
flexmock(module).should_receive('parse_pattern').with_args('# comment').never()
flexmock(module).should_receive('parse_pattern').with_args('').never()
flexmock(module).should_receive('parse_pattern').with_args(' ').never()
flexmock(module).should_receive('parse_pattern').with_args('/baz').and_return(Pattern('/baz'))
assert module.collect_patterns({'excludes_from': ['file1.txt', 'file2.txt']}) == (
Pattern('/foo', Pattern_type.EXCLUDE, Pattern_style.FNMATCH),