diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index f9a36ea31..62e4d7970 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -80,7 +80,7 @@ class YamlConfig(QObject): VERSION: The current version number of the config file. """ - VERSION = 1 + VERSION = 2 changed = pyqtSignal() def __init__(self, parent=None): @@ -173,9 +173,12 @@ class YamlConfig(QObject): config_version = self._pop_object(yaml_data, 'config_version', int) - settings = self._load_settings_object(yaml_data) - - self._dirty = False + if config_version == 1: + settings = self._load_legacy_settings_object(yaml_data) + self._mark_changed() + else: + settings = self._load_settings_object(yaml_data) + self._dirty = False settings = self._handle_migrations(settings) self._validate(settings) self._build_values(settings) @@ -184,9 +187,15 @@ class YamlConfig(QObject): """Load the settings from the settings: key.""" return self._pop_object(yaml_data, 'settings', dict) + def _load_legacy_settings_object(self, yaml_data): + data = self._pop_object(yaml_data, 'global', dict) + settings = {} + for name, value in data.items(): + settings[name] = {'global': value} + return settings + def _build_values(self, settings): """Build up self._values from the values in the given dict.""" - # FIXME:conf test this for name, yaml_values in settings.items(): values = configutils.Values(configdata.DATA[name]) if 'global' in yaml_values: @@ -200,9 +209,6 @@ class YamlConfig(QObject): def _handle_migrations(self, settings): """Migrate older configs to the newest format.""" - # FIXME:conf handle per-URL settings - # FIXME:conf migrate from older format with global: key - # Simple renamed/deleted options for name in list(settings): if name in configdata.MIGRATIONS.renamed: diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index d7d0b6173..29314d87e 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -45,19 +45,25 @@ class AutoConfigHelper: def __init__(self, config_tmpdir): self.fobj = config_tmpdir / 'autoconfig.yml' - def write(self, values): - data = {'config_version': 1, 'settings': values} + def write_toplevel(self, data): with self.fobj.open('w', encoding='utf-8') as f: utils.yaml_dump(data, f) + def write(self, values): + data = {'config_version': 2, 'settings': values} + self.write_toplevel(data) + def write_raw(self, text): self.fobj.write_text(text, encoding='utf-8', ensure=True) - def read(self): + def read_toplevel(self): with self.fobj.open('r', encoding='utf-8') as f: data = utils.yaml_load(f) - assert data['config_version'] == 1 - return data['settings'] + assert data['config_version'] == 2 + return data + + def read(self): + return self.read_toplevel()['settings'] def read_raw(self): return self.fobj.read_text('utf-8') @@ -284,9 +290,9 @@ class TestYaml: @pytest.mark.parametrize('line, text, exception', [ ('%', 'While parsing', 'while scanning a directive'), - ('settings: 42\nconfig_version: 1', + ('settings: 42\nconfig_version: 2', 'While loading data', "'settings' object is not a dict"), - ('foo: 42\nconfig_version: 1', 'While loading data', + ('foo: 42\nconfig_version: 2', 'While loading data', "Toplevel object does not contain 'settings' key"), ('settings: {}', 'While loading data', "Toplevel object does not contain 'config_version' key"), @@ -304,6 +310,26 @@ class TestYaml: assert str(error.exception).splitlines()[0] == exception assert error.traceback is None + def test_legacy_migration(self, yaml, autoconfig, qtbot): + autoconfig.write_toplevel({ + 'config_version': 1, + 'global': {'content.javascript.enabled': True}, + }) + with qtbot.wait_signal(yaml.changed): + yaml.load() + + yaml._save() + + data = autoconfig.read_toplevel() + assert data == { + 'config_version': 2, + 'settings': { + 'content.javascript.enabled': { + 'global': True, + } + } + } + def test_oserror(self, yaml, autoconfig): autoconfig.fobj.ensure() autoconfig.fobj.chmod(0) diff --git a/tests/unit/config/test_configinit.py b/tests/unit/config/test_configinit.py index 230b64a54..c139ff6b9 100644 --- a/tests/unit/config/test_configinit.py +++ b/tests/unit/config/test_configinit.py @@ -123,19 +123,19 @@ class TestEarlyInit: 'settings:', ' colors.foobar:', ' global: magenta', - 'config_version: 1', + 'config_version: 2', ], 'wrong-type': [ 'settings:', ' tabs.position:', ' global: true', - 'config_version: 1', + 'config_version: 2', ], False: [ 'settings:', ' colors.hints.fg:', ' global: magenta', - 'config_version: 1', + 'config_version: 2', ], } text = '\n'.join(yaml_lines[invalid_yaml]) @@ -240,7 +240,7 @@ class TestEarlyInit: args.temp_settings = settings elif method == 'auto': autoconfig_file = config_tmpdir / 'autoconfig.yml' - lines = (["config_version: 1", "settings:"] + + lines = (["config_version: 2", "settings:"] + [" {}:\n global:\n '{}'".format(k, v) for k, v in settings]) autoconfig_file.write_text('\n'.join(lines), 'utf-8', ensure=True)