1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-04-19 09:10:47 +01: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): def test_match(stderr):
assert match(Command('git push master', '', stderr)) assert match(Command('git push master', '', stderr), None)
assert not match(Command('git push master', '', '')) assert not match(Command('git push master', '', ''), None)
assert not match(Command('ls', '', stderr)) assert not match(Command('ls', '', stderr), None)
def test_get_new_command(stderr): 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" == "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 import pytest
from subprocess import PIPE from subprocess import PIPE
from thefuck.rules.no_command import match, get_new_command 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): def test_match(command_found, command_not_found):
with patch('thefuck.rules.no_command.Popen') as Popen: with patch('thefuck.rules.no_command.Popen') as Popen:
Popen.return_value.stderr.read.return_value = command_found 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', Popen.assert_called_once_with('/usr/lib/command-not-found aptget',
shell=True, stderr=PIPE) shell=True, stderr=PIPE)
Popen.return_value.stderr.read.return_value = command_not_found 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: with patch('thefuck.rules.no_command.Popen') as Popen:
Popen.return_value.stderr.read.return_value = command_found Popen.return_value.stderr.read.return_value = command_found
assert match(Command('sudo aptget install vim', '', '')) assert match(Command('sudo aptget install vim', '', ''),
Popen.assert_called_once_with('/usr/lib/command-not-found aptget', Mock(command_not_found='test'))
Popen.assert_called_once_with('test aptget',
shell=True, stderr=PIPE) shell=True, stderr=PIPE)
def test_get_new_command(command_found): def test_get_new_command(command_found):
with patch('thefuck.rules.no_command._get_output', with patch('thefuck.rules.no_command._get_output',
return_value=command_found.decode()): 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' == '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' == 'sudo apt-get install vim'

View File

@ -3,11 +3,11 @@ from thefuck.rules.sudo import match, get_new_command
def test_match(): def test_match():
assert match(Command('', '', 'Permission denied')) assert match(Command('', '', 'Permission denied'), None)
assert match(Command('', '', 'permission denied')) assert match(Command('', '', 'permission denied'), None)
assert match(Command('', '', "npm ERR! Error: EACCES, unlink")) assert match(Command('', '', "npm ERR! Error: EACCES, unlink"), None)
assert not match(Command('', '', '')) assert not match(Command('', '', ''), None)
def test_get_new_command(): 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(): def test_is_rule_enabled():
assert main.is_rule_enabled(main.Settings(None), Path('bash.py')) assert main.is_rule_enabled(Mock(rules=None), Path('bash.py'))
assert main.is_rule_enabled(main.Settings(['bash']), Path('bash.py')) assert main.is_rule_enabled(Mock(rules=['bash']), Path('bash.py'))
assert not main.is_rule_enabled(main.Settings(['bash']), Path('lisp.py')) assert not main.is_rule_enabled(Mock(rules=['bash']), Path('lisp.py'))
def test_load_rule(): def test_load_rule():
@ -50,13 +50,13 @@ def test_get_rules():
glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')] glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
assert main.get_rules( assert main.get_rules(
Path('~'), Path('~'),
main.Settings(None)) == [main.Rule('bash', 'bash'), Mock(rules=None)) == [main.Rule('bash', 'bash'),
main.Rule('lisp', 'lisp'), main.Rule('lisp', 'lisp'),
main.Rule('bash', 'bash'), main.Rule('bash', 'bash'),
main.Rule('lisp', 'lisp')] main.Rule('lisp', 'lisp')]
assert main.get_rules( assert main.get_rules(
Path('~'), Path('~'),
main.Settings(['bash'])) == [main.Rule('bash', 'bash'), Mock(rules=['bash'])) == [main.Rule('bash', 'bash'),
main.Rule('bash', 'bash')] main.Rule('bash', 'bash')]
@ -73,9 +73,9 @@ def test_get_command():
def test_get_matched_rule(): def test_get_matched_rule():
rules = [main.Rule(lambda x: x.script == 'cd ..', None), rules = [main.Rule(lambda x, _: x.script == 'cd ..', None),
main.Rule(lambda _: False, None)] main.Rule(lambda _, _: False, None)]
assert main.get_matched_rule(main.Command('ls', '', ''), assert main.get_matched_rule(main.Command('ls', '', ''),
rules) is None rules, None) is None
assert main.get_matched_rule(main.Command('cd ..', '', ''), 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 imp import load_source
from pathlib import Path from pathlib import Path
from os.path import expanduser from os.path import expanduser
from os import environ
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import sys import sys
Command = namedtuple('Command', ('script', 'stdout', 'stderr')) Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
Settings = namedtuple('Settings', ('rules',))
Rule = namedtuple('Rule', ('match', 'get_new_command')) Rule = namedtuple('Rule', ('match', 'get_new_command'))
@ -22,14 +20,16 @@ def setup_user_dir() -> Path:
return user_dir return user_dir
def get_settings(user_dir: Path) -> Settings: def get_settings(user_dir: Path):
"""Returns prepared settings module.""" """Returns prepared settings module."""
settings = load_source('settings', settings = load_source('settings',
str(user_dir.joinpath('settings.py'))) 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` """Returns `True` when rule mentioned in `rules` or `rules`
isn't defined. isn't defined.
@ -43,7 +43,7 @@ def load_rule(rule: Path) -> Rule:
return Rule(rule_module.match, rule_module.get_new_command) 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.""" """Returns all enabled rules."""
bundled = Path(__file__).parent\ bundled = Path(__file__).parent\
.joinpath('rules')\ .joinpath('rules')\
@ -61,16 +61,16 @@ def get_command(args: [str]) -> Command:
result.stderr.read().decode()) 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.""" """Returns first matched rule for command."""
for rule in rules: for rule in rules:
if rule.match(command): if rule.match(command, settings):
return rule return rule
def run_rule(rule: Rule, command: Command): def run_rule(rule: Rule, command: Command, settings):
"""Runs command from rule for passed command.""" """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) print(new_command)
@ -79,8 +79,8 @@ def main():
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = get_settings(user_dir) settings = get_settings(user_dir)
rules = get_rules(user_dir, settings) rules = get_rules(user_dir, settings)
matched_rule = get_matched_rule(command, rules) matched_rule = get_matched_rule(command, rules, settings)
if matched_rule: if matched_rule:
run_rule(matched_rule, command) run_rule(matched_rule, command, settings)
else: else:
print('echo No fuck given') print('echo No fuck given')

View File

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

View File

@ -2,20 +2,22 @@ from subprocess import Popen, PIPE
import re import re
def _get_output(command): def _get_output(command, settings):
name = command.script.split(' ')[command.script.startswith('sudo')] 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) result = Popen(check_script, shell=True, stderr=PIPE)
return result.stderr.read().decode() return result.stderr.read().decode()
def match(command): def match(command, settings):
output = _get_output(command) output = _get_output(command, settings)
return "No command" in output and "from package" in output return "No command" in output and "from package" in output
def get_new_command(command): def get_new_command(command, settings):
output = _get_output(command) output = _get_output(command, settings)
broken_name = re.findall(r"No command '([^']*)' found", broken_name = re.findall(r"No command '([^']*)' found",
output)[0] output)[0]
fixed_name = re.findall(r"Command '([^']*)' from package", 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() return ('permission denied' in command.stderr.lower()
or 'EACCES' in command.stderr) or 'EACCES' in command.stderr)
def get_new_command(command): def get_new_command(command, settings):
return 'sudo {}'.format(command.script) return 'sudo {}'.format(command.script)