1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-01-31 02:01:13 +00:00

Pass settings to the rules

This commit is contained in:
nvbn 2015-04-08 21:08:35 +02:00
parent 173a4300b4
commit 9ed022d67f
8 changed files with 50 additions and 47 deletions

View File

@ -14,11 +14,11 @@ To push the current branch and set the remote as upstream, use
def test_match(stderr):
assert match(Command('git push master', '', stderr))
assert not match(Command('git push master', '', ''))
assert not match(Command('ls', '', stderr))
assert match(Command('git push master', '', stderr), None)
assert not match(Command('git push master', '', ''), None)
assert not match(Command('ls', '', stderr), None)
def test_get_new_command(stderr):
assert get_new_command(Command('', '', stderr))\
assert get_new_command(Command('', '', stderr), None)\
== "git push --set-upstream origin master"

View File

@ -1,4 +1,4 @@
from unittest.mock import patch
from unittest.mock import patch, Mock
import pytest
from subprocess import PIPE
from thefuck.rules.no_command import match, get_new_command
@ -22,23 +22,24 @@ vom: command not found
def test_match(command_found, command_not_found):
with patch('thefuck.rules.no_command.Popen') as Popen:
Popen.return_value.stderr.read.return_value = command_found
assert match(Command('aptget install vim', '', ''))
assert match(Command('aptget install vim', '', ''), None)
Popen.assert_called_once_with('/usr/lib/command-not-found aptget',
shell=True, stderr=PIPE)
Popen.return_value.stderr.read.return_value = command_not_found
assert not match(Command('ls', '', ''))
assert not match(Command('ls', '', ''), None)
with patch('thefuck.rules.no_command.Popen') as Popen:
Popen.return_value.stderr.read.return_value = command_found
assert match(Command('sudo aptget install vim', '', ''))
Popen.assert_called_once_with('/usr/lib/command-not-found aptget',
assert match(Command('sudo aptget install vim', '', ''),
Mock(command_not_found='test'))
Popen.assert_called_once_with('test aptget',
shell=True, stderr=PIPE)
def test_get_new_command(command_found):
with patch('thefuck.rules.no_command._get_output',
return_value=command_found.decode()):
assert get_new_command(Command('aptget install vim', '', ''))\
assert get_new_command(Command('aptget install vim', '', ''), None)\
== 'apt-get install vim'
assert get_new_command(Command('sudo aptget install vim', '', '')) \
assert get_new_command(Command('sudo aptget install vim', '', ''), None) \
== 'sudo apt-get install vim'

View File

@ -3,11 +3,11 @@ from thefuck.rules.sudo import match, get_new_command
def test_match():
assert match(Command('', '', 'Permission denied'))
assert match(Command('', '', 'permission denied'))
assert match(Command('', '', "npm ERR! Error: EACCES, unlink"))
assert not match(Command('', '', ''))
assert match(Command('', '', 'Permission denied'), None)
assert match(Command('', '', 'permission denied'), None)
assert match(Command('', '', "npm ERR! Error: EACCES, unlink"), None)
assert not match(Command('', '', ''), None)
def test_get_new_command():
assert get_new_command(Command('ls', '', '')) == 'sudo ls'
assert get_new_command(Command('ls', '', ''), None) == 'sudo ls'

View File

@ -27,9 +27,9 @@ def test_get_settings():
def test_is_rule_enabled():
assert main.is_rule_enabled(main.Settings(None), Path('bash.py'))
assert main.is_rule_enabled(main.Settings(['bash']), Path('bash.py'))
assert not main.is_rule_enabled(main.Settings(['bash']), Path('lisp.py'))
assert main.is_rule_enabled(Mock(rules=None), Path('bash.py'))
assert main.is_rule_enabled(Mock(rules=['bash']), Path('bash.py'))
assert not main.is_rule_enabled(Mock(rules=['bash']), Path('lisp.py'))
def test_load_rule():
@ -50,13 +50,13 @@ def test_get_rules():
glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
assert main.get_rules(
Path('~'),
main.Settings(None)) == [main.Rule('bash', 'bash'),
Mock(rules=None)) == [main.Rule('bash', 'bash'),
main.Rule('lisp', 'lisp'),
main.Rule('bash', 'bash'),
main.Rule('lisp', 'lisp')]
assert main.get_rules(
Path('~'),
main.Settings(['bash'])) == [main.Rule('bash', 'bash'),
Mock(rules=['bash'])) == [main.Rule('bash', 'bash'),
main.Rule('bash', 'bash')]
@ -73,9 +73,9 @@ def test_get_command():
def test_get_matched_rule():
rules = [main.Rule(lambda x: x.script == 'cd ..', None),
main.Rule(lambda _: False, None)]
rules = [main.Rule(lambda x, _: x.script == 'cd ..', None),
main.Rule(lambda _, _: False, None)]
assert main.get_matched_rule(main.Command('ls', '', ''),
rules) is None
rules, None) is None
assert main.get_matched_rule(main.Command('cd ..', '', ''),
rules) == rules[0]
rules, None) == rules[0]

