diff --git a/tests/test_conf.py b/tests/test_conf.py index c74d3430..41c693e6 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -19,8 +19,8 @@ def test_default(): def test_settings_defaults(): with patch('thefuck.conf.load_source', return_value=object()), \ patch('thefuck.conf.os.environ', new_callable=lambda: {}): - for key, val in conf.Settings.defaults.items(): - assert getattr(conf.Settings(Mock()), key) == val + for key, val in conf.DEFAULT_SETTINGS.items(): + assert getattr(conf.get_settings(Mock()), key) == val def test_settings_from_file(): @@ -29,7 +29,7 @@ def test_settings_from_file(): require_confirmation=True, no_colors=True)), \ patch('thefuck.conf.os.environ', new_callable=lambda: {}): - settings = conf.Settings(Mock()) + settings = conf.get_settings(Mock()) assert settings.rules == ['test'] assert settings.wait_command == 10 assert settings.require_confirmation is True @@ -42,7 +42,7 @@ def test_settings_from_file_with_DEFAULT(): require_confirmation=True, no_colors=True)), \ patch('thefuck.conf.os.environ', new_callable=lambda: {}): - settings = conf.Settings(Mock()) + settings = conf.get_settings(Mock()) assert settings.rules == conf.DEFAULT + ['test'] @@ -54,7 +54,7 @@ def test_settings_from_env(): 'THEFUCK_WAIT_COMMAND': '55', 'THEFUCK_REQUIRE_CONFIRMATION': 'true', 'THEFUCK_NO_COLORS': 'false'}): - settings = conf.Settings(Mock()) + settings = conf.get_settings(Mock()) assert settings.rules == ['bash', 'lisp'] assert settings.wait_command == 55 assert settings.require_confirmation is True @@ -64,12 +64,12 @@ def test_settings_from_env(): def test_settings_from_env_with_DEFAULT(): with patch('thefuck.conf.load_source', return_value=Mock()), \ patch('thefuck.conf.os.environ', new_callable=lambda: {'THEFUCK_RULES': 'DEFAULT:bash:lisp'}): - settings = conf.Settings(Mock()) + settings = conf.get_settings(Mock()) assert settings.rules == conf.DEFAULT + ['bash', 'lisp'] def test_update_settings(): - settings = conf.BaseSettings({'key': 'val'}) + settings = conf.Settings({'key': 'val'}) new_settings = settings.update(key='new-val') assert new_settings.key == 'new-val' assert settings.key == 'val' diff --git a/tests/test_utils.py b/tests/test_utils.py index e1ec93d5..43439048 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,15 +1,15 @@ from mock import Mock from thefuck.utils import sudo_support, wrap_settings from thefuck.main import Command -from thefuck.conf import BaseSettings +from thefuck.conf import Settings def test_wrap_settings(): fn = lambda _, settings: settings._conf - assert wrap_settings({'key': 'val'})(fn)(None, BaseSettings({})) \ + assert wrap_settings({'key': 'val'})(fn)(None, Settings({})) \ == {'key': 'val'} assert wrap_settings({'key': 'new-val'})(fn)( - None, BaseSettings({'key': 'val'})) == {'key': 'new-val'} + None, Settings({'key': 'val'})) == {'key': 'new-val'} def test_sudo_support(): diff --git a/thefuck/conf.py b/thefuck/conf.py index 4593905a..2f3da7d1 100644 --- a/thefuck/conf.py +++ b/thefuck/conf.py @@ -40,7 +40,7 @@ class _DefaultRules(RulesList): DEFAULT = _DefaultRules([]) -class BaseSettings(object): +class Settings(object): def __init__(self, conf): self._conf = conf @@ -51,70 +51,74 @@ class BaseSettings(object): """Returns new settings with new values from `kwargs`.""" conf = copy(self._conf) conf.update(kwargs) - return BaseSettings(conf) + return Settings(conf) -class Settings(BaseSettings): - """Settings loaded from defaults/file/env.""" - defaults = {'rules': DEFAULT, - 'wait_command': 3, - 'require_confirmation': False, - 'no_colors': False} +DEFAULT_SETTINGS = {'rules': DEFAULT, + 'wait_command': 3, + 'require_confirmation': False, + 'no_colors': False} - env_to_attr = {'THEFUCK_RULES': 'rules', - 'THEFUCK_WAIT_COMMAND': 'wait_command', - 'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation', - 'THEFUCK_NO_COLORS': 'no_colors'} +ENV_TO_ATTR = {'THEFUCK_RULES': 'rules', + 'THEFUCK_WAIT_COMMAND': 'wait_command', + 'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation', + 'THEFUCK_NO_COLORS': 'no_colors'} - def __init__(self, user_dir): - super(Settings, self).__init__(self._load_conf(user_dir)) - def _load_conf(self, user_dir): - conf = copy(self.defaults) - try: - conf.update(self._load_from_file(user_dir)) - except: - logs.exception("Can't load settings from file", - sys.exc_info(), - BaseSettings(conf)) - try: - conf.update(self._load_from_env()) - except: - logs.exception("Can't load settings from env", - sys.exc_info(), - BaseSettings(conf)) - if not isinstance(conf['rules'], RulesList): - conf['rules'] = RulesList(conf['rules']) - return conf +def _settings_from_file(user_dir): + """Loads settings from file.""" + settings = load_source('settings', + text_type(user_dir.joinpath('settings.py'))) + return {key: getattr(settings, key) + for key in DEFAULT_SETTINGS.keys() + if hasattr(settings, key)} - def _load_from_file(self, user_dir): - """Loads settings from file.""" - settings = load_source('settings', - text_type(user_dir.joinpath('settings.py'))) - return {key: getattr(settings, key) - for key in self.defaults.keys() - if hasattr(settings, key)} - def _load_from_env(self): - """Loads settings from env.""" - return {attr: self._val_from_env(env, attr) - for env, attr in self.env_to_attr.items() - if env in os.environ} +def _rules_from_env(val): + """Transforms rules list from env-string to python.""" + val = val.split(':') + if 'DEFAULT' in val: + val = DEFAULT + [rule for rule in val if rule != 'DEFAULT'] + return val - def _val_from_env(self, env, attr): - """Transforms env-strings to python.""" - val = os.environ[env] - if attr == 'rules': - val = self._rules_from_env(val) - elif attr == 'wait_command': - val = int(val) - elif attr in ('require_confirmation', 'no_colors'): - val = val.lower() == 'true' - return val - def _rules_from_env(self, val): - """Transforms rules list from env-string to python.""" - val = val.split(':') - if 'DEFAULT' in val: - val = DEFAULT + [rule for rule in val if rule != 'DEFAULT'] - return val +def _val_from_env(env, attr): + """Transforms env-strings to python.""" + val = os.environ[env] + if attr == 'rules': + val = _rules_from_env(val) + elif attr == 'wait_command': + val = int(val) + elif attr in ('require_confirmation', 'no_colors'): + val = val.lower() == 'true' + return val + + +def _settings_from_env(): + """Loads settings from env.""" + return {attr: _val_from_env(env, attr) + for env, attr in ENV_TO_ATTR.items() + if env in os.environ} + + +def get_settings(user_dir): + """Returns settings filled with values from `settings.py` and env.""" + conf = copy(DEFAULT_SETTINGS) + try: + conf.update(_settings_from_file(user_dir)) + except Exception: + logs.exception("Can't load settings from file", + sys.exc_info(), + Settings(conf)) + + try: + conf.update(_settings_from_env()) + except Exception: + logs.exception("Can't load settings from env", + sys.exc_info(), + Settings(conf)) + + if not isinstance(conf['rules'], RulesList): + conf['rules'] = RulesList(conf['rules']) + + return Settings(conf) diff --git a/thefuck/main.py b/thefuck/main.py index 2db62103..341c9621 100644 --- a/thefuck/main.py +++ b/thefuck/main.py @@ -121,7 +121,7 @@ def is_second_run(command): def main(): colorama.init() user_dir = setup_user_dir() - settings = conf.Settings(user_dir) + settings = conf.get_settings(user_dir) command = get_command(settings, sys.argv) if command: