Add a --relaxed-config options.

This commit is contained in:
Florian Bruhin 2015-03-23 07:58:28 +01:00
parent e7f5433da3
commit 0e8b42a9d8
4 changed files with 37 additions and 6 deletions

View File

@ -65,6 +65,9 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
*--harfbuzz* '{old,new,system,auto}':: *--harfbuzz* '{old,new,system,auto}'::
HarfBuzz engine version to use. Default: auto. HarfBuzz engine version to use. Default: auto.
*--relaxed-config*::
Silently remove unknown config options.
*--nowindow*:: *--nowindow*::
Don't show the main window. Don't show the main window.

View File

@ -117,8 +117,9 @@ def _init_main_config():
"""Initialize the main config.""" """Initialize the main config."""
try: try:
app = objreg.get('app') app = objreg.get('app')
args = objreg.get('args')
config_obj = ConfigManager(standarddir.config(), 'qutebrowser.conf', config_obj = ConfigManager(standarddir.config(), 'qutebrowser.conf',
app) args.relaxed_config, app)
except (configexc.Error, configparser.Error, UnicodeDecodeError) as e: except (configexc.Error, configparser.Error, UnicodeDecodeError) as e:
log.init.exception(e) log.init.exception(e)
errstr = "Error while reading config:" errstr = "Error while reading config:"
@ -270,7 +271,7 @@ class ConfigManager(QObject):
changed = pyqtSignal(str, str) changed = pyqtSignal(str, str)
style_changed = pyqtSignal(str, str) style_changed = pyqtSignal(str, str)
def __init__(self, configdir, fname, parent=None): def __init__(self, configdir, fname, relaxed=False, parent=None):
super().__init__(parent) super().__init__(parent)
self._initialized = False self._initialized = False
self.sections = configdata.DATA self.sections = configdata.DATA
@ -285,7 +286,7 @@ class ConfigManager(QObject):
else: else:
self._configdir = configdir self._configdir = configdir
parser = ini.ReadConfigParser(configdir, fname) parser = ini.ReadConfigParser(configdir, fname)
self._from_cp(parser) self._from_cp(parser, relaxed)
self._initialized = True self._initialized = True
self._validate_all() self._validate_all()
@ -394,16 +395,18 @@ class ConfigManager(QObject):
else: else:
return None return None
def _from_cp(self, cp): def _from_cp(self, cp, relaxed=False):
"""Read the config from a configparser instance. """Read the config from a configparser instance.
Args: Args:
cp: The configparser instance to read the values from. cp: The configparser instance to read the values from.
relaxed: Whether to ignore inexistent sections/optons
""" """
for sectname in cp: for sectname in cp:
if sectname in self.RENAMED_SECTIONS: if sectname in self.RENAMED_SECTIONS:
sectname = self.RENAMED_SECTIONS[sectname] sectname = self.RENAMED_SECTIONS[sectname]
if sectname is not 'DEFAULT' and sectname not in self.sections: if sectname is not 'DEFAULT' and sectname not in self.sections:
if not relaxed:
raise configexc.NoSectionError(sectname) raise configexc.NoSectionError(sectname)
for sectname in self.sections: for sectname in self.sections:
real_sectname = self._get_real_sectname(cp, sectname) real_sectname = self._get_real_sectname(cp, sectname)
@ -416,7 +419,13 @@ class ConfigManager(QObject):
continue continue
elif (sectname, k) in self.RENAMED_OPTIONS: elif (sectname, k) in self.RENAMED_OPTIONS:
k = self.RENAMED_OPTIONS[sectname, k] k = self.RENAMED_OPTIONS[sectname, k]
try:
self.set('conf', sectname, k, v, validate=False) self.set('conf', sectname, k, v, validate=False)
except configexc.NoOptionError:
if relaxed:
pass
else:
raise
def _validate_all(self): def _validate_all(self):
"""Validate all values set in self._from_cp.""" """Validate all values set in self._from_cp."""

View File

@ -73,6 +73,8 @@ def get_argparser():
debug.add_argument('--harfbuzz', choices=['old', 'new', 'system', 'auto'], debug.add_argument('--harfbuzz', choices=['old', 'new', 'system', 'auto'],
default='auto', help="HarfBuzz engine version to use. " default='auto', help="HarfBuzz engine version to use. "
"Default: auto.") "Default: auto.")
debug.add_argument('--relaxed-config', action='store_true',
help="Silently remove unknown config options.")
debug.add_argument('--nowindow', action='store_true', help="Don't show " debug.add_argument('--nowindow', action='store_true', help="Don't show "
"the main window.") "the main window.")
debug.add_argument('--debug-exit', help="Turn on debugging of late exit.", debug.add_argument('--debug-exit', help="Turn on debugging of late exit.",

View File

@ -27,6 +27,7 @@ import configparser
import tempfile import tempfile
import types import types
import shutil import shutil
import argparse
from unittest import mock from unittest import mock
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
@ -143,6 +144,20 @@ class ConfigParserTests(unittest.TestCase):
with self.assertRaises(configexc.NoOptionError): with self.assertRaises(configexc.NoOptionError):
self.cfg._from_cp(self.cp) self.cfg._from_cp(self.cp)
def test_invalid_section_relaxed(self):
"""Test an invalid section with relaxed=True."""
self.cp.read_dict({'foo': {'bar': 'baz'}})
self.cfg._from_cp(self.cp, relaxed=True)
with self.assertRaises(configexc.NoSectionError):
self.cfg.get('foo', 'bar')
def test_invalid_option_relaxed(self):
"""Test an invalid option with relaxed=True."""
self.cp.read_dict({'general': {'bar': 'baz'}})
self.cfg._from_cp(self.cp, relaxed=True)
with self.assertRaises(configexc.NoOptionError):
self.cfg.get('general', 'bar')
class DefaultConfigTests(unittest.TestCase): class DefaultConfigTests(unittest.TestCase):
@ -173,6 +188,8 @@ class ConfigInitTests(unittest.TestCase):
} }
objreg.register('app', QObject()) objreg.register('app', QObject())
objreg.register('save-manager', mock.MagicMock()) objreg.register('save-manager', mock.MagicMock())
args = argparse.Namespace(relaxed_config=False)
objreg.register('args', args)
def tearDown(self): def tearDown(self):
shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir)