1
0
mirror of https://github.com/nvbn/thefuck.git synced 2024-10-05 18:31:10 +01:00

Merge pull request #361 from nvbn/357-exclude-rules

#357 Add `exclude_rules` settings option
This commit is contained in:
Vladimir Iakovlev 2015-09-06 12:59:34 +03:00
commit f7ce0fda25
5 changed files with 47 additions and 16 deletions

View File

@ -271,6 +271,7 @@ requires_output = True
The Fuck has a few settings parameters which can be changed in `~/.thefuck/settings.py`:
* `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
* `exclude_rules` – list of disabled rules, by default `[]`;
* `require_confirmation` – requires confirmation before running new command, by default `True`;
* `wait_command` – max amount of time in seconds for getting previous command output;
* `no_colors` – disable colored output;
@ -281,6 +282,7 @@ Example of `settings.py`:
```python
rules = ['sudo', 'no_command']
exclude_rules = ['git_push']
require_confirmation = True
wait_command = 10
no_colors = False
@ -291,6 +293,7 @@ debug = False
Or via environment variables:
* `THEFUCK_RULES` – list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`;
* `THEFUCK_EXCLUDE_RULES` – list of disabled rules, like `git_pull:git_push`;
* `THEFUCK_REQUIRE_CONFIRMATION` – require confirmation before running new command, `true/false`;
* `THEFUCK_WAIT_COMMAND` – max amount of time in seconds for getting previous command output;
* `THEFUCK_NO_COLORS` – disable colored output, `true/false`;
@ -302,6 +305,7 @@ For example:
```bash
export THEFUCK_RULES='sudo:no_command'
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false'

View File

@ -39,17 +39,20 @@ class TestSettingsFromFile(object):
wait_command=10,
require_confirmation=True,
no_colors=True,
priority={'vim': 100})
priority={'vim': 100},
exclude_rules=['git'])
settings = conf.get_settings(Mock())
assert settings.rules == ['test']
assert settings.wait_command == 10
assert settings.require_confirmation is True
assert settings.no_colors is True
assert settings.priority == {'vim': 100}
assert settings.exclude_rules == ['git']
def test_from_file_with_DEFAULT(self, load_source):
load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'],
wait_command=10,
exclude_rules=[],
require_confirmation=True,
no_colors=True)
settings = conf.get_settings(Mock())
@ -60,12 +63,14 @@ class TestSettingsFromFile(object):
class TestSettingsFromEnv(object):
def test_from_env(self, environ):
environ.update({'THEFUCK_RULES': 'bash:lisp',
'THEFUCK_EXCLUDE_RULES': 'git:vim',
'THEFUCK_WAIT_COMMAND': '55',
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false',
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
settings = conf.get_settings(Mock())
assert settings.rules == ['bash', 'lisp']
assert settings.exclude_rules == ['git', 'vim']
assert settings.wait_command == 55
assert settings.require_confirmation is True
assert settings.no_colors is False

View File

@ -22,23 +22,39 @@ def test_load_rule(mocker):
class TestGetRules(object):
@pytest.fixture(autouse=True)
@pytest.fixture
def glob(self, mocker):
return mocker.patch('thefuck.corrector.Path.glob', return_value=[])
results = {}
mocker.patch('thefuck.corrector.Path.glob',
new_callable=lambda: lambda *_: results.pop('value', []))
return lambda value: results.update({'value': value})
def _compare_names(self, rules, names):
return [r.name for r in rules] == names
@pytest.mark.parametrize('conf_rules, rules', [
(conf.DEFAULT_RULES, ['bash', 'lisp', 'bash', 'lisp']),
(types.RulesNamesList(['bash']), ['bash', 'bash'])])
def test_get(self, monkeypatch, glob, conf_rules, rules):
glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
@pytest.fixture(autouse=True)
def load_source(self, monkeypatch):
monkeypatch.setattr('thefuck.corrector.load_source',
lambda x, _: Rule(x))
assert self._compare_names(
corrector.get_rules(Path('~'), Mock(rules=conf_rules, priority={})),
rules)
def _compare_names(self, rules, names):
assert {r.name for r in rules} == set(names)
def _prepare_rules(self, rules):
if rules == conf.DEFAULT_RULES:
return rules
else:
return types.RulesNamesList(rules)
@pytest.mark.parametrize('paths, conf_rules, exclude_rules, loaded_rules', [
(['git.py', 'bash.py'], conf.DEFAULT_RULES, [], ['git', 'bash']),
(['git.py', 'bash.py'], ['git'], [], ['git']),
(['git.py', 'bash.py'], conf.DEFAULT_RULES, ['git'], ['bash']),
(['git.py', 'bash.py'], ['git'], ['git'], [])])
def test_get_rules(self, glob, paths, conf_rules, exclude_rules, loaded_rules):
glob([PosixPath(path) for path in paths])
settings = Mock(rules=self._prepare_rules(conf_rules),
priority={},
exclude_rules=self._prepare_rules(exclude_rules))
rules = corrector.get_rules(Path('~'), settings)
self._compare_names(rules, loaded_rules)
class TestIsRuleMatch(object):

View File

@ -26,6 +26,7 @@ DEFAULT_PRIORITY = 1000
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'exclude_rules': [],
'wait_command': 3,
'require_confirmation': True,
'no_colors': False,
@ -34,6 +35,7 @@ DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'env': {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}}
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
'THEFUCK_EXCLUDE_RULES': 'exclude_rules',
'THEFUCK_WAIT_COMMAND': 'wait_command',
'THEFUCK_REQUIRE_CONFIRMATION': 'require_confirmation',
'THEFUCK_NO_COLORS': 'no_colors',
@ -84,7 +86,7 @@ def _priority_from_env(val):
def _val_from_env(env, attr):
"""Transforms env-strings to python."""
val = os.environ[env]
if attr == 'rules':
if attr in ('rules', 'exclude_rules'):
return _rules_from_env(val)
elif attr == 'priority':
return dict(_priority_from_env(val))
@ -123,6 +125,9 @@ def get_settings(user_dir):
if not isinstance(conf['rules'], types.RulesNamesList):
conf['rules'] = types.RulesNamesList(conf['rules'])
if not isinstance(conf['exclude_rules'], types.RulesNamesList):
conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules'])
return types.Settings(conf)

View File

@ -23,7 +23,8 @@ def get_loaded_rules(rules, settings):
for rule in rules:
if rule.name != '__init__.py':
loaded_rule = load_rule(rule, settings)
if loaded_rule in settings.rules:
if loaded_rule in settings.rules and \
loaded_rule not in settings.exclude_rules:
yield loaded_rule