1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-04-19 09:10:47 +01:00

#280: Add debug output

This commit is contained in:
nvbn 2015-07-15 07:47:54 +03:00
parent 934099fe9e
commit 3e4c043ccc
6 changed files with 40 additions and 6 deletions

View File

@ -253,7 +253,8 @@ The Fuck has a few settings parameters which can be changed in `~/.thefuck/setti
* `require_confirmation` – requires confirmation before running new command, by default `False`; * `require_confirmation` – requires 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. * `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
* `debug` – enabled debug output, by default `False`;
Example of `settings.py`: Example of `settings.py`:
@ -263,6 +264,7 @@ require_confirmation = True
wait_command = 10 wait_command = 10
no_colors = False no_colors = False
priority = {'sudo': 100, 'no_command': 9999} priority = {'sudo': 100, 'no_command': 9999}
debug = False
``` ```
Or via environment variables: Or via environment variables:
@ -272,7 +274,8 @@ Or via environment variables:
* `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`, * `THEFUCK_PRIORITY` – priority of the rules, like `no_command=9999:apt_get=100`,
rule with lower `priority` will be matched first. rule with lower `priority` will be matched first;
* `THEFUCK_DEBUG` – enables debug output, `true/false`.
For example: For example:

View File

@ -5,3 +5,10 @@ from thefuck import logs
def test_color(): def test_color():
assert logs.color('red', Mock(no_colors=False)) == 'red' assert logs.color('red', Mock(no_colors=False)) == 'red'
assert logs.color('red', Mock(no_colors=True)) == '' assert logs.color('red', Mock(no_colors=True)) == ''
def test_debug(capsys):
logs.debug('test', Mock(no_colors=True, debug=True))
assert capsys.readouterr() == ('', 'DEBUG: test\n')
logs.debug('test', Mock(no_colors=True, debug=False))
assert capsys.readouterr() == ('', '')

View File

@ -110,7 +110,7 @@ class TestGetMatchedRule(object):
def test_when_rule_failed(self, capsys): def test_when_rule_failed(self, capsys):
main.get_matched_rule( main.get_matched_rule(
Command('ls'), [Rule('test', Mock(side_effect=OSError('Denied')))], Command('ls'), [Rule('test', Mock(side_effect=OSError('Denied')))],
Mock(no_colors=True)) Mock(no_colors=True, debug=False))
assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:' assert capsys.readouterr()[1].split('\n')[0] == '[WARN] Rule test:'
@ -126,7 +126,7 @@ class TestRunRule(object):
def test_run_rule_with_side_effect(self, capsys): def test_run_rule_with_side_effect(self, capsys):
side_effect = Mock() side_effect = Mock()
settings = Mock() settings = Mock(debug=False)
command = Command() command = Command()
main.run_rule(Rule(get_new_command=lambda *_: 'new-command', main.run_rule(Rule(get_new_command=lambda *_: 'new-command',
side_effect=side_effect), side_effect=side_effect),

View File

@ -29,13 +29,15 @@ DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'wait_command': 3, 'wait_command': 3,
'require_confirmation': False, 'require_confirmation': False,
'no_colors': False, 'no_colors': False,
'debug': False,
'priority': {}} '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'} 'THEFUCK_PRIORITY': 'priority',
'THEFUCK_DEBUG': 'debug'}
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
@ -87,7 +89,7 @@ def _val_from_env(env, attr):
return dict(_priority_from_env(val)) return dict(_priority_from_env(val))
elif attr == 'wait_command': elif attr == 'wait_command':
return int(val) return int(val)
elif attr in ('require_confirmation', 'no_colors'): elif attr in ('require_confirmation', 'no_colors', 'debug'):
return val.lower() == 'true' return val.lower() == 'true'
else: else:
return val return val

View File

@ -1,3 +1,4 @@
from pprint import pformat
import sys import sys
from traceback import format_exception from traceback import format_exception
import colorama import colorama
@ -52,3 +53,12 @@ def failed(msg, settings):
msg=msg, msg=msg,
red=color(colorama.Fore.RED, settings), red=color(colorama.Fore.RED, settings),
reset=color(colorama.Style.RESET_ALL, settings))) reset=color(colorama.Style.RESET_ALL, settings)))
def debug(msg, settings):
if settings.debug:
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
msg=msg,
reset=color(colorama.Style.RESET_ALL, settings),
blue=color(colorama.Fore.BLUE, settings),
bold=color(colorama.Style.BRIGHT, settings)))

View File

@ -1,6 +1,7 @@
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 pprint import pformat
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
import os import os
import sys import sys
@ -79,6 +80,7 @@ def get_command(settings, args):
return return
script = shells.from_shell(script) script = shells.from_shell(script)
logs.debug('Call: {}'.format(script), settings)
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE,
env=dict(os.environ, LANG='C')) env=dict(os.environ, LANG='C'))
if wait_output(settings, result): if wait_output(settings, result):
@ -90,6 +92,7 @@ def get_matched_rule(command, rules, settings):
"""Returns first matched rule for command.""" """Returns first matched rule for command."""
for rule in rules: for rule in rules:
try: try:
logs.debug(u'Trying rule: {}'.format(rule.name), settings)
if rule.match(command, settings): if rule.match(command, settings):
return rule return rule
except Exception: except Exception:
@ -125,12 +128,21 @@ def main():
colorama.init() colorama.init()
user_dir = setup_user_dir() user_dir = setup_user_dir()
settings = conf.get_settings(user_dir) settings = conf.get_settings(user_dir)
logs.debug('Run with settings: {}'.format(pformat(settings)), settings)
command = get_command(settings, sys.argv) command = get_command(settings, sys.argv)
if command: if command:
logs.debug('Received stdout: {}'.format(command.stdout), settings)
logs.debug('Received stderr: {}'.format(command.stderr), settings)
rules = get_rules(user_dir, settings) rules = get_rules(user_dir, settings)
logs.debug(
'Loaded rules: {}'.format(', '.join(rule.name for rule in rules)),
settings)
matched_rule = get_matched_rule(command, rules, settings) matched_rule = get_matched_rule(command, rules, settings)
if matched_rule: if matched_rule:
logs.debug('Matched rule: {}'.format(matched_rule.name), settings)
run_rule(matched_rule, command, settings) run_rule(matched_rule, command, settings)
return return