mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 12:06:04 +00:00
Merge pull request #361 from nvbn/357-exclude-rules
#357 Add `exclude_rules` settings option
This commit is contained in:
commit
f7ce0fda25
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user