1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-21 20:38:54 +00:00

#154 Add ability to override priority in settings

This commit is contained in:
nvbn 2015-05-07 13:11:45 +02:00
parent 5bf1424613
commit 05f594b918
5 changed files with 51 additions and 18 deletions

View File

@ -213,7 +213,8 @@ The Fuck has a few settings parameters, they can be changed in `~/.thefuck/setti
* `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`; * `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
* `require_confirmation` – require confirmation before running new command, by default `False`; * `require_confirmation` – require confirmation before running new command, by default `False`;
* `wait_command` – max amount of time in seconds for getting previous command output; * `wait_command` – max amount of time in seconds for getting previous command output;
* `no_colors` – disable colored output. * `no_colors` – disable colored output;
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first.
Example of `settings.py`: Example of `settings.py`:
@ -222,6 +223,7 @@ rules = ['sudo', 'no_command']
require_confirmation = True require_confirmation = True
wait_command = 10 wait_command = 10
no_colors = False no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
``` ```
Or via environment variables: Or via environment variables:
@ -229,7 +231,9 @@ Or via environment variables:
* `THEFUCK_RULES` – list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`; * `THEFUCK_RULES` – list of enabled rules, like `DEFAULT_RULES:rm_root` or `sudo:no_command`;
* `THEFUCK_REQUIRE_CONFIRMATION` – require confirmation before running new command, `true/false`; * `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_WAIT_COMMAND` – max amount of time in seconds for getting previous command output;
* `THEFUCK_NO_COLORS` – disable colored output, `true/false`. * `THEFUCK_NO_COLORS` – disable colored output, `true/false`;
* `THEFUCK_PRIORITY` – priority of the rules, like `no_command=9999:apt_get=100`,
rule with lower `priority` will be matched first.
For example: For example:
@ -238,6 +242,7 @@ export THEFUCK_RULES='sudo:no_command'
export THEFUCK_REQUIRE_CONFIRMATION='true' export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10 export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false' export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'
``` ```
## Developing ## Developing

View File

@ -40,12 +40,14 @@ class TestSettingsFromFile(object):
load_source.return_value = Mock(rules=['test'], load_source.return_value = Mock(rules=['test'],
wait_command=10, wait_command=10,
require_confirmation=True, require_confirmation=True,
no_colors=True) no_colors=True,
priority={'vim': 100})
settings = conf.get_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
assert settings.no_colors is True assert settings.no_colors is True
assert settings.priority == {'vim': 100}
def test_from_file_with_DEFAULT(self, load_source): def test_from_file_with_DEFAULT(self, load_source):
load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'], load_source.return_value = Mock(rules=conf.DEFAULT_RULES + ['test'],
@ -62,12 +64,14 @@ class TestSettingsFromEnv(object):
environ.update({'THEFUCK_RULES': 'bash:lisp', environ.update({'THEFUCK_RULES': 'bash:lisp',
'THEFUCK_WAIT_COMMAND': '55', 'THEFUCK_WAIT_COMMAND': '55',
'THEFUCK_REQUIRE_CONFIRMATION': 'true', 'THEFUCK_REQUIRE_CONFIRMATION': 'true',
'THEFUCK_NO_COLORS': 'false'}) 'THEFUCK_NO_COLORS': 'false',
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
settings = conf.get_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
assert settings.no_colors is False assert settings.no_colors is False
assert settings.priority == {'bash': 10, 'vim': 15}
def test_from_env_with_DEFAULT(self, environ): def test_from_env_with_DEFAULT(self, environ):
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'}) environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})

View File

@ -38,17 +38,25 @@ class TestGetRules(object):
monkeypatch.setattr('thefuck.main.load_source', monkeypatch.setattr('thefuck.main.load_source',
lambda x, _: Rule(x)) lambda x, _: Rule(x))
assert self._compare_names( assert self._compare_names(
main.get_rules(Path('~'), Mock(rules=conf_rules)), rules) main.get_rules(Path('~'), Mock(rules=conf_rules, priority={})),
rules)
@pytest.mark.parametrize('unordered, ordered', [ @pytest.mark.parametrize('priority, unordered, ordered', [
([Rule('bash', priority=100), Rule('python', priority=5)], ({},
[Rule('bash', priority=100), Rule('python', priority=5)],
['python', 'bash']), ['python', 'bash']),
([Rule('lisp', priority=9999), Rule('c', priority=conf.DEFAULT_PRIORITY)], ({},
['c', 'lisp'])]) [Rule('lisp', priority=9999), Rule('c', priority=conf.DEFAULT_PRIORITY)],
def test_ordered_by_priority(self, monkeypatch, unordered, ordered): ['c', 'lisp']),
({'python': 9999},
[Rule('bash', priority=100), Rule('python', priority=5)],
['bash', 'python'])])
def test_ordered_by_priority(self, monkeypatch, priority, unordered, ordered):
monkeypatch.setattr('thefuck.main._get_loaded_rules', monkeypatch.setattr('thefuck.main._get_loaded_rules',
lambda *_: unordered) lambda *_: unordered)
assert self._compare_names(main.get_rules(Path('~'), Mock()), ordered) assert self._compare_names(
main.get_rules(Path('~'), Mock(priority=priority)),
ordered)
class TestGetCommand(object): class TestGetCommand(object):

View File

@ -28,12 +28,14 @@ DEFAULT_PRIORITY = 1000
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES, DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'wait_command': 3, 'wait_command': 3,
'require_confirmation': False, 'require_confirmation': False,
'no_colors': False} 'no_colors': False,
'priority': {}}
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',
'THEFUCK_PRIORITY': 'priority'}
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
@ -66,16 +68,29 @@ def _rules_from_env(val):
return val return val
def _priority_from_env(val):
"""Gets priority pairs from env."""
for part in val.split(':'):
try:
rule, priority = part.split('=')
yield rule, int(priority)
except ValueError:
continue
def _val_from_env(env, attr): def _val_from_env(env, attr):
"""Transforms env-strings to python.""" """Transforms env-strings to python."""
val = os.environ[env] val = os.environ[env]
if attr == 'rules': if attr == 'rules':
val = _rules_from_env(val) return _rules_from_env(val)
elif attr == 'priority':
return dict(_priority_from_env(val))
elif attr == 'wait_command': elif attr == 'wait_command':
val = int(val) return int(val)
elif attr in ('require_confirmation', 'no_colors'): elif attr in ('require_confirmation', 'no_colors'):
val = val.lower() == 'true' return val.lower() == 'true'
return val else:
return val
def _settings_from_env(): def _settings_from_env():

View File

@ -46,7 +46,8 @@ def get_rules(user_dir, settings):
.glob('*.py') .glob('*.py')
user = user_dir.joinpath('rules').glob('*.py') user = user_dir.joinpath('rules').glob('*.py')
rules = _get_loaded_rules(sorted(bundled) + sorted(user), settings) rules = _get_loaded_rules(sorted(bundled) + sorted(user), settings)
return sorted(rules, key=lambda rule: rule.priority) return sorted(rules, key=lambda rule: settings.priority.get(
rule.name, rule.priority))
def wait_output(settings, popen): def wait_output(settings, popen):