View File

@ -2,13 +2,11 @@ from collections import namedtuple
from imp import load_source
from pathlib import Path
from os.path import expanduser
from os import environ
from subprocess import Popen, PIPE
import sys
Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
Settings = namedtuple('Settings', ('rules',))
Rule = namedtuple('Rule', ('match', 'get_new_command'))
@ -22,14 +20,16 @@ def setup_user_dir() -> Path:
return user_dir
def get_settings(user_dir: Path) -> Settings:
def get_settings(user_dir: Path):
"""Returns prepared settings module."""
settings = load_source('settings',
str(user_dir.joinpath('settings.py')))
return Settings(getattr(settings, 'rules', None))
if not hasattr(settings, 'rules'):
settings.rules = None
return settings
def is_rule_enabled(settings: Settings, rule: Path) -> bool:
def is_rule_enabled(settings, rule: Path) -> bool:
"""Returns `True` when rule mentioned in `rules` or `rules`
isn't defined.
@ -43,7 +43,7 @@ def load_rule(rule: Path) -> Rule:
return Rule(rule_module.match, rule_module.get_new_command)
def get_rules(user_dir: Path, settings: Settings) -> [Rule]:
def get_rules(user_dir: Path, settings) -> [Rule]:
"""Returns all enabled rules."""
bundled = Path(__file__).parent\
.joinpath('rules')\
@ -61,16 +61,16 @@ def get_command(args: [str]) -> Command:
result.stderr.read().decode())
def get_matched_rule(command: Command, rules: [Rule]) -> Rule:
def get_matched_rule(command: Command, rules: [Rule], settings) -> Rule:
"""Returns first matched rule for command."""
for rule in rules:
if rule.match(command):
if rule.match(command, settings):
return rule
def run_rule(rule: Rule, command: Command):
def run_rule(rule: Rule, command: Command, settings):
"""Runs command from rule for passed command."""
new_command = rule.get_new_command(command)
new_command = rule.get_new_command(command, settings)
print(new_command)
@ -79,8 +79,8 @@ def main():
user_dir = setup_user_dir()
settings = get_settings(user_dir)
rules = get_rules(user_dir, settings)
matched_rule = get_matched_rule(command, rules)
matched_rule = get_matched_rule(command, rules, settings)
if matched_rule:
run_rule(matched_rule, command)
run_rule(matched_rule, command, settings)
else:
print('echo No fuck given')

View File

@ -1,8 +1,8 @@
def match(command):
def match(command, settings):
return ('git' in command.script
and 'push' in command.script
and 'set-upstream' in command.stderr)
def get_new_command(command):
def get_new_command(command, settings):
return command.stderr.split('\n')[-3].strip()

View File

@ -2,20 +2,22 @@ from subprocess import Popen, PIPE
import re
def _get_output(command):
def _get_output(command, settings):
name = command.script.split(' ')[command.script.startswith('sudo')]
check_script = '/usr/lib/command-not-found {}'.format(name)
check_script = '{} {}'.format(getattr(settings, 'command_not_found',
'/usr/lib/command-not-found'),
name)
result = Popen(check_script, shell=True, stderr=PIPE)
return result.stderr.read().decode()
def match(command):
output = _get_output(command)
def match(command, settings):
output = _get_output(command, settings)
return "No command" in output and "from package" in output
def get_new_command(command):
output = _get_output(command)
def get_new_command(command, settings):
output = _get_output(command, settings)
broken_name = re.findall(r"No command '([^']*)' found",
output)[0]
fixed_name = re.findall(r"Command '([^']*)' from package",

View File

@ -1,7 +1,7 @@
def match(command):
def match(command, settings):
return ('permission denied' in command.stderr.lower()
or 'EACCES' in command.stderr)
def get_new_command(command):
def get_new_command(command, settings):
return 'sudo {}'.format(command.script)