ソースを参照

Remove legacy configuration parsing code, no longer needed with upgrade-borgmatic-config gone (#529).

Dan Helfman 2 年 前
コミット
b9a11e860d

+ 0 - 2
borgmatic/commands/borgmatic.py

@@ -46,8 +46,6 @@ from borgmatic.verbosity import verbosity_to_log_level
 
 logger = logging.getLogger(__name__)
 
-LEGACY_CONFIG_PATH = '/etc/borgmatic/config'
-
 
 def run_configuration(config_filename, config, arguments):
     '''

+ 0 - 146
borgmatic/config/legacy.py

@@ -1,146 +0,0 @@
-from collections import OrderedDict, namedtuple
-from configparser import RawConfigParser
-
-Section_format = namedtuple('Section_format', ('name', 'options'))
-Config_option = namedtuple('Config_option', ('name', 'value_type', 'required'))
-
-
-def option(name, value_type=str, required=True):
-    '''
-    Given a config file option name, an expected type for its value, and whether it's required,
-    return a Config_option capturing that information.
-    '''
-    return Config_option(name, value_type, required)
-
-
-CONFIG_FORMAT = (
-    Section_format(
-        'location',
-        (
-            option('source_directories'),
-            option('one_file_system', value_type=bool, required=False),
-            option('remote_path', required=False),
-            option('repository'),
-        ),
-    ),
-    Section_format(
-        'storage',
-        (
-            option('encryption_passphrase', required=False),
-            option('compression', required=False),
-            option('umask', required=False),
-        ),
-    ),
-    Section_format(
-        'retention',
-        (
-            option('keep_within', required=False),
-            option('keep_hourly', int, required=False),
-            option('keep_daily', int, required=False),
-            option('keep_weekly', int, required=False),
-            option('keep_monthly', int, required=False),
-            option('keep_yearly', int, required=False),
-            option('prefix', required=False),
-        ),
-    ),
-    Section_format(
-        'consistency', (option('checks', required=False), option('check_last', required=False))
-    ),
-)
-
-
-def validate_configuration_format(parser, config_format):
-    '''
-    Given an open RawConfigParser and an expected config file format, validate that the parsed
-    configuration file has the expected sections, that any required options are present in those
-    sections, and that there aren't any unexpected options.
-
-    A section is required if any of its contained options are required.
-
-    Raise ValueError if anything is awry.
-    '''
-    section_names = set(parser.sections())
-    required_section_names = tuple(
-        section.name
-        for section in config_format
-        if any(option.required for option in section.options)
-    )
-
-    unknown_section_names = section_names - set(
-        section_format.name for section_format in config_format
-    )
-    if unknown_section_names:
-        raise ValueError(f"Unknown config sections found: {', '.join(unknown_section_names)}")
-
-    missing_section_names = set(required_section_names) - section_names
-    if missing_section_names:
-        raise ValueError(f"Missing config sections: {', '.join(missing_section_names)}")
-
-    for section_format in config_format:
-        if section_format.name not in section_names:
-            continue
-
-        option_names = parser.options(section_format.name)
-        expected_options = section_format.options
-
-        unexpected_option_names = set(option_names) - set(
-            option.name for option in expected_options
-        )
-
-        if unexpected_option_names:
-            raise ValueError(
-                f"Unexpected options found in config section {section_format.name}: {', '.join(sorted(unexpected_option_names))}",
-            )
-
-        missing_option_names = tuple(
-            option.name
-            for option in expected_options
-            if option.required
-            if option.name not in option_names
-        )
-
-        if missing_option_names:
-            raise ValueError(
-                f"Required options missing from config section {section_format.name}: {', '.join(missing_option_names)}",
-            )
-
-
-def parse_section_options(parser, section_format):
-    '''
-    Given an open RawConfigParser and an expected section format, return the option values from that
-    section as a dict mapping from option name to value. Omit those options that are not present in
-    the parsed options.
-
-    Raise ValueError if any option values cannot be coerced to the expected Python data type.
-    '''
-    type_getter = {str: parser.get, int: parser.getint, bool: parser.getboolean}
-
-    return OrderedDict(
-        (option.name, type_getter[option.value_type](section_format.name, option.name))
-        for option in section_format.options
-        if parser.has_option(section_format.name, option.name)
-    )
-
-
-def parse_configuration(config_filename, config_format):
-    '''
-    Given a config filename and an expected config file format, return the parsed configuration
-    as a namedtuple with one attribute for each parsed section.
-
-    Raise IOError if the file cannot be read, or ValueError if the format is not as expected.
-    '''
-    parser = RawConfigParser()
-    if not parser.read(config_filename):
-        raise ValueError(f'Configuration file cannot be opened: {config_filename}')
-
-    validate_configuration_format(parser, config_format)
-
-    # Describes a parsed configuration, where each attribute is the name of a configuration file
-    # section and each value is a dict of that section's parsed options.
-    Parsed_config = namedtuple(
-        'Parsed_config', (section_format.name for section_format in config_format)
-    )
-
-    return Parsed_config(
-        *(parse_section_options(parser, section_format) for section_format in config_format)
-    )

+ 0 - 18
tests/integration/config/test_legacy.py

@@ -1,18 +0,0 @@
-import string
-from collections import OrderedDict
-from io import StringIO
-
-from borgmatic.config import legacy as module
-
-
-def test_parse_section_options_with_punctuation_should_return_section_options():
-    parser = module.RawConfigParser()
-    parser.read_file(StringIO(f'[section]\nfoo: {string.punctuation}\n'))
-
-    section_format = module.Section_format(
-        'section', (module.Config_option('foo', str, required=True),)
-    )
-
-    config = module.parse_section_options(parser, section_format)
-
-    assert config == OrderedDict((('foo', string.punctuation),))

+ 0 - 210
tests/unit/config/test_legacy.py

@@ -1,210 +0,0 @@
-from collections import OrderedDict
-
-import pytest
-from flexmock import flexmock
-
-from borgmatic.config import legacy as module
-
-
-def test_option_should_create_config_option():
-    option = module.option('name', bool, required=False)
-
-    assert option == module.Config_option('name', bool, False)
-
-
-def test_option_should_create_config_option_with_defaults():
-    option = module.option('name')
-
-    assert option == module.Config_option('name', str, True)
-
-
-def test_validate_configuration_format_with_valid_config_should_not_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section', 'other'))
-    parser.should_receive('options').with_args('section').and_return(('stuff',))
-    parser.should_receive('options').with_args('other').and_return(('such',))
-    config_format = (
-        module.Section_format(
-            'section', options=(module.Config_option('stuff', str, required=True),)
-        ),
-        module.Section_format('other', options=(module.Config_option('such', str, required=True),)),
-    )
-
-    module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_missing_required_section_should_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section',))
-    config_format = (
-        module.Section_format(
-            'section', options=(module.Config_option('stuff', str, required=True),)
-        ),
-        # At least one option in this section is required, so the section is required.
-        module.Section_format(
-            'missing',
-            options=(
-                module.Config_option('such', str, required=False),
-                module.Config_option('things', str, required=True),
-            ),
-        ),
-    )
-
-    with pytest.raises(ValueError):
-        module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_missing_optional_section_should_not_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section',))
-    parser.should_receive('options').with_args('section').and_return(('stuff',))
-    config_format = (
-        module.Section_format(
-            'section', options=(module.Config_option('stuff', str, required=True),)
-        ),
-        # No options in the section are required, so the section is optional.
-        module.Section_format(
-            'missing',
-            options=(
-                module.Config_option('such', str, required=False),
-                module.Config_option('things', str, required=False),
-            ),
-        ),
-    )
-
-    module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_unknown_section_should_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section', 'extra'))
-    config_format = (module.Section_format('section', options=()),)
-
-    with pytest.raises(ValueError):
-        module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_missing_required_option_should_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section',))
-    parser.should_receive('options').with_args('section').and_return(('option',))
-    config_format = (
-        module.Section_format(
-            'section',
-            options=(
-                module.Config_option('option', str, required=True),
-                module.Config_option('missing', str, required=True),
-            ),
-        ),
-    )
-
-    with pytest.raises(ValueError):
-        module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_missing_optional_option_should_not_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section',))
-    parser.should_receive('options').with_args('section').and_return(('option',))
-    config_format = (
-        module.Section_format(
-            'section',
-            options=(
-                module.Config_option('option', str, required=True),
-                module.Config_option('missing', str, required=False),
-            ),
-        ),
-    )
-
-    module.validate_configuration_format(parser, config_format)
-
-
-def test_validate_configuration_format_with_extra_option_should_raise():
-    parser = flexmock()
-    parser.should_receive('sections').and_return(('section',))
-    parser.should_receive('options').with_args('section').and_return(('option', 'extra'))
-    config_format = (
-        module.Section_format(
-            'section', options=(module.Config_option('option', str, required=True),)
-        ),
-    )
-
-    with pytest.raises(ValueError):
-        module.validate_configuration_format(parser, config_format)
-
-
-def test_parse_section_options_should_return_section_options():
-    parser = flexmock()
-    parser.should_receive('get').with_args('section', 'foo').and_return('value')
-    parser.should_receive('getint').with_args('section', 'bar').and_return(1)
-    parser.should_receive('getboolean').never()
-    parser.should_receive('has_option').with_args('section', 'foo').and_return(True)
-    parser.should_receive('has_option').with_args('section', 'bar').and_return(True)
-
-    section_format = module.Section_format(
-        'section',
-        (
-            module.Config_option('foo', str, required=True),
-            module.Config_option('bar', int, required=True),
-        ),
-    )
-
-    config = module.parse_section_options(parser, section_format)
-
-    assert config == OrderedDict((('foo', 'value'), ('bar', 1)))
-
-
-def test_parse_section_options_for_missing_section_should_return_empty_dict():
-    parser = flexmock()
-    parser.should_receive('get').never()
-    parser.should_receive('getint').never()
-    parser.should_receive('getboolean').never()
-    parser.should_receive('has_option').with_args('section', 'foo').and_return(False)
-    parser.should_receive('has_option').with_args('section', 'bar').and_return(False)
-
-    section_format = module.Section_format(
-        'section',
-        (
-            module.Config_option('foo', str, required=False),
-            module.Config_option('bar', int, required=False),
-        ),
-    )
-
-    config = module.parse_section_options(parser, section_format)
-
-    assert config == OrderedDict()
-
-
-def insert_mock_parser():
-    parser = flexmock()
-    parser.should_receive('read').and_return([flexmock()])
-    module.RawConfigParser = lambda: parser
-
-    return parser
-
-
-def test_parse_configuration_should_return_section_configs():
-    parser = insert_mock_parser()
-    config_format = (flexmock(name='items'), flexmock(name='things'))
-    mock_module = flexmock(module)
-    mock_module.should_receive('validate_configuration_format').with_args(
-        parser, config_format
-    ).once()
-    mock_section_configs = (flexmock(), flexmock())
-
-    for section_format, section_config in zip(config_format, mock_section_configs):
-        mock_module.should_receive('parse_section_options').with_args(
-            parser, section_format
-        ).and_return(section_config).once()
-
-    parsed_config = module.parse_configuration('filename', config_format)
-
-    assert parsed_config == type(parsed_config)(*mock_section_configs)
-
-
-def test_parse_configuration_with_file_open_error_should_raise():
-    parser = insert_mock_parser()
-    parser.should_receive('read').and_return([])
-
-    with pytest.raises(ValueError):
-        module.parse_configuration('filename', config_format=flexmock())