mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
Don't mess with inheritance for filling settings
This commit is contained in:
parent
69a9516477
commit
0553d57ec1
@ -19,8 +19,8 @@ def test_default():
|
|||||||
def test_settings_defaults():
|
def test_settings_defaults():
|
||||||
with patch('thefuck.conf.load_source', return_value=object()), \
|
with patch('thefuck.conf.load_source', return_value=object()), \
|
||||||
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
||||||
for key, val in conf.Settings.defaults.items():
|
for key, val in conf.DEFAULT_SETTINGS.items():
|
||||||
assert getattr(conf.Settings(Mock()), key) == val
|
assert getattr(conf.get_settings(Mock()), key) == val
|
||||||
|
|
||||||
|
|
||||||
def test_settings_from_file():
|
def test_settings_from_file():
|
||||||
@ -29,7 +29,7 @@ def test_settings_from_file():
|
|||||||
require_confirmation=True,
|
require_confirmation=True,
|
||||||
no_colors=True)), \
|
no_colors=True)), \
|
||||||
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
||||||
settings = conf.Settings(Mock())
|
settings = conf.get_settings(Mock())
|
||||||
assert settings.rules == ['test']
|
assert settings.rules == ['test']
|
||||||
assert settings.wait_command == 10
|
assert settings.wait_command == 10
|
||||||
assert settings.require_confirmation is True
|
assert settings.require_confirmation is True
|
||||||
@ -42,7 +42,7 @@ def test_settings_from_file_with_DEFAULT():
|
|||||||
require_confirmation=True,
|
require_confirmation=True,
|
||||||
no_colors=True)), \
|
no_colors=True)), \
|
||||||
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
patch('thefuck.conf.os.environ', new_callable=lambda: {}):
|
||||||
settings = conf.Settings(Mock())
|
settings = conf.get_settings(Mock())
|
||||||
assert settings.rules == conf.DEFAULT + ['test']
|
assert settings.rules == conf.DEFAULT + ['test']
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ def test_settings_from_env():
|
|||||||
'THEFUCK_WAIT_COMMAND': '55',
|
'THEFUCK_WAIT_COMMAND': '55',
|
||||||
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
|
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
|
||||||
'THEFUCK_NO_COLORS': 'false'}):
|
'THEFUCK_NO_COLORS': 'false'}):
|
||||||
settings = conf.Settings(Mock())
|
settings = conf.get_settings(Mock())
|
||||||
assert settings.rules == ['bash', 'lisp']
|
assert settings.rules == ['bash', 'lisp']
|
||||||
assert settings.wait_command == 55
|
assert settings.wait_command == 55
|
||||||
assert settings.require_confirmation is True
|
assert settings.require_confirmation is True
|
||||||
@ -64,12 +64,12 @@ def test_settings_from_env():
|
|||||||
def test_settings_from_env_with_DEFAULT():
|
def test_settings_from_env_with_DEFAULT():
|
||||||
with patch('thefuck.conf.load_source', return_value=Mock()), \
|
with patch('thefuck.conf.load_source', return_value=Mock()), \
|
||||||
patch('thefuck.conf.os.environ', new_callable=lambda: {'THEFUCK_RULES': 'DEFAULT:bash:lisp'}):
|
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']
|
assert settings.rules == conf.DEFAULT + ['bash', 'lisp']
|
||||||
|
|
||||||
|
|
||||||
def test_update_settings():
|
def test_update_settings():
|
||||||
settings = conf.BaseSettings({'key': 'val'})
|
settings = conf.Settings({'key': 'val'})
|
||||||
new_settings = settings.update(key='new-val')
|
new_settings = settings.update(key='new-val')
|
||||||
assert new_settings.key == 'new-val'
|
assert new_settings.key == 'new-val'
|
||||||
assert settings.key == 'val'
|
assert settings.key == 'val'
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
from mock import Mock
|
from mock import Mock
|
||||||
from thefuck.utils import sudo_support, wrap_settings
|
from thefuck.utils import sudo_support, wrap_settings
|
||||||
from thefuck.main import Command
|
from thefuck.main import Command
|
||||||
from thefuck.conf import BaseSettings
|
from thefuck.conf import Settings
|
||||||
|
|
||||||
|
|
||||||
def test_wrap_settings():
|
def test_wrap_settings():
|
||||||
fn = lambda _, settings: settings._conf
|
fn = lambda _, settings: settings._conf
|
||||||
assert wrap_settings({'key': 'val'})(fn)(None, BaseSettings({})) \
|
assert wrap_settings({'key': 'val'})(fn)(None, Settings({})) \
|
||||||
== {'key': 'val'}
|
== {'key': 'val'}
|
||||||
assert wrap_settings({'key': 'new-val'})(fn)(
|
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():
|
def test_sudo_support():
|
||||||
|
122
thefuck/conf.py
122
thefuck/conf.py
@ -40,7 +40,7 @@ class _DefaultRules(RulesList):
|
|||||||
DEFAULT = _DefaultRules([])
|
DEFAULT = _DefaultRules([])
|
||||||
|
|
||||||
|
|
||||||
class BaseSettings(object):
|
class Settings(object):
|
||||||
def __init__(self, conf):
|
def __init__(self, conf):
|
||||||
self._conf = conf
|
self._conf = conf
|
||||||
|
|
||||||
@ -51,70 +51,74 @@ class BaseSettings(object):
|
|||||||
"""Returns new settings with new values from `kwargs`."""
|
"""Returns new settings with new values from `kwargs`."""
|
||||||
conf = copy(self._conf)
|
conf = copy(self._conf)
|
||||||
conf.update(kwargs)
|
conf.update(kwargs)
|
||||||
return BaseSettings(conf)
|
return Settings(conf)
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
DEFAULT_SETTINGS = {'rules': DEFAULT,
|
||||||
"""Settings loaded from defaults/file/env."""
|
'wait_command': 3,
|
||||||
defaults = {'rules': DEFAULT,
|
'require_confirmation': False,
|
||||||
'wait_command': 3,
|
'no_colors': False}
|
||||||
'require_confirmation': False,
|
|
||||||
'no_colors': False}
|
|
||||||
|
|
||||||
env_to_attr = {'THEFUCK_RULES': 'rules',
|
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
||||||
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
||||||
'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation',
|
'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation',
|
||||||
'THEFUCK_NO_COLORS': 'no_colors'}
|
'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):
|
def _settings_from_file(user_dir):
|
||||||
conf = copy(self.defaults)
|
"""Loads settings from file."""
|
||||||
try:
|
settings = load_source('settings',
|
||||||
conf.update(self._load_from_file(user_dir))
|
text_type(user_dir.joinpath('settings.py')))
|
||||||
except:
|
return {key: getattr(settings, key)
|
||||||
logs.exception("Can't load settings from file",
|
for key in DEFAULT_SETTINGS.keys()
|
||||||
sys.exc_info(),
|
if hasattr(settings, key)}
|
||||||
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 _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):
|
def _rules_from_env(val):
|
||||||
"""Loads settings from env."""
|
"""Transforms rules list from env-string to python."""
|
||||||
return {attr: self._val_from_env(env, attr)
|
val = val.split(':')
|
||||||
for env, attr in self.env_to_attr.items()
|
if 'DEFAULT' in val:
|
||||||
if env in os.environ}
|
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):
|
def _val_from_env(env, attr):
|
||||||
"""Transforms rules list from env-string to python."""
|
"""Transforms env-strings to python."""
|
||||||
val = val.split(':')
|
val = os.environ[env]
|
||||||
if 'DEFAULT' in val:
|
if attr == 'rules':
|
||||||
val = DEFAULT + [rule for rule in val if rule != 'DEFAULT']
|
val = _rules_from_env(val)
|
||||||
return 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)
|
||||||
|
@ -121,7 +121,7 @@ def is_second_run(command):
|
|||||||
def main():
|
def main():
|
||||||
colorama.init()
|
colorama.init()
|
||||||
user_dir = setup_user_dir()
|
user_dir = setup_user_dir()
|
||||||
settings = conf.Settings(user_dir)
|
settings = conf.get_settings(user_dir)
|
||||||
|
|
||||||
command = get_command(settings, sys.argv)
|
command = get_command(settings, sys.argv)
|
||||||
if command:
|
if command:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user