From 71bb1994c39c89ea53c7e4bd531b4acef07e6bee Mon Sep 17 00:00:00 2001 From: mcarton Date: Sat, 25 Jul 2015 23:04:08 +0200 Subject: [PATCH] Allow rules to correct commands that time out --- tests/test_main.py | 3 ++- tests/utils.py | 5 +++-- thefuck/main.py | 42 ++++++++++++++++++++++++++---------------- thefuck/types.py | 3 ++- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 10294c3c..50e7c03a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -14,7 +14,8 @@ def test_load_rule(mocker): return_value=Mock(match=match, get_new_command=get_new_command, enabled_by_default=True, - priority=900)) + priority=900, + requires_output=True)) assert main.load_rule(Path('/rules/bash.py')) \ == Rule('bash', match, get_new_command, priority=900) load_source.assert_called_once_with('bash', '/rules/bash.py') diff --git a/tests/utils.py b/tests/utils.py index 4641971d..6efeafa8 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,7 +10,8 @@ def Rule(name='', match=lambda *_: True, get_new_command=lambda *_: '', enabled_by_default=True, side_effect=None, - priority=DEFAULT_PRIORITY): + priority=DEFAULT_PRIORITY, + requires_output=True): return types.Rule(name, match, get_new_command, enabled_by_default, side_effect, - priority) + priority, requires_output) diff --git a/thefuck/main.py b/thefuck/main.py index 3668cad5..37c06e5c 100644 --- a/thefuck/main.py +++ b/thefuck/main.py @@ -28,7 +28,8 @@ def load_rule(rule): rule_module.get_new_command, getattr(rule_module, 'enabled_by_default', True), getattr(rule_module, 'side_effect', None), - getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY)) + getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY), + getattr(rule_module, 'requires_output', True)) def _get_loaded_rules(rules, settings): @@ -87,13 +88,26 @@ def get_command(settings, args): settings): result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env) if wait_output(settings, result): - return types.Command(script, result.stdout.read().decode('utf-8'), - result.stderr.read().decode('utf-8')) + stdout = result.stdout.read().decode('utf-8') + stderr = result.stderr.read().decode('utf-8') + + logs.debug(u'Received stdout: {}'.format(stdout), settings) + logs.debug(u'Received stderr: {}'.format(stderr), settings) + + return types.Command(script, stdout, stderr) + else: + logs.debug(u'Execution timed out!', settings) + return types.Script(script) def get_matched_rule(command, rules, settings): """Returns first matched rule for command.""" + script_only = isinstance(command, types.Script) + for rule in rules: + if script_only and rule.requires_output: + continue + try: with logs.debug_time(u'Trying rule: {};'.format(rule.name), settings): @@ -138,20 +152,16 @@ def main(): logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings) command = get_command(settings, sys.argv) - if command: - logs.debug(u'Received stdout: {}'.format(command.stdout), settings) - logs.debug(u'Received stderr: {}'.format(command.stderr), settings) + rules = get_rules(user_dir, settings) + logs.debug( + u'Loaded rules: {}'.format(', '.join(rule.name for rule in rules)), + settings) - rules = get_rules(user_dir, settings) - logs.debug( - u'Loaded rules: {}'.format(', '.join(rule.name for rule in rules)), - settings) - - matched_rule = get_matched_rule(command, rules, settings) - if matched_rule: - logs.debug(u'Matched rule: {}'.format(matched_rule.name), settings) - run_rule(matched_rule, command, settings) - return + matched_rule = get_matched_rule(command, rules, settings) + if matched_rule: + logs.debug(u'Matched rule: {}'.format(matched_rule.name), settings) + run_rule(matched_rule, command, settings) + return logs.failed('No fuck given', settings) diff --git a/thefuck/types.py b/thefuck/types.py index 3ca2cf85..8ee392d8 100644 --- a/thefuck/types.py +++ b/thefuck/types.py @@ -2,10 +2,11 @@ from collections import namedtuple Command = namedtuple('Command', ('script', 'stdout', 'stderr')) +Script = namedtuple('Script', ('script')) Rule = namedtuple('Rule', ('name', 'match', 'get_new_command', 'enabled_by_default', 'side_effect', - 'priority')) + 'priority', 'requires_output')) class RulesNamesList(list